/// <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; NativeMethods.RECT rect = new NativeMethods.RECT(); CreateParams cp = CreateParams; AdjustWindowRectEx(ref rect, cp.Style, false, cp.ExStyle); Rectangle bounds = Bounds; rgn1 = SafeNativeMethods.CreateRectRgn(0, 0, bounds.Width, bounds.Height); try { rgn2 = SafeNativeMethods.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 (SafeNativeMethods.CombineRgn(new HandleRef(null, rgn1), new HandleRef(null, rgn1), new HandleRef(null, rgn2), NativeMethods.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) { SafeNativeMethods.DeleteObject(new HandleRef(null, rgn2)); } } } finally { if (rgn1 != IntPtr.Zero) { SafeNativeMethods.DeleteObject(new HandleRef(null, rgn1)); } } }
private void InvalidateNonClient() { if (!IsPopupTextBox) { return; } NativeMethods.RECT absoluteClientRectangle = AbsoluteClientRECT; HandleRef hNonClientRegion = NativeMethods.NullHandleRef; HandleRef hClientRegion = NativeMethods.NullHandleRef; HandleRef hTotalRegion = NativeMethods.NullHandleRef; try { // get the total client area, then exclude the client by using XOR hTotalRegion = new HandleRef(this, SafeNativeMethods.CreateRectRgn(0, 0, this.Width, this.Height)); hClientRegion = new HandleRef(this, SafeNativeMethods.CreateRectRgn(absoluteClientRectangle.left, absoluteClientRectangle.top, absoluteClientRectangle.right, absoluteClientRectangle.bottom)); hNonClientRegion = new HandleRef(this, SafeNativeMethods.CreateRectRgn(0, 0, 0, 0)); SafeNativeMethods.CombineRgn(hNonClientRegion, hTotalRegion, hClientRegion, NativeMethods.RGN_XOR); // Call RedrawWindow with the region. NativeMethods.RECT ignored = new NativeMethods.RECT(); SafeNativeMethods.RedrawWindow(new HandleRef(this, Handle), ref ignored, hNonClientRegion, NativeMethods.RDW_INVALIDATE | NativeMethods.RDW_ERASE | NativeMethods.RDW_UPDATENOW | NativeMethods.RDW_ERASENOW | NativeMethods.RDW_FRAME); } finally { // clean up our regions. try { if (hNonClientRegion.Handle != IntPtr.Zero) { SafeNativeMethods.DeleteObject(hNonClientRegion); } } finally { try { if (hClientRegion.Handle != IntPtr.Zero) { SafeNativeMethods.DeleteObject(hClientRegion); } } finally { if (hTotalRegion.Handle != IntPtr.Zero) { SafeNativeMethods.DeleteObject(hTotalRegion); } } } } }
public DCMapping(HandleRef hDC, Rectangle bounds) { if (hDC.Handle == IntPtr.Zero) { throw new ArgumentNullException("hDC"); } bool success; NativeMethods.POINT viewportOrg = new NativeMethods.POINT(); HandleRef hOriginalClippingRegion = NativeMethods.NullHandleRef; NativeMethods.RegionFlags originalRegionType = NativeMethods.RegionFlags.NULLREGION; this.translatedBounds = bounds; this.graphics = null; this.dc = DeviceContext.FromHdc(hDC.Handle); this.dc.SaveHdc(); // Retrieve the x-coordinates and y-coordinates of the viewport origin for the specified device context. success = SafeNativeMethods.GetViewportOrgEx(hDC, viewportOrg); 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. HandleRef hClippingRegion = new HandleRef(null, SafeNativeMethods.CreateRectRgn(viewportOrg.x + bounds.Left, viewportOrg.y + bounds.Top, viewportOrg.x + bounds.Right, viewportOrg.y + bounds.Bottom)); Debug.Assert(hClippingRegion.Handle != 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 = new HandleRef(this, SafeNativeMethods.CreateRectRgn(0, 0, 0, 0)); Debug.Assert(hOriginalClippingRegion.Handle != IntPtr.Zero, "CreateRectRgn() failed."); // Get the clipping region from the hDC: result = {-1 = error, 0 = no region, 1 = success} per MSDN int result = SafeNativeMethods.GetClipRgn(hDC, hOriginalClippingRegion); Debug.Assert(result != -1, "GetClipRgn() failed."); // Shift the viewpoint origint by coordinates specified in "bounds". NativeMethods.POINT lastViewPort = new NativeMethods.POINT(); success = SafeNativeMethods.SetViewportOrgEx(hDC, viewportOrg.x + bounds.Left, viewportOrg.y + bounds.Top, lastViewPort); Debug.Assert(success, "SetViewportOrgEx() failed."); 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.) NativeMethods.RECT originalClipRect = new NativeMethods.RECT(); originalRegionType = (NativeMethods.RegionFlags)SafeNativeMethods.GetRgnBox(hOriginalClippingRegion, ref originalClipRect); Debug.Assert(originalRegionType != NativeMethods.RegionFlags.ERROR, "ERROR returned from SelectClipRgn while selecting the original clipping region.."); if (originalRegionType == NativeMethods.RegionFlags.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 NativeMethods.RegionFlags combineResult = (NativeMethods.RegionFlags)SafeNativeMethods.CombineRgn(hClippingRegion, hClippingRegion, hOriginalClippingRegion, NativeMethods.RGN_AND); Debug.Assert((combineResult == NativeMethods.RegionFlags.SIMPLEREGION) || (combineResult == NativeMethods.RegionFlags.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. SafeNativeMethods.DeleteObject(hOriginalClippingRegion); hOriginalClippingRegion = new HandleRef(null, IntPtr.Zero); originalRegionType = NativeMethods.RegionFlags.SIMPLEREGION; } // Select the new clipping region; make sure it's a SIMPLEREGION or NULLREGION NativeMethods.RegionFlags selectResult = (NativeMethods.RegionFlags)SafeNativeMethods.SelectClipRgn(hDC, hClippingRegion); Debug.Assert((selectResult == NativeMethods.RegionFlags.SIMPLEREGION || selectResult == NativeMethods.RegionFlags.NULLREGION), "SIMPLEREGION or NULLLREGION expected."); } catch (Exception ex) { if (ClientUtils.IsSecurityOrCriticalException(ex)) { throw; } this.dc.RestoreHdc(); this.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 = SafeNativeMethods.DeleteObject(hClippingRegion); Debug.Assert(success, "DeleteObject(hClippingRegion) failed."); if (hOriginalClippingRegion.Handle != IntPtr.Zero) { success = SafeNativeMethods.DeleteObject(hOriginalClippingRegion); Debug.Assert(success, "DeleteObject(hOriginalClippingRegion) failed."); } } }