2

我试图捕捉并重新翻译键盘和鼠标事件。所以我在 dll 中使用 SetWindowsHookEx 和函数。第一次 Ш 有一个大错误 - GetProcAddress 无法获取我的函数。这个答案对我有很大帮助GetProcAddress 返回 NULL

现在我可以从 dll 调用函数,我可以从钩子中看到效果:我的键盘在程序运行时不起作用。但是没有调用钩子。

主文件

#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, "_hookProcedure@12");//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;
}

钩子dll.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;
}
4

1 回答 1

1

键盘钩子允许你拦截WM_KEYDOWNWM_KEYUP窗口消息。除非有活动的 Windows 消息队列,否则控制台应用程序不会收到这些消息。如果您想在控制台应用程序中查看和处理这些消息,请创建一个窗口并为其提供键盘焦点。pumping确保在拥有窗口的线程中使用GetMessageDispatchMessageWinAPI 调用进行消息传递。

如果您不想创建窗口,您可以使用WH_KEYBOARD_LL拦截发送到线程的活动消息队列的键盘相关消息。您仍然需要使用GetMessage从队列中读取,否则它最终会开始丢弃消息。

于 2013-05-26T18:44:23.593 回答