/// <summary> /// Draw the text supporting clipping according to ClipRegion. /// </summary> /// <param name="g"></param> /// <param name="color"></param> /// <param name="rect"></param> /// <param name="topOffset"></param> /// <param name="orientation"></param> /// <param name="fontDescription"></param> /// <param name="text"></param> /// <param name="contentAlignment"></param> /// <param name="flags"></param> public static void ClipSupportingDrawText(Graphics g, Color color, Rectangle rect, int topOffset, int orientation, FontDescription fontDescription, String text, ContentAlignment contentAlignment, int flags, bool rightToLeft) { IntPtr region = IntPtr.Zero; IntPtr currentclippedRegion = g.Clip.GetHrgn(g); bool IsRegionInfinite = g.Clip.IsInfinite(g); IntPtr hdc = g.GetHdc(); NativeWindowCommon.SetBkMode(hdc, NativeWindowCommon.TRANSPARENT); NativeWindowCommon.SetTextColor(hdc, ColorTranslator.ToWin32(color)); // Text rectangle as clip Region IntPtr clipRegion = NativeWindowCommon.CreateRectRgn(rect.Left, rect.Top, rect.Right, rect.Bottom); // If Text starts above control, it needs to clip if (topOffset < 0) { // if current graphics is already clipped, then we need to merge with current text rectangle clip if (!IsRegionInfinite) { NativeWindowCommon.CombineRgn(currentclippedRegion, currentclippedRegion, clipRegion, NativeWindowCommon.RGN_AND); } } if (IsRegionInfinite) { // If there is no clip region on graphics, set text rectangle as clip region region = clipRegion; } else if (currentclippedRegion != IntPtr.Zero) { // use intersected region as clip region region = currentclippedRegion; } // Select resultant clipped region on DC if (region != IntPtr.Zero) { NativeWindowCommon.SelectClipRgn(hdc, region); } if (clipRegion != IntPtr.Zero) { NativeWindowCommon.DeleteObject(clipRegion); } // Draw text DrawText(hdc, color, rect, topOffset, orientation, fontDescription, text, contentAlignment, flags, rightToLeft); // release objects g.ReleaseHdc(hdc); if (currentclippedRegion != IntPtr.Zero) { g.Clip.ReleaseHrgn(currentclippedRegion); } }
/// <summary> /// Paint the border /// </summary> /// <param name="m"></param> private void WMNCPaint(ref Message m) { IntPtr hDC = NativeWindowCommon.GetWindowDC(m.HWnd); if (hDC != IntPtr.Zero) { IntPtr hrgnWindow = IntPtr.Zero; IntPtr hrgnClient = IntPtr.Zero; try { Rectangle rect = new Rectangle(1, 1, Width - 2, Height - 2); hrgnWindow = NativeWindowCommon.CreateRectRgn(0, 0, Width, Height); hrgnClient = NativeWindowCommon.CreateRectRgn(rect.Left, rect.Top, rect.Right, rect.Bottom); //Creates the union of two combined regions except for any overlapping areas. NativeWindowCommon.CombineRgn(hrgnWindow, hrgnWindow, hrgnClient, NativeWindowCommon.RGN_XOR); NativeWindowCommon.SelectClipRgn(hDC, hrgnWindow); using (Graphics g = Graphics.FromHdc(hDC)) { g.Clear(VisualStyleInformation.TextControlBorder); } m.Result = IntPtr.Zero; } finally { NativeWindowCommon.ReleaseDC(m.HWnd, hDC); if (hrgnWindow != IntPtr.Zero) { NativeWindowCommon.DeleteObject(hrgnWindow); } if (hrgnClient != IntPtr.Zero) { NativeWindowCommon.DeleteObject(hrgnClient); } } } }