protected IntPtr CombineRgn(IntPtr hrgnSrc1, IntPtr hrgnSrc2, int fnCombineMode) { IntPtr hRegion = Gdi32.CreateRectRgn(Rectangle.Empty); Gdi32.CombineRgn(hRegion, hrgnSrc1, hrgnSrc2, fnCombineMode); return(hRegion); }
private IntPtr GetRegion() { IntPtr hShadowReg = IntPtr.Zero; IntPtr hOwnerReg = IntPtr.Zero; IntPtr hRegion = IntPtr.Zero; try { var rect = new RECT(); User32.GetWindowRect(_handle, ref rect); hShadowReg = Gdi32.CreateRectRgn(0, 0, rect.Width, rect.Height); hOwnerReg = Gdi32.CreateRectRgn(GetRegionRect()); hRegion = CombineRgn(hShadowReg, hOwnerReg, 4); } finally { if (hShadowReg != IntPtr.Zero) { Gdi32.DeleteObject(hShadowReg); } if (hOwnerReg != IntPtr.Zero) { Gdi32.DeleteObject(hOwnerReg); } } return(hRegion); }
/// <summary> /// This code is required to set the correct window region during the resize of the Form at design time. /// There is case when the form contains a MainMenu and also has IsMdiContainer property set, in which, the MdiClient fails to /// resize and hence draw the correct backcolor. /// </summary> private void SetWindowRgn() { IntPtr rgn1 = IntPtr.Zero; IntPtr rgn2 = IntPtr.Zero; RECT rect = new RECT(); CreateParams cp = CreateParams; AdjustWindowRectEx(ref rect, cp.Style, false, cp.ExStyle); Rectangle bounds = Bounds; rgn1 = Gdi32.CreateRectRgn(0, 0, bounds.Width, bounds.Height); try { rgn2 = Gdi32.CreateRectRgn( -rect.left, -rect.top, bounds.Width - rect.right, bounds.Height - rect.bottom); try { if (rgn1 == IntPtr.Zero || rgn2 == IntPtr.Zero) { throw new InvalidOperationException(SR.ErrorSettingWindowRegion); } if (Gdi32.CombineRgn(rgn1, rgn1, rgn2, Gdi32.CombineMode.RGN_DIFF) == 0) { throw new InvalidOperationException(SR.ErrorSettingWindowRegion); } if (UnsafeNativeMethods.SetWindowRgn(new HandleRef(this, Handle), new HandleRef(null, rgn1), true) == 0) { throw new InvalidOperationException(SR.ErrorSettingWindowRegion); } else { // The hwnd now owns the region. rgn1 = IntPtr.Zero; } } finally { if (rgn2 != IntPtr.Zero) { Gdi32.DeleteObject(rgn2); } } } finally { if (rgn1 != IntPtr.Zero) { Gdi32.DeleteObject(rgn1); } } }
static void SetRegion(IntPtr hwnd, int width, int height, bool force) { if (Dwmapi.IsCompositionEnabled) { //clear if (force) { User32.SetWindowRgn(hwnd, IntPtr.Zero, User32.IsWindowVisible(hwnd)); } } else { var wpl = default(WINDOWPLACEMENT); wpl.length = (uint)Marshal.SizeOf(typeof(WINDOWPLACEMENT)); if (User32.GetWindowPlacement(hwnd, ref wpl)) { if (wpl.showCmd == ShowWindowOption.SW_MAXIMIZE) { //clear User32.SetWindowRgn(hwnd, IntPtr.Zero, User32.IsWindowVisible(hwnd)); } else { // always rectangle to prevent rounded corners for some themes IntPtr rgn = IntPtr.Zero; try { if (width == 0 || height == 0) { RECT r = default(RECT); User32.GetWindowRect(hwnd, ref r); width = r.Width; height = r.Height; } rgn = Gdi32.CreateRectRgn(0, 0, width, height); User32.SetWindowRgn(hwnd, rgn, User32.IsWindowVisible(hwnd)); } finally { if (rgn != IntPtr.Zero) { Gdi32.DeleteObject(rgn); } } } } } }
public unsafe DCMapping(IntPtr hDC, Rectangle bounds) { if (hDC == IntPtr.Zero) { throw new ArgumentNullException(nameof(hDC)); } bool success; IntPtr hOriginalClippingRegion = IntPtr.Zero; _translatedBounds = bounds; _graphics = null; _dc = DeviceContext.FromHdc(hDC); _dc.SaveHdc(); // Retrieve the x-coordinates and y-coordinates of the viewport origin for the specified device context. success = Gdi32.GetViewportOrgEx(hDC, out Point viewportOrg).IsTrue(); Debug.Assert(success, "GetViewportOrgEx() failed."); // Create a new rectangular clipping region based off of the bounds specified, shifted over by the x & y specified in the viewport origin. IntPtr hClippingRegion = Gdi32.CreateRectRgn(viewportOrg.X + bounds.Left, viewportOrg.Y + bounds.Top, viewportOrg.X + bounds.Right, viewportOrg.Y + bounds.Bottom); Debug.Assert(hClippingRegion != IntPtr.Zero, "CreateRectRgn() failed."); try { // Create an empty region oriented at 0,0 so we can populate it with the original clipping region of the hDC passed in. hOriginalClippingRegion = Gdi32.CreateRectRgn(0, 0, 0, 0); Debug.Assert(hOriginalClippingRegion != IntPtr.Zero, "CreateRectRgn() failed."); // Get the clipping region from the hDC: result = {-1 = error, 0 = no region, 1 = success} per MSDN int result = Gdi32.GetClipRgn(hDC, hOriginalClippingRegion); Debug.Assert(result != -1, "GetClipRgn() failed."); // Shift the viewpoint origint by coordinates specified in "bounds". var lastViewPort = new Point(); success = Gdi32.SetViewportOrgEx(hDC, viewportOrg.X + bounds.Left, viewportOrg.Y + bounds.Top, &lastViewPort).IsTrue(); Debug.Assert(success, "SetViewportOrgEx() failed."); RegionType originalRegionType; if (result != 0) { // Get the origninal clipping region so we can determine its type (we'll check later if we've restored the region back properly.) RECT originalClipRect = new RECT(); originalRegionType = Gdi32.GetRgnBox(hOriginalClippingRegion, ref originalClipRect); Debug.Assert(originalRegionType != RegionType.ERROR, "ERROR returned from SelectClipRgn while selecting the original clipping region.."); if (originalRegionType == RegionType.SIMPLEREGION) { // Find the intersection of our clipping region and the current clipping region (our parent's) // Returns a NULLREGION, the two didn't intersect. // Returns a SIMPLEREGION, the two intersected // Resulting region (stuff that was in hOriginalClippingRegion AND hClippingRegion is placed in hClippingRegion RegionType combineResult = Gdi32.CombineRgn(hClippingRegion, hClippingRegion, hOriginalClippingRegion, Gdi32.CombineMode.RGN_AND); Debug.Assert((combineResult == RegionType.SIMPLEREGION) || (combineResult == RegionType.NULLREGION), "SIMPLEREGION or NULLREGION expected."); } } else { // If there was no clipping region, then the result is a simple region. // We don't need to keep track of the original now, since it is empty. Gdi32.DeleteObject(hOriginalClippingRegion); hOriginalClippingRegion = IntPtr.Zero; originalRegionType = RegionType.SIMPLEREGION; } // Select the new clipping region; make sure it's a SIMPLEREGION or NULLREGION RegionType selectResult = Gdi32.SelectClipRgn(hDC, hClippingRegion); Debug.Assert((selectResult == RegionType.SIMPLEREGION || selectResult == RegionType.NULLREGION), "SIMPLEREGION or NULLLREGION expected."); } catch (Exception ex) when(!ClientUtils.IsSecurityOrCriticalException(ex)) { _dc.RestoreHdc(); _dc.Dispose(); } finally { // Delete the new clipping region, as the clipping region for the HDC is now set // to this rectangle. Hold on to hOriginalClippingRegion, as we'll need to restore // it when this object is disposed. success = Gdi32.DeleteObject(hClippingRegion).IsTrue(); Debug.Assert(success, "DeleteObject(hClippingRegion) failed."); if (hOriginalClippingRegion != IntPtr.Zero) { success = Gdi32.DeleteObject(hOriginalClippingRegion).IsTrue(); Debug.Assert(success, "DeleteObject(hOriginalClippingRegion) failed."); } } }
private void CreateRegion(Rectangle rect) { Debug.Assert(nativeHandle == IntPtr.Zero, "nativeHandle should be null, we're leaking handle"); nativeHandle = Gdi32.CreateRectRgn(rect.X, rect.Y, rect.Right, rect.Bottom); ownHandle = true; }