2013-12-03 31 views
2

我創建了一個使用CBT掛鉤來掛鉤某些事件的DLL。它似乎只適用於啓動過程中創建的窗口...CBT Hook只接收一些事件

我的系統是Windows 7 x64,但在x32上的行爲也是一樣的。

這是代碼(抱歉,我不是C++專家):

#include "windows.h" 

extern "C" 
{ 
    static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam); 
    HINSTANCE g_hDll  = NULL; 
    HWND  g_hNotifyWin = NULL; 
    DWORD  g_uNotifyMsg = NULL; 
    HHOOK  g_hHook  = NULL; 

    __declspec(dllexport) HHOOK SetCbtHook(HWND hWnd, LPCWSTR lStrMsg, DWORD threadId) 
    { 
     g_hNotifyWin = hWnd; 
     g_uNotifyMsg = RegisterWindowMessage(lStrMsg); 
     g_hHook  = SetWindowsHookEx(WH_CBT, (HOOKPROC)CbtProcCb, g_hDll, threadId); 
     return g_hHook; 
    } 

    __declspec(dllexport) int UnsetCbtHook() 
    { 
     if (!g_hHook) 
      return 0; 
     return UnhookWindowsHookEx(g_hHook); 
    } 
} 

static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
    SendNotifyMessage(g_hNotifyWin, g_uNotifyMsg, nCode, wParam); // Send nCode to check the received event 
    return CallNextHookEx(g_hHook, nCode, wParam, lParam); 
} 

BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 
{ 
    if (fdwReason == DLL_PROCESS_ATTACH) 
     g_hDll = hinstDLL; 
    return true; 
} 

任何提示?

回答

3

當Windows安裝全局變量掛鉤時,實現掛鉤函數的DLL通常會加載到其他進程中。在這些過程中,全局變量爲g_hNotifyWing_uNotifyMsg爲NULL。在調用SetCbtHook的過程中,全局變量僅爲NULL。

您必須有辦法在任意進程中檢索g_hNotifyWin和'g_uNotifyMsg'的正確值。

地址:

const char * g_pszClassName = "MyClassName"; 
const char * g_pszRegisteredMsg = "MyMessage"; 

你的DLL,並通過g_hNotifyWin窗口的類名稱替換 「MyClassName」。請參閱EXE中的RegisterClass調用。更新「MyMessage」。

然後,使用以下CbtProcCb功能:

static LRESULT CALLBACK CbtProcCb(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
    if (nCode >= 0) { 
     if (g_hNotifyWin == NULL) g_hNotifyWin = FindWindow(g_pszClassName, NULL); 
     if (g_uNotifyMsg == 0) g_uNotifyMsg = RegisterWindowMessage(g_pszRegisteredMsg); 
     if (g_hNotifyWin && g_uNotifyMsg) 
      SendNotifyMessage(g_hNotifyWin, g_uNotifyMsg, nCode, wParam); // Send nCode to check the received event 
    } 
    return CallNextHookEx(NULL, nCode, wParam, lParam); // first arg useless see MSDN 
} 

編輯: 正如你在評論所指出的,g_uNotifyMsg同樣的問題,請參見更新的功能。實際上,您可以在DllMain中設置這些變量。

CallNextHookEx的第一個參數可能爲NULL。

+0

感謝您的帖子。我試着用你的代碼(稍微修改一下,因爲我認爲你用g_uNotifyMsg代替了g_hNotifyWin),但是它的行爲是一樣的。 無論如何,我想如果你猜測它是正確的,它也必須對其他全局變量有效,如g_uNotifyMsg。在DllMain中初始化它們可能是正確的嗎? – cyrusza

+0

對不起,低級別的答案。你是對的。更新! – manuell

+0

我設置了DllMain中的所有變量以避免回調中的混亂。它的工作,所以你的猜測是正確的!感謝您的幫助,非常感謝! 您是否認爲有機會通過這些值而不對其進行硬編碼? – cyrusza