My dll uses SetWindowsHookEx to get into the main window's thread ( 3rd party application ) to subclass it with SetWindowSubclass. Subclassed window procedure is used just to control additional child window added to the main window. RemoveWindowSubclass is called inside window procedure on WM_DESTROY. When the hooked window is closed by user, application unloads dll. After DLL_PROCESS_DETACH is processed, sometimes ( on some pc's ) application is crashed. All threads which dll created are finished before DLL_PROCESS_DETACH, so it does not look like some not finished cleanup. After many experiments i've found out that commenting all this subclassing stuff solves the crash. So what am i doing wrong?
Here are code snippets to verify
Here is subclasser methods
BOOL CSubclasser2::subclass( HWND hwnd, SUBCLASSPROC proc, DWORD_PTR data )
{
BOOL res;
if( GetCurrentThreadId() == GetWindowThreadProcessId( hwnd, 0 ) )
{
res = SetWindowSubclass( hwnd, proc, 0, data );
}
else
{
m_hwnd = hwnd;
m_wndProc = proc;
m_pData = data;
m_bSubclass = TRUE;
setHook();
SendMessage( hwnd, WM_NULL, 0, 0 ); //waiting for hook proc called
unsetHook();
res = m_subclassed;
}
void CSubclasser2::setHook()
{
if( !m_hook )
{
m_hook = SetWindowsHookEx( WH_CALLWNDPROC, m_hookCallWndProc, 0, GetWindowThreadProcessId( m_hwnd, 0 ) );
}
}
LRESULT CALLBACK CSubclasser2::m_hookCallWndProc( int nCode, WPARAM wParam, LPARAM lParam )
{
if( nCode == HC_ACTION && m_hwnd && ( ( CWPSTRUCT* )lParam )->hwnd == m_hwnd )
{
if( m_bSubclass )
{
m_subclassed = SetWindowSubclass( m_hwnd, m_wndProc, 0, m_pData );
}
else
{
m_subclassed = RemoveWindowSubclass( m_hwnd, m_wndProc, 0 );
}
m_hwnd = 0;
}
return( CallNextHookEx( 0, nCode, wParam, lParam ) );
}
Here is WM_DESTROY handler
...
case WM_DESTROY:
g_sc->unsubclass( hWnd, ( SUBCLASSPROC )wndProc );
break;
}
return( DefSubclassProc( hwnd, msg, wp, lp ) );
unsubclass() method works similar to subclass(). Of course, in case of calling unsubclass() on WM_DESTROY, direct RemoveWindowSubclass is called instead of SetWindowsHookEx.