dotnet/wpf · error · InvalidOperationException
SR.ChildWindowMustHaveCorrectParent
Error message
SR.ChildWindowMustHaveCorrectParent
What it means
HwndHost.BuildWindow checks that the hosted HWND's parent is exactly the parent handle WPF passed in. If GetParent(_hwnd) does not match hwndParent, it throws InvalidOperationException (SR.ChildWindowMustHaveCorrectParent), enforcing that the child window was created with (or reparented to) the expected WPF parent.
Solutions
- Create the window with the hwndParent passed to BuildWindowCore as its parent.
- If wrapping an existing window, call SetParent(existingHwnd, hwndParent.Handle) before returning it.
- Check for third-party code re-parenting the window and remove or defer that reparenting.
Example fix
// before
protected override HandleRef BuildWindowCore(HandleRef parent) {
return new HandleRef(this, CreateWindow(cls, IntPtr.Zero)); // NULL parent
}
// after
protected override HandleRef BuildWindowCore(HandleRef parent) {
return new HandleRef(this, CreateWindow(cls, parent.Handle));
} Defensive patterns
Strategy: validation
Validate before calling
if (UnsafeNativeMethods.GetParent(hwnd) != parent.Handle)
UnsafeNativeMethods.SetParent(new HandleRef(null, hwnd), parent); Type guard
bool HasExpectedParent(IntPtr child, IntPtr expectedParent) =>
UnsafeNativeMethods.GetParent(child) == expectedParent; Prevention
- Create hosted windows using exactly the hwndParent passed to BuildWindowCore.
- Call SetParent when adopting existing windows into the WPF tree.
- Audit native libraries for re-parenting behavior that changes the window's parent.
When it happens
Trigger: BuildWindowCore creates the window with a different/NULL parent, reparents the window after creation, or another component re-parents the HWND before HwndHost validation runs.
Common situations: Wrapping pre-existing native windows without calling SetParent, native libraries that re-parent their own windows, passing IntPtr.Zero as parent in custom CreateWindow calls.
Related errors
- SR.ChildWindowNotCreated
- SR.HostedWindowMustBeAChildWindow
- ArgumentNullException
- InvalidOperationException
- InvalidOperationException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ce31d5608c5bee30.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Interop/HwndHost.cs:1024
// 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))
{
_hasDpiAwarenessContextTransition = true;
}
// Only subclass the child HWND if it is owned by our thread.
int idWindowProcess;
int idWindowThread = UnsafeNativeMethods.GetWindowThreadProcessId(_hwnd, out idWindowProcess);
#if WCP_SERVER2003_OR_LATER_ENABLED
IntPtr hCurrentThread = UnsafeNativeMethods.GetCurrentThread();
if ((idWindowThread == SafeNativeMethods.GetThreadId(hCurrentThread)) &&
(idWindowProcess == UnsafeNativeMethods.GetProcessIdOfThread(hCurrentThread)))
#else
if ((idWindowThread == SafeNativeMethods.GetCurrentThreadId()) &&View on GitHub (pinned to 81131a70a4)