我的dll使用SetWindowsHookEx进入主窗口的线程(第三方应用程序)以使用SetWindowSubclass对其进行子类化。子类窗口过程仅用于控制添加到主窗口的附加子窗口。在WM_DESTROY上的窗口过程内调用RemoveWindowSubclass。当用户关闭钩子窗口时,应用程序卸载dll。处理DLL_PROCESS_DETACH后,有时(在某些PC上)应用程序崩溃。 dll创建的所有线程都在DLL_PROCESS_DETACH之前完成,因此它看起来不像一些未完成的清理。经过多次实验,我发现评论所有这些子类化的东西可以解决崩溃问题。我做错了什么?
以下是验证的代码段
这是子类方法
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 ) );
}
这是WM_DESTROY处理程序
...
case WM_DESTROY:
g_sc->unsubclass( hWnd, ( SUBCLASSPROC )wndProc );
break;
}
return( DefSubclassProc( hwnd, msg, wp, lp ) );
unsubclass()方法的工作方式类似于subclass()。当然,如果在WM_DESTROY上调用unsubclass(),则直接调用RemoveWindowSubclass而不是SetWindowsHookEx。