SetWindowSubclass + SetWindowsHookEx =没有完全清理和崩溃?

时间:2014-04-22 18:58:24

标签: c++ winapi hook subclassing

我的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。

0 个答案:

没有答案