HandyOrg/HandyControl · error · InvalidOperationException
Unable to combine two HRGNs.
Error message
Unable to combine two HRGNs.
What it means
WindowChromeWorker._CreateAndCombineRoundRectRgn builds a rounded-rectangle GDI region and OR-combines it into an existing HRGN using NativeMethods.CombineRgn. If CombineRgn returns CombineRgnResult.ERROR (a GDI failure), the worker throws InvalidOperationException because the window chrome region can no longer be constructed correctly. The original source HRGN is cleaned up safely before rethrowing.
Solutions
- Check for GDI handle leaks (GDI Objects count in Task Manager) and ensure all HRGNs are deleted via DeleteObject
- Verify the source hrgnSource handle is valid before combining
- Catch the InvalidOperationException around window chrome setup and fall back to a non-chrome (standard) window presentation
Example fix
// before
worker.EnableChrome(); // throws InvalidOperationException under GDI pressure
// after
try { worker.EnableChrome(); }
catch (InvalidOperationException) { /* fall back: don't customize chrome */ } Defensive patterns
Strategy: try-catch
Validate before calling
if (hrgnSource == IntPtr.Zero || hrgnSource == hrgnInvalid) throw new InvalidOperationException("Source HRGN is invalid before CombineRgn"); Type guard
bool IsValidRegion(IntPtr hrgn) => hrgn != IntPtr.Zero && NativeMethods.GetRegionData(hrgn, 0, IntPtr.Zero) != 0;
Try / catch
try { worker.EnableChrome(); } catch (InvalidOperationException ex) when (ex.Message == "Unable to combine two HRGNs.") { /* disable chrome customization, keep standard window frame */ } Prevention
- Always pair region creation with DeleteObject in a finally block
- Monitor GDI object counts for leaks under heavy window churn
- Recreate regions rather than reusing stale HRGN handles across window operations
When it happens
Trigger: CombineRgn returning ERROR during chrome region creation — typically when one of the HRGN handles is invalid/zero (previous _CreateRoundRectRgn failed under GDI resource pressure), or the target HRGN was already deleted.
Common situations: GDI handle exhaustion (many windows/regions leaked), window operations racing with handle destruction, running in Remote Desktop or low-memory sessions where GDI allocations fail.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Win32Exception
- Win32Exception
- Unable to create a device context from the specified device…
- Unable to initialize GDI+
- The element must be a DependencyObject
AI-assisted analysis of HandyOrg/HandyControl@2c0875ebd6 (2026-09-14).
Data as JSON: /api/errors/687c3bcc05cbf0e1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Shared/Microsoft.Windows.Shell/WindowChromeWorker.cs:630
private static IntPtr _CreateRoundRectRgn(Rect region, double radius)
{
if (DoubleUtilities.AreClose(0.0, radius))
{
return NativeMethods.CreateRectRgn((int) Math.Floor(region.Left), (int) Math.Floor(region.Top), (int) Math.Ceiling(region.Right), (int) Math.Ceiling(region.Bottom));
}
return NativeMethods.CreateRoundRectRgn((int) Math.Floor(region.Left), (int) Math.Floor(region.Top), (int) Math.Ceiling(region.Right) + 1, (int) Math.Ceiling(region.Bottom) + 1, (int) Math.Ceiling(radius), (int) Math.Ceiling(radius));
}
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "HRGNs")]
private static void _CreateAndCombineRoundRectRgn(IntPtr hrgnSource, Rect region, double radius)
{
IntPtr hrgnSrc = IntPtr.Zero;
try
{
hrgnSrc = WindowChromeWorker._CreateRoundRectRgn(region, radius);
if (NativeMethods.CombineRgn(hrgnSource, hrgnSource, hrgnSrc, RGN.OR) == CombineRgnResult.ERROR)
{
throw new InvalidOperationException("Unable to combine two HRGNs.");
}
}
catch
{
Utility.SafeDeleteObject(ref hrgnSrc);
throw;
}
}
private static bool _IsUniform(CornerRadius cornerRadius)
{
return DoubleUtilities.AreClose(cornerRadius.BottomLeft, cornerRadius.BottomRight) && DoubleUtilities.AreClose(cornerRadius.TopLeft, cornerRadius.TopRight) && DoubleUtilities.AreClose(cornerRadius.BottomLeft, cornerRadius.TopRight);
}
private void _ExtendGlassFrame()
{
if (!Utility.IsOSVistaOrNewer)
{View on GitHub (pinned to 2c0875ebd6)