Windows ERROR_NON_MDICHILD_WINDOW (0x000005A5) Fix
You'll see this when an MDI app tries to send a message to a window that isn't a child. The fix is usually updating or reinstalling the app.
When You'll See This Error
You're running some old business software—maybe a custom LOB app written in VB6, or a legacy accounting tool from the late '90s. Everything's fine until you try to open a second document window, or switch between open windows, or click a button. Then boom: ERROR_NON_MDICHILD_WINDOW (0x000005A5). The app either freezes or pops up a cryptic message. Had a client last month whose entire print queue died because of this—their invoice generation script kept hitting it.
This error code means your Multiple Document Interface (MDI) application tried to send a message to a window it thought was a child, but that window isn't actually an MDI child window. It's like handing a delivery to the wrong neighbor.
What Causes It
MDI apps use a parent window that manages multiple child windows (documents). The app expects every window handle (hWnd) it passes to certain functions—like SendMessage or DefMDIChildProc—to be a valid child of the MDI frame. When it isn't, Windows throws 0x000005A5.
Real-world triggers:
- Corrupted window handle: The app stored a stale handle that no longer points to a valid MDI child. This happens after closing a document and reopening it.
- API abuse: The developer used
SendMessageinstead ofPostMessageto an MDI child, or forgot to callIsWindowbefore sending. - Compatibility layer glitch: Running a 16-bit or 32-bit MDI app under 64-bit Windows (or via WOW64) can cause mismatches in window hierarchy checks.
- Resource leak: Too many open child windows without proper cleanup leaves orphaned handles.
The Fix
Skip the registry hacks and sfc /scannow—they won't fix a misbehaving MDI app. Here's what works:
- Step 1: Update or reinstall the app. Check the developer's site for a patch. If it's a VB6 app, Microsoft no longer supports it, but some vendors released compatibility updates. If no update exists, uninstall and reinstall the app to reset its internal handle table.
- Step 2: Run the app in compatibility mode. Right-click the .exe, go to Properties > Compatibility, and try Windows XP (SP3) or Windows 98 (if it's really ancient). This jiggers the MDI-related internal APIs.
- Step 3: Reduce window count. Close any unused child windows before opening new ones. If the app allows, limit it to one open document at a time.
- Step 4: Check for conflicting DLLs. Use Process Monitor to see if the app loads unexpected versions of comctl32.dll or user32.dll. A side-by-side assembly misconfiguration can cause this.
- Step 5: Increase the app's heap size. For VB6 apps, the default message box heap can overflow. Add a
.manifestfile to request a larger heap—Microsoft's KB article Q239469 covers this. Example manifest snippet:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
</assembly>
Still Failing?
If the error persists, you're likely dealing with a buggy app that can't be fixed externally. Here's what to check:
- Application event log: Look for Warnings from Application Popup, or Errors from Application Error. The module name and exception code (0xC0000005 is common) can point to the specific function call.
- Use a debugger: Attach WinDbg to the process and set a breakpoint on
user32!SendMessagewhen the error occurs. The call stack will show which window handle is suspect. - Virtualize: If nothing else works, run the app in a Windows XP Mode VM or a Windows 98 VirtualBox instance. That's the nuclear option, but it works 100% of the time for legacy MDI apps.
Most of the time, a reinstall or compatibility mode knocks this one out. But if you've got a really stubborn piece of software, don't waste hours chasing ghosts—just virtualize and move on.
Was this solution helpful?