2013-05-26 108 views
2

我試圖捕獲並重新翻譯鍵盤和鼠標事件。所以我使用SetWindowsHookEx和函數在DLL中。第一次Ш有一個大錯誤 - GetProcAddress無法獲得我的功能。這個答案幫了我很多GetProcAddress returns NULL不調用DLL鉤函數

現在我可以從dll調用函數,並且可以從鉤子看到效果:當程序運行時,我的鍵盤不工作。但鉤子不叫。

的main.cpp

#include <Windows.h> 
#include <WinUser.h> 
#include <iostream> 
#include <fstream> 
using namespace std; 
HHOOK hhk; 


int main(){ 
    HINSTANCE hinstLib = LoadLibrary(TEXT("hookdll.dll")); 
    typedef void (*Install)(); 
    typedef void (*Uninstall)(); 
    typedef LRESULT (_stdcall *HookProcedure)(int, WPARAM , LPARAM); 
    Install install = (Install) GetProcAddress(hinstLib, "install"); 
    Uninstall uninstall = (Uninstall) GetProcAddress(hinstLib, "uninstall"); 
    HookProcedure hookProc = (HookProcedure) GetProcAddress(hinstLib, "[email protected]");//omg 
    cout << GetLastError()<< "\n"; 
    install(); 
    hhk = SetWindowsHookEx(WH_KEYBOARD, hookProc, hinstLib, NULL); 
    cout << GetLastError()<< "\n"; 
    for(int i = 0; i < 50; i++){ 
     Sleep(200); 
     cout << i << "\n"; 
    } 
    UnhookWindowsHookEx(hhk); 
    uninstall(); 
    return 0; 
} 

hookdll.cpp

#include <Windows.h> 
#include <iostream> 
#include <fstream> 

HINSTANCE hinst; 
HHOOK hhk; 
std::ofstream myfile; 

extern "C" __declspec(dllexport) 
LRESULT CALLBACK hookProcedure(int code, WPARAM w, LPARAM l) 
{ 
    MessageBox(NULL, (LPCWSTR)L"HEY HEY", (LPCWSTR)L"Test", MB_OK); 
    //never saw this message 
    return CallNextHookEx(NULL, code, w, l); 
} 

extern "C" __declspec(dllexport) void install() { 
    myfile.open("log.txt",std::ios_base::app); 
    myfile << "\ninstall " << GetLastError(); 
} 
extern "C" __declspec(dllexport) void uninstall() { 
    myfile << "\nuninstall " << GetLastError(); 
    myfile.close(); 
} 

extern "C" __declspec(dllexport) 
BOOL WINAPI DllMain( __in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved) { 
    hinst = hinstDLL; 
    return TRUE; 
} 

回答

1

鍵盤鉤子,您可以攔截WM_KEYDOWNWM_KEYUP窗口消息。除非有活動的Windows消息隊列,否則控制檯應用程序不會收到這些消息。如果您想在控制檯應用程序中查看和處理這些消息,請創建一個窗口併爲其指定鍵盤焦點。確保你在消息pumpingGetMessageDispatchMessage WinAPI調用擁有該窗口的線程。

如果您不想創建窗口,則可以使用WH_KEYBOARD_LL來攔截髮送到線程的活動消息隊列的鍵盤相關消息。您仍然需要使用GetMessage從隊列中讀取,否則它最終會開始丟棄消息。

+0

感謝您的回答。讓我檢查一下我是否理解鉤子的用途。我認爲我的程序是全球性的,抓住每一件事。如果我不正確可能是我需要在winapi的另一個功能?我也嘗試使用'SetWindowsHookEx(WH_KEYBOARD_LL,..)' - 結果是類似的。 – vlastachu

+0

**謝謝!** 給其他誰讀這個問題:下一個問題,我發現關鍵字http://stackoverflow.com/questions/7458807/why-must-setwindowshookex-be-used-with-a-windows - 消息隊列 看起來很奇怪,我不能相信調用dll和鏈接過程並鏈接到鉤子的過程也應該做無限循環。 – vlastachu

+0

請記住,如果您正在安裝全局鉤子,您的DLL將被注入到可應用鉤子的任何應用程序中。 –