{"record":{"id":"4d0238c7f13b7be0","repo":"dotnet/wpf","slug":"unable-to-combine-two-hrgns","errorCode":null,"errorMessage":"Unable to combine two HRGNs.","messagePattern":"Unable to combine two HRGNs\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Shell/WindowChromeWorker.cs","lineNumber":892,"sourceCode":"                (int)Math.Floor(region.Left),\n                (int)Math.Floor(region.Top),\n                (int)Math.Ceiling(region.Right) + 1,\n                (int)Math.Ceiling(region.Bottom) + 1,\n                (int)Math.Ceiling(radius),\n                (int)Math.Ceiling(radius));\n        }\n\n        [SuppressMessage(\"Microsoft.Naming\", \"CA2204:Literals should be spelled correctly\", MessageId = \"HRGNs\")]\n        private static void _CreateAndCombineRoundRectRgn(IntPtr hrgnSource, Rect region, double radius)\n        {\n            IntPtr hrgn = IntPtr.Zero;\n            try\n            {\n                hrgn = _CreateRoundRectRgn(region, radius);\n                CombineRgnResult result = NativeMethods.CombineRgn(hrgnSource, hrgnSource, hrgn, RGN.OR);\n                if (result == CombineRgnResult.ERROR)\n                {\n                    throw new InvalidOperationException(\"Unable to combine two HRGNs.\");\n                }\n            }\n            catch\n            {\n                Utility.SafeDeleteObject(ref hrgn);\n                throw;\n            }\n        }\n\n        private static bool _IsUniform(CornerRadius cornerRadius)\n        {\n            if (!DoubleUtilities.AreClose(cornerRadius.BottomLeft, cornerRadius.BottomRight))\n            {\n                return false;\n            }\n\n            if (!DoubleUtilities.AreClose(cornerRadius.TopLeft, cornerRadius.TopRight))\n            {","sourceCodeStart":874,"sourceCodeEnd":910,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Shell/WindowChromeWorker.cs#L874-L910","documentation":"When WindowChromeWorker builds the custom window region, it combines a rounded-rectangle HRGN into an existing region with the Win32 CombineRgn API. If CombineRgn returns ERROR, the code throws InvalidOperationException after cleaning up the native region handle, since the window region cannot be computed.","triggerScenarios":"CombineRgn(hrgnSource, hrgnSource, hrgn, RGN.OR) returning ERROR — typically when one of the HRGN handles is invalid or GDI resources/handles are exhausted.","commonSituations":"GDI handle leaks in the process exhausting resources; many concurrent custom-chromed windows; low-memory or remote-desktop sessions with constrained GDI; invalid region after prior native failures.","solutions":["Check for GDI handle leaks (GDI Objects count in Task Manager) and fix leaked HRGN/HDC/HBITMAP handles.","Reduce concurrent custom-chromed windows or release unused window chrome regions.","Catch the InvalidOperationException and fall back to the default (non-rounded) window region.","Restart the process if GDI exhaustion is persistent; keep the SafeDeleteObject cleanup path (the library already does this)."],"exampleFix":"// before\nWindowChromeWorker._UpdateRegion(...) // throws on GDI failure\n// after\ntry { chromeWorker.UpdateWindowRegion(); }\ncatch (InvalidOperationException ex)\n{\n    // fall back to default rectangular window region\n    Trace.WriteLine(\"Region combine failed: \" + ex.Message);\n}","handlingStrategy":"try-catch","validationCode":"int gdiCount = GetGuiResources(Process.GetCurrentProcess().Handle, 0); // GR_GDIOBJECTS\nif (gdiCount > 9000)\n    throw new InvalidOperationException(\"GDI handle exhaustion imminent\");","typeGuard":null,"tryCatchPattern":"try { worker.UpdateWindowRegion(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"HRGN\"))\n{ /* fall back to default rectangular region */ }","preventionTips":["Fix GDI handle leaks (delete HRGN/HDC/HBITMAP via DeleteObject).","Monitor the GDI Objects column in Task Manager in long-running apps.","Limit the number of simultaneously custom-chromed windows.","Wrap chrome-region updates in try/catch with a fallback to the default region."],"tags":["wpf","gdi","native-interop","window-chrome"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}