multithreading - Closing Window and Thread Generates Invalid Window Handle Error - C++ -
my console application spawns new (invisible) window in own thread. prior exiting application, attempts clean up, , last call getmessage
in window's message pump fails. getlasterror
returns 1400, "invalid window handle."
this how clean proceeds in application thread:
if ( s_hnotifywindowthread != null ) { assert(s_pobjnotifywindow != null); ::postmessage( s_pobjnotifywindow->m_hwnd, wm_close, 0, 0 ); ::waitforsingleobject( s_hnotifywindowthread, 50000l ); // step 1: breakpoint here ::closehandle( s_hnotifywindowthread ); // step 4: breakpoint here s_hnotifywindowthread = null; }
this wndproc
exists in new thread created window:
static lresult callback wndproc( hwnd hwnd, uint umsg, wparam wparam, lparam lparam ) { switch ( umsg ) { case wm_close: ::destroywindow( hwnd ); // step 2: breakpoint here break; case wm_destroy: ::postquitmessage( 0 ); // step 3: breakpoint here break; case wm_devicechange: /* handle device change. */ break; default: // nothing. break; } return ::defwindowproc( hwnd, umsg, wparam, lparam ); }
this in window's thread function new window created , message pump located:
s_pobjnotifywindow = new cnotifywindow( pparam ); while ( (bretval = ::getmessage( &msg, // message structure s_pobjnotifywindow->m_hwnd, // handle window messages retrieved 0, // lowest message value retrieve 0 // highest message value retrieve )) != 0 ) { switch ( bretval ) { case -1: // error generated in getmessage. trace(_t("notifywindowthreadfn : failed notify window message.\r\n\terror: %d\r\n\tfile: %s\r\n\tline: %d\r\n"), ::getlasterror(), __wfile__, __line__); return ::getlasterror(); // step 5: breakpoint here: returns error 1400 break; default: // other message received. ::translatemessage( &msg ); ::dispatchmessage( &msg ); break; } }
what doing wrong? thanks.
you passing invalid window handle getmessage, why it's failing , reporting window handle invalid.
you'll see same error if run code made-up window handle:
msg msg = {0}; bool b = ::getmessage(&msg, (hwnd)(0x123000), 0, 0); if (b == -1) { dword dwerr = ::getlasterror(); wprintf(l"%lu\n", dwerr); }
the problem still using window handle after window has been destroyed. window destroyed handle invalid (or, worse, re-used other window). message pump won't exit until processes quit-message. since quit-message posted during window destruction processed after window destruction complete. i.e. message pump keeps running short time after window destroyed.
just pass null getmessage window argument, retrieves messages windows on thread. since thread exists 1 window it's going messages window anyway. (plus quit-message posted thread itself, , potentially messages other windows things com creates if use com on thread... you'd want process messages, telling getmessage filter window doing nothing @ best , prevent working @ worst, in addition error you're seeing getmessage return.)
Comments
Post a Comment