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
- Fix BuildWindowCore so it returns a valid, live HWND; check the native CreateWindow/CreateWindowEx result before returning.
- If native creation fails, throw a meaningful exception from BuildWindowCore instead of returning zero.
- 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
- Check native CreateWindow return values and GetLastError in BuildWindowCore.
- Throw early with a specific message instead of returning a zero handle.
- Verify the native control exists and is created on the UI thread.
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
- new System.ComponentModel.Win32Exception(win32Error)
- SR.ChildWindowMustHaveCorrectParent
- SR.HostedWindowMustBeAChildWindow
- The operation completed successfully.
- Win32Exception (native SystemParametersInfo failure…
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)