I performed a few more tests - it turns out that this was working only because the same copy of mIRC was sending the WM_PRINT message to itself.

After adding some debug code to monitor WM_PRINT and WM_PRINTCLIENT requests, it turns out that if mIRC receives a WM_PRINT from an external application, nothing else happens - the WM_PRINT is not propagated. If I send WM_PRINTCLIENT directly to the text display routine, it receives the message, however even if I perform a simple FillRect() on the memory dc, it remains black.

As far as I know, HDCs cannot be passed across processes, however I assumed that WM_PRINT would bypass that. It seems that it does not. Either that or it requires a special type of HDC that can be used across processes.