dotnet/wpf · error · InvalidOperationException

SR.ChildWindowNotCreated

Error message

SR.ChildWindowNotCreated

What it means

HwndHost.BuildWindow validates the HWND returned by the derived class's BuildWindowCore override. If the returned handle is IntPtr.Zero or no longer a valid window (IsWindow fails), it throws InvalidOperationException (SR.ChildWindowNotCreated) because the subclass failed to create its child window.

Solutions

  1. Fix BuildWindowCore so it returns a valid, live HWND; check the native CreateWindow/CreateWindowEx result before returning.
  2. If native creation fails, throw a meaningful exception from BuildWindowCore instead of returning zero.
  3. Ensure the native control is created on the same UI thread and not destroyed prematurely.

Example fix

// before
protected override HandleRef BuildWindowCore(HandleRef parent) =>
    new HandleRef(this, _maybeZeroHwnd);
// after
protected override HandleRef BuildWindowCore(HandleRef parent) {
    var hwnd = NativeMethods.CreateControlWindow(parent.Handle);
    if (hwnd == IntPtr.Zero)
        throw new Win32Exception(Marshal.GetLastWin32Error());
    return new HandleRef(this, hwnd);
}
Defensive patterns

Strategy: validation

Validate before calling

var hwnd = NativeCreateWindow(...);
if (hwnd == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(hwnd))
    throw new Win32Exception(Marshal.GetLastWin32Error());
// then return it from BuildWindowCore

Type guard

bool IsValidHwnd(IntPtr hwnd) => hwnd != IntPtr.Zero && UnsafeNativeMethods.IsWindow(hwnd);

Try / catch

try
{
    hwndHost.Measure(arrangeSize);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("child window"))
{
    Log($"BuildWindowCore returned an invalid HWND: {ex}");
}

Prevention

When it happens

Trigger: A derived HwndHost's BuildWindowCore returned a null/zero HandleRef without throwing, or returned a handle to a window that was already destroyed before validation.

Common situations: Custom HwndHost subclasses wrapping native controls whose creation failed silently, wrong parent handles, native DLL issues, or returning a destroyed handle on re-hosting.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/d3519805d390d4f3. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Interop/HwndHost.cs:1011

            finally
            {
                // Be careful to clear our guard bit.
                _isBuildingWindow = false;
            }
        }


        private void BuildWindow(HandleRef hwndParent)
        {
            // Demand unmanaged code to the caller. IT'S RISKY TO REMOVE THIS
            DemandIfUntrusted();

            // Allow the derived class to build our HWND.
            _hwnd = BuildWindowCore(hwndParent);

            if(_hwnd.Handle == IntPtr.Zero || !UnsafeNativeMethods.IsWindow(_hwnd))
            {
                throw new InvalidOperationException(SR.ChildWindowNotCreated);
            }

            // Make sure that the window that was created is indeed a child window.
            int windowStyle = UnsafeNativeMethods.GetWindowLong(new HandleRef(this,_hwnd.Handle), NativeMethods.GWL_STYLE);
            if((windowStyle & NativeMethods.WS_CHILD) == 0)
            {
                throw new InvalidOperationException(SR.HostedWindowMustBeAChildWindow);
            }

            // Make sure the child window is the child of the expected parent window.
            if(hwndParent.Handle != UnsafeNativeMethods.GetParent(_hwnd))
            {
                throw new InvalidOperationException(SR.ChildWindowMustHaveCorrectParent);
            }

            // Test to see if hwndParent and _hwnd have different DPI_AWARENESS_CONTEXT's
            if (DpiUtil.GetDpiAwarenessContext(_hwnd.Handle) != DpiUtil.GetDpiAwarenessContext(hwndParent.Handle))
            {

View on GitHub (pinned to 81131a70a4)