dll挂钩函数未调用

时间:2013-05-26 18:10:46

标签: c++ winapi dll hook

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

现在我可以从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, "_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;
}

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 个答案:

答案 0 :(得分:1)

键盘钩子允许您拦截WM_KEYDOWNWM_KEYUP窗口消息。除非存在活动的Windows消息队列,否则控制台应用程序不会收到这些消息。如果要在控制台应用程序中查看和处理这些消息,请创建一个窗口并为其提供键盘焦点。确保在拥有该窗口的主题中使用pumpingGetMessage WinAPI调用发送消息DispatchMessage

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