예제 #1
0
        protected IntPtr CombineRgn(IntPtr hrgnSrc1, IntPtr hrgnSrc2, int fnCombineMode)
        {
            IntPtr hRegion = Gdi32.CreateRectRgn(Rectangle.Empty);

            Gdi32.CombineRgn(hRegion, hrgnSrc1, hrgnSrc2, fnCombineMode);
            return(hRegion);
        }
예제 #2
0
        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);
        }
예제 #3
0
        /// <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);
                }
            }
        }
예제 #4
0
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
            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.");
                    }
                }
            }
예제 #6
0
 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;
 }