// "Therefore those skilled at the unorthodox // are infinite as heaven and earth, // inexhaustible as the great rivers. // When they come to an end, // they begin again, // like the days and months; // they die and are reborn, // like the four seasons." // // - Sun Tsu, // "The Art of War" #if !MONO using System; using System.Drawing; using System.Runtime.InteropServices; namespace TheArtOfDev.HtmlRenderer.WinForms.Utilities { /// /// Utility for Win32 API. /// internal static class Win32Utils { public const int WsBorder = 0x00800000; public const int WsExClientEdge = 0x200; /// /// Const for BitBlt copy raster-operation code. /// public const int BitBltCopy = 0x00CC0020; /// /// Const for BitBlt paint raster-operation code. /// public const int BitBltPaint = 0x00EE0086; public const int WmSetCursor = 0x20; public const int IdcHand = 32649; public const int TextAlignDefault = 0; public const int TextAlignRtl = 256; public const int TextAlignBaseline = 24; public const int TextAlignBaselineRtl = 256 + 24; [DllImport("user32.dll")] public static extern int SetCursor(int hCursor); [DllImport("user32.dll")] public static extern int LoadCursor(int hInstance, int lpCursorName); /// /// Create a compatible memory HDC from the given HDC.
/// The memory HDC can be rendered into without effecting the original HDC.
/// The returned memory HDC and must be released using . ///
/// the HDC to create memory HDC from /// the width of the memory HDC to create /// the height of the memory HDC to create /// returns used bitmap memory section that must be released when done with memory HDC /// memory HDC public static IntPtr CreateMemoryHdc(IntPtr hdc, int width, int height, out IntPtr dib) { // Create a memory DC so we can work off-screen IntPtr memoryHdc = CreateCompatibleDC(hdc); SetBkMode(memoryHdc, 1); // Create a device-independent bitmap and select it into our DC var info = new BitMapInfo(); info.biSize = Marshal.SizeOf(info); info.biWidth = width; info.biHeight = -height; info.biPlanes = 1; info.biBitCount = 32; info.biCompression = 0; // BI_RGB IntPtr ppvBits; dib = CreateDIBSection(hdc, ref info, 0, out ppvBits, IntPtr.Zero, 0); SelectObject(memoryHdc, dib); return memoryHdc; } /// /// Release the given memory HDC and dib section created from . /// /// Memory HDC to release /// bitmap section to release public static void ReleaseMemoryHdc(IntPtr memoryHdc, IntPtr dib) { DeleteObject(dib); DeleteDC(memoryHdc); } [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll")] public static extern IntPtr WindowFromDC(IntPtr hdc); /// /// Retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen. /// /// /// In conformance with conventions for the RECT structure, the bottom-right coordinates of the returned rectangle are exclusive. In other words, /// the pixel at (right, bottom) lies immediately outside the rectangle. /// /// A handle to the window. /// A pointer to a RECT structure that receives the screen coordinates of the upper-left and lower-right corners of the window. /// If the function succeeds, the return value is nonzero. [DllImport("User32", SetLastError = true)] public static extern int GetWindowRect(IntPtr hWnd, out Rectangle lpRect); /// /// Retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen. /// /// /// In conformance with conventions for the RECT structure, the bottom-right coordinates of the returned rectangle are exclusive. In other words, /// the pixel at (right, bottom) lies immediately outside the rectangle. /// /// A handle to the window. /// RECT structure that receives the screen coordinates of the upper-left and lower-right corners of the window. public static Rectangle GetWindowRectangle(IntPtr handle) { Rectangle rect; GetWindowRect(handle, out rect); return new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); } [DllImport("User32.dll")] public static extern bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw); [DllImport("gdi32.dll")] public static extern int SetTextAlign(IntPtr hdc, uint fMode); [DllImport("gdi32.dll")] public static extern int SetBkMode(IntPtr hdc, int mode); [DllImport("gdi32.dll")] public static extern int SelectObject(IntPtr hdc, IntPtr hgdiObj); [DllImport("gdi32.dll")] public static extern int SetTextColor(IntPtr hdc, int color); [DllImport("gdi32.dll", CharSet = CharSet.Auto)] public static extern bool GetTextMetrics(IntPtr hdc, out TextMetric lptm); [DllImport("gdi32.dll", EntryPoint = "GetTextExtentPoint32W")] public static extern int GetTextExtentPoint32(IntPtr hdc, [MarshalAs(UnmanagedType.LPWStr)] string str, int len, ref Size size); [DllImport("gdi32.dll", EntryPoint = "GetTextExtentExPointW")] public static extern bool GetTextExtentExPoint(IntPtr hDc, [MarshalAs(UnmanagedType.LPWStr)] string str, int nLength, int nMaxExtent, int[] lpnFit, int[] alpDx, ref Size size); [DllImport("gdi32.dll", EntryPoint = "TextOutW")] public static extern bool TextOut(IntPtr hdc, int x, int y, [MarshalAs(UnmanagedType.LPWStr)] string str, int len); [DllImport("gdi32.dll")] public static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); [DllImport("gdi32.dll")] public static extern int GetClipBox(IntPtr hdc, out Rectangle lprc); [DllImport("gdi32.dll")] public static extern int SelectClipRgn(IntPtr hdc, IntPtr hrgn); [DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); [DllImport("gdi32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop); [DllImport("gdi32.dll", EntryPoint = "GdiAlphaBlend")] public static extern bool AlphaBlend(IntPtr hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, BlendFunction blendFunction); [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] public static extern bool DeleteDC(IntPtr hdc); [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] public static extern IntPtr CreateCompatibleDC(IntPtr hdc); [DllImport("gdi32.dll")] public static extern IntPtr CreateDIBSection(IntPtr hdc, [In] ref BitMapInfo pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset); } [StructLayout(LayoutKind.Sequential)] internal struct BlendFunction { public byte BlendOp; public byte BlendFlags; public byte SourceConstantAlpha; public byte AlphaFormat; public BlendFunction(byte alpha) { BlendOp = 0; BlendFlags = 0; AlphaFormat = 0; SourceConstantAlpha = alpha; } } [StructLayout(LayoutKind.Sequential)] internal struct BitMapInfo { public int biSize; public int biWidth; public int biHeight; public short biPlanes; public short biBitCount; public int biCompression; public int biSizeImage; public int biXPelsPerMeter; public int biYPelsPerMeter; public int biClrUsed; public int biClrImportant; public byte bmiColors_rgbBlue; public byte bmiColors_rgbGreen; public byte bmiColors_rgbRed; public byte bmiColors_rgbReserved; } [StructLayout(LayoutKind.Sequential)] internal struct TextMetric { public int tmHeight; public int tmAscent; public int tmDescent; public int tmInternalLeading; public int tmExternalLeading; public int tmAveCharWidth; public int tmMaxCharWidth; public int tmWeight; public int tmOverhang; public int tmDigitizedAspectX; public int tmDigitizedAspectY; public char tmFirstChar; public char tmLastChar; public char tmDefaultChar; public char tmBreakChar; public byte tmItalic; public byte tmUnderlined; public byte tmStruckOut; public byte tmPitchAndFamily; public byte tmCharSet; } } #endif