0X000005A2

Fix ERROR_NOT_CHILD_WINDOW (0X000005A2) on Windows 10/11

Windows Errors Intermediate 👁 0 views 📅 May 28, 2026

This error means a window handle is treated as a child when it's not. Often hits during app development or custom UI scripts. Here's how to squash it fast.

What's Actually Happening

I know this error stings—especially when you're in the middle of debugging a custom UI or a third-party app integration. ERROR_NOT_CHILD_WINDOW (0X000005A2) pops up when you call a function like SetParent, GetParent, or SendMessage with a window handle that isn't a child of the target. Windows expects the handle to be a direct child (or at least a descendant) and throws this code at you. I've seen it most often when someone's using a desktop window handle or a top-level window as a child—both are no-gos.

Let me walk you through three tiers of fixes. Start with the simplest and stop when it's gone. No fluff, just fixes.

Quick Fix (30 seconds): Verify the Window Handle

Before you rewrite anything, check if you're passing the right handle. Nine times out of ten, the issue is a stale or wrong HWND.

  1. Open your debugger or log the handle value. If it's NULL or an old handle from a closed window, that's your problem.
  2. Use IsWindow(hWnd) in your code to confirm the handle still exists. If it returns false, grab a fresh handle via FindWindow or EnumWindows.
  3. Specifically test with IsChild(hWndParent, hWndChild)—if that returns false, you've got a non-child handle.

I've tripped over this myself: reusing a handle from a modal dialog that already closed. The fix was as simple as re-querying the window list. Don't overthink this step.

Moderate Fix (5 minutes): Correct the Parent-Child Relationship

If the handle is valid but still fails, you're likely calling a function that assumes a child relationship where none exists. Here's how to fix the two most common triggers.

Case 1: Using SetParent with a Top-Level Window

SetParent doesn't force a top-level window to become a child. It silently fails or throws this error. Instead, make sure the target window has the WS_CHILD style set. In C++, do this before calling SetParent:

LONG_PTR style = GetWindowLongPtr(hWndChild, GWL_STYLE);
style |= WS_CHILD;
SetWindowLongPtr(hWndChild, GWL_STYLE, style);
SetParent(hWndChild, hWndNewParent);

If you're in C# using P/Invoke, the same logic applies. Also strip WS_POPUP if it's set—that conflicts with WS_CHILD.

Case 2: SendMessage to a Non-Child

Messages like WM_CHILDACTIVATE or WM_MDIACTIVATE expect a child window. If you're sending these to a top-level window, switch to WM_ACTIVATE or rethink the message. I usually grep my codebase for WM_CHILD and review each call—half the time it's a copy-paste error from an MDI example.

Advanced Fix (15+ minutes): Debug the Window Hierarchy

When the easy stuff doesn't work, you need to see what Windows really thinks. This is where I've spent hours, but it's worth it.

Step 1: Use Spy++ to Inspect the Tree

Spy++ (spyxx.exe, ships with Visual Studio) shows the actual window hierarchy. Launch it, find your window by dragging the crosshair, and look at the parent chain. If the parent isn't what you expect, or if the window is an orphan (no parent), that's your culprit.

  1. In Spy++, go to Search > Find Window.
  2. Drag the finder tool to your app's window.
  3. Check the "Parent" and "Owner" fields. A child window must have a parent; an owner is different.

I've fixed this by noticing a window was attached to the desktop as a parent (yep, that's a real scenario). The fix was to reparent it to a valid container.

Step 2: Programmatic Hierarchy Dump

Write a quick function to dump the tree recursively. Here's a rough example:

void DumpWindowChain(HWND hWnd, int depth) {
    HWND parent = GetParent(hWnd);
    HWND owner = GetWindow(hWnd, GW_OWNER);
    printf("Depth %d: HWND=%p, Parent=%p, Owner=%p\n", depth, hWnd, parent, owner);
    HWND child = GetWindow(hWnd, GW_CHILD);
    while (child) {
        DumpWindowChain(child, depth+1);
        child = GetWindow(child, GW_HWNDNEXT);
    }
}

Run this on your target window and verify that the parent chain is intact. I've seen cases where a window was accidentally reparented to a destroyed control, leaving it hanging.

Step 3: Check for Threading Issues

A less common but nasty cause: the window handle belongs to a different thread. Windows has a rule that a child window must be created by the same thread as its parent. If you're using SetParent across threads, it'll often fail with this error. Use GetWindowThreadProcessId to check both handles. If they differ, you need to either move the window creation to the parent's thread or use FindWindow from the correct thread. This one bit me hard when I was working with a multithreaded plugin system.

When to Give Up and Use Alternatives

If you've tried all three and the error persists, consider a different approach. Instead of reparenting, try using SetWindowLongPtr with GWL_HWNDPARENT to set an owner (not a parent). Or use layered windows with WS_EX_LAYERED and UpdateLayeredWindow for overlay effects without child windows. I've had to do this twice in the past year—sometimes the window manager just doesn't play nice, and fighting it wastes time.

Also check for antivirus software interfering with window creation. I've seen Norton and McAfee block certain SetParent calls on Windows 10. Disable it temporarily to test.

That's it. Start with the handle, then the relationship, then the hierarchy. You'll beat this error—I've seen it vanish with just the first fix more often than not.

Was this solution helpful?