首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将钩子添加到键盘(HookProc)

如何将钩子添加到键盘(HookProc)
EN

Stack Overflow用户
提问于 2014-11-21 20:51:20
回答 1查看 3.7K关注 0票数 2

我试着做一个简单的键盘测试,但我的程序不能像预期的那样工作,我也不知道为什么。

在我的程序中,我有一个低级别的键盘挂钩,并附加了一个简单的进程。该过程只是打开/创建一个文件并写入"Hello“,然后关闭。但是,它没有创建文件,可能是因为我的进程不正确,或者因为我的钩子没有正确地建立。

代码:

代码语言:javascript
运行
复制
#include<windows.h>
#include<stdio.h>
#include <iostream>
#include <fstream>

using namespace std;

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam){
    ofstream myfile;
        myfile.open ("[PATH]/example.txt");
        myfile << "Hello world";//((KBDLLHOOKSTRUCT *)lParam)->vkCode
    myfile.close();
    return CallNextHookEx(NULL,code,wParam,lParam);
}

int main(void){
    HINSTANCE hInst = NULL;
    HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, hInst, 0);
    printf("HHOOK is not null: %s\n", (hHook != NULL) ? "True" : "False");
    char q;
    for (cout << "q to quit\n"; q != 'q'; cin >> q);

    printf("Successfully unhooked: %s", UnhookWindowsHookEx(hHook) ? "True" : "False");
}

解决方案I需要向主函数添加一个消息循环:

代码语言:javascript
运行
复制
LPMSG Msg;
while(GetMessage(Msg, NULL, 0, 0) > 0)
{
    TranslateMessage(Msg);
    DispatchMessage(Msg);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-21 21:16:55

这是两种钩子:

全球钩子

全局钩子过程应该放在一个单独的dll中,然后在您的主进程中加载挂钩DLL,并设置挂钩过程。

全局钩子监视与调用线程相同桌面上所有线程的消息。特定于线程的钩子只监视单个线程的消息.可以在与调用线程相同的桌面上的任何应用程序的上下文中调用全局钩子过程,因此该过程必须位于单独的DLL模块中。

也就是说:KeyboardProc进入一个单独的DLL (例如myhookdll.dll)。

在您的过程中,您会做这样的事情:

代码语言:javascript
运行
复制
HOOKPROC hkprc;
static HINSTANCE hhookDLL ; 
static HHOOK hhook ; 

hhookDLL = LoadLibrary(TEXT("c:\\...\\myhookdll.dll")); 
hkprc = (HOOKPROC)GetProcAddress(hhookDLL, "KeyboardProc"); 

hhook = SetWindowsHookEx( 
                    WH_KEYBOARD,
                    hkprc,
                    hhookDLL,
                    0); 

这里有一个很好的参考资料:http://msdn.microsoft.com/en-us/library/windows/desktop/ms644960(v=vs.85).aspx

线程级钩子

关于线程级别的这个特定的“WH_KEYBOARD_LL”,它不需要一个单独的DLL。

只在关联线程的上下文中调用特定于线程的钩子过程.如果应用程序为自己的线程安装钩子过程,则钩子过程可以位于与应用程序其余代码相同的模块中,也可以位于DLL中。如果应用程序为不同应用程序的线程安装钩子过程,则该过程必须位于DLL中。有关信息,请参见动态链接库。

但是线程级钩子需要一个消息泵:

这个钩子是在安装它的线程上下文中调用的。调用是通过向安装钩子的线程发送消息进行的。因此,安装钩子的线程必须有一个消息循环。

这里有一个基本消息循环:

代码语言:javascript
运行
复制
   while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
   {
     if(bRet == -1)
     {
         // Handle Error
     }
     else
     {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
     }
   }
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27070135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档