易语言教程_易语言源码_易语言视频教程_易语言论坛

 找回密码
 点击注册

Vip新手入门区
新手学习指南  学员作品展示 Vip课程总纲  Vip绝密课程系列

Vip相关下载区
Vip模块下载   Vip模块绑定   Vip模块例子 魔鬼插件下载  魔鬼插件例子  教程工具下载

Vip论坛服务区
教程问题提问区   模块问题提问区 技术交流区   魔鬼插件建议   忘记密码找回

VIP会员办理QQ: 8643245   
【请先加好友,然后到好友列表双击联系客服,办理VIP会员。】
【基础篇】易语言辅助入门基础教程
VIP模块办理QQ: 7189694 办理正版魔鬼作坊VIP模块 【基础篇】OD与CE入门基础教程
办理【终身VIP会员】“秒杀价” 仅需 RMB278.00元… 【基础篇】零基础绝密汇编语言入门课程 (共26课已完成)…
办理VIP详情…猛击这里查看详情 【基础篇】VIP辅助入门基础教程-新手必学 已发布10课 ……
VIP教程免费试看章节…猛击下载 【第1款】制作“辅助挂”教程目录查看(共107+16_x64下更新课已完成)…
亲爱的VIP学员,请到此写下你学习的感受与发布作品截图… 【第2款】制作“任务挂”教程目录查看(共77+1_x64下更新课已完成)…
卍解吧!不用bp send类封包断点找CALL的各种通杀思路 【第3款】驱动过保护技术课程(共38课已完成)…
【绝密教程】VIP绝密教程系列---注意:随时会更新! 【第4款】VIP邪恶二叉树辅助课程 (共31+17_x64下更新课已完成)…
【精品第13款】3D射击游戏与页游透视 智辅课程 已完成17课… 【第5款】零基础易语言按键辅助教程 (30课已完成)…
【精品第14款】变态功能辅助是如何炼成的 已完成36课… 【第6款】从零开始学习封包辅助技术教程(20课已完成) …
【精品第15款】DNF商业变态辅助的修炼之路 已完成27课… 【第7款】大杀特杀分析来源与CALL吸血鬼课程 (56课已完成)
【精品第16款】中控台多线程多开自动化商业辅助课程 已完成66课… 【第8款】完全零基础网页辅助课程(40课已完成)
【全新精品第17款】检测原理与过游戏内存检测技术课程 已发布9课… 【第9款】自动登录与操控LUA技术课程 (共46+8_x64下更新课已完成)…
【全新精品第18款】手游全自动化任务脚本辅助课程 已发布25课…… 【第10款】网页辅助封包脱机进阶课程 已完成30课…
【全新精品第19款】D3D方框骨骼透视与自瞄辅助课程进阶篇 已发布34课…… 【第11款】VC++ Lua脚本辅助课程 已完成112课…
【全新精品第20款】 X64模拟器吃鸡游戏方框透视自瞄辅助课程 发布中... 【第12款】网游脱机封包智辅课程 已完成35课…
查看: 2013|回复: 0

Windows API hook 钩子监听

[复制链接]

5

主题

4

回帖

542

积分

编程入门

Rank: 1

魔鬼币
542
发表于 2017-5-10 15:12:10 | 显示全部楼层 |阅读模式
如何创建一个窗口

另外一个再录的 Windows SDK教程 里面有讲到快捷创建窗口的方式,不过这样的话要分好几个文件,感觉有点混所以这里就用原始的方式创建一个窗口。

那么,为什么讲到 hook(钩子)的时候要去创建窗口呢?其实这个问题说起来也不复杂,简单点说,按博主这样写不用写DLL也不用资源文件,实际上是把问题简化了一些。通常 hook 是用来监听自己窗口上的键盘和鼠标输入的,监听全局的通常是设置一些全局的热键(如QQ的 Ctrl+Alt+Z 调出QQ窗口),这些常见的功能也都是要依托窗口才能存在。所以我们先来简单说下手动建立一个窗口的流程。

手动创建窗口的流程

设置注册窗口结构体
使用【窗口结构体】注册窗口
创建窗口
显示窗口
窗口过程处理
消息循环
实际代码

这里不会详细讲这个,有感兴趣的可以去追博主的 SDK教程 或者去搜 杨中科的《C语言也能干大事》

#include <windows.h>

// 5. 窗口过程处理
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;  // 更多详细都可以去百度的 http://baike.baidu.com/view/1750396.htm
    HWND hwnd;
    MSG Msg;
    char text[30];

    const char szClassName[] = "myWindowClass";

    // 1. 设置注册窗口结构体
    wc.cbSize        = sizeof(WNDCLASSEX);              // 注册窗口结构体的大小
    wc.style         = 0;                               // 窗口的样式
    wc.lpfnWndProc   = WndProc;                         // 指向窗口处理过程的函数指针
    wc.cbClsExtra    = 0;                               // 指定紧跟在窗口类结构后的附加字节数
    wc.cbWndExtra    = 0;                               // 指定紧跟在窗口事例后的附加字节数
    wc.hInstance     = hInstance;                       // 本模块的实例句柄
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);     // 光标的句柄
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);        // 背景画刷的句柄
    wc.lpszMenuName  = NULL;                            // 指向菜单的指针
    wc.lpszClassName = szClassName;                     // 指向类名称的指针
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标

    // 2. 使用【窗口结构体】注册窗口
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 3. 创建窗口
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,       // 窗口的扩展风格
        szClassName,            // 指向注册类名的指针
        TEXT("窗口标题"),       // 指向窗口名称的指针
        WS_OVERLAPPEDWINDOW,    // 窗口风格
        CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高
        NULL,                   // 父窗口的句柄
        NULL,                   // 菜单的句柄
        hInstance,              // 应用程序实例的句柄
        NULL                    // 指向窗口的创建数据
        );

    if(hwnd == NULL)
    {
        MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 4. 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 6. 消息循环
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
因为是比较死的形式,以上代码大家混个脸熟,大概知道各个部分的作用就行了,博主也从来没有专门记过。

安装钩子 (Install hook)

简介

窗口建好了之后就要开始转到我们的正题了,首先我们需要明确的是,这个钩子(hook)到底是什么,那么博主这里也不做太书面的解释留下几个链接:

百度百科:hook
MSDN: Hooks
博客园: Beginning HOOK

各位可以多多参考,那么博主说下自己的理解:

windows 系统中的【hook 机制】,就类似于一个【消息过滤网】,如果我们向操作系统申请并成功对某个窗口安装了一个【hook】指定了【回调函数】,那么这个【回调函数】也就相当于我们人为对这个窗口添加了一个【消息过滤网】。此时当 windows 操作系统要对这个窗口发送任何消息的时候(例如按键、鼠标点击等消息)操作系统会先调用我们在【消息过滤网】中设置的【回调函数】去接受、处理、过滤等等,当然如果你在【回调函数】中拿到了数据却没有继续传递给窗口的话,就相当于拦截了这些消息。

打个简单的比方,如果你在系统全局安装了一个【键盘消息】的钩子,并且在其指定的【回调函数】中没有把这个键盘消息继续传递给系统上的窗口,那么你的所有【键盘消息】都被这个【hook】也就我们挂在这个【消息过滤网】上的【回调函数】给拦截了,这也意味着你的键盘会失灵。

SetWindowsHookEx 函数

那么 SetWindowsHookEx 函数就是我们用来在 windows 操作系统上安装钩子的函数,我们简单来看一下这个函数的原型:

HHOOK WINAPI SetWindowsHookEx(
  _In_  int idHook,         // 安装的钩子类型
  _In_  HOOKPROC lpfn,      // 处理消息的回调函数
  _In_  HINSTANCE hMod,     // 当前实例句柄
  _In_  DWORD dwThreadId    // 线程ID
);
钩子类型有很多种,本页中留的大部分链接上都有讲到这里就不废话了,关于 hMod(当前实例句柄)和 dwThreadId(线程ID)之间的一些小九九博主这里也不多说,各位可以到下方的链接中去看看,博主这里就举一个容易实现的实例。

百度百科: SetWindowsHookEx
MSDN: SetWindowsHookEx

设置监听【键盘】消息

PKBDLLHOOKSTRUCT 是 WH_KEYBOARD_LL 方式中用来接收消息的结构体,大家可以到 WindUser.h 中多逛逛。

我们监听键盘的时候主要用的是该结构体的 vkCode(value code)和 scanCode 这两个字段。即键盘的【值码】和【扫描码】那么为什么判断一个按键要分成两个部分呢,原因是因为世界上的键盘有很多种,不同国家、不同厂商生产的键盘甚,至同一个键盘上【同样的键】不同的地方按下都可能会有差异。vkCode 是常见的一般都是公用的键盘值,而 scanCode 扫描码则是用来辅助区分的一个一个参数,例如同样是按下 ctrl 键,他们的 vkCode 是相同的但是 scanCode 却不同。

#include <windows.h>

HHOOK myhook;   // 保存当前钩子句柄

/****************************************************************
  WH_KEYBOARD hook procedure
  鍵盤钩子处理过程
****************************************************************/
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{   
    char text[50], data[20];    // 输出字符串
    const char *info = NULL;    // 类型字符指针
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam; // 获取按键消息
    HDC hdc;    // 画图设备句柄

    // 判断是否收到键盘消息
    if (nCode >= 0)
    {
        // 判断消息类型
        if      (wParam == WM_KEYDOWN)      info = "普通按鍵抬起";
        else if (wParam == WM_KEYUP)        info = "普通按鍵按下";
        else if (wParam == WM_SYSKEYDOWN)   info = "系統按鍵抬起";
        else if (wParam == WM_SYSKEYUP)     info = "系統按鍵按下";

        // 初始化数组
        ZeroMemory(text, sizeof(text));
        ZeroMemory(data, sizeof(data));
        // 拼装字符串
        wsprintf(text, "%s - 键盘码 [%04d], 扫描码 [%04d]  ", info, p->vkCode, p->scanCode);
        wsprintf(data, "按鍵目测为: %c  ", p->vkCode);

        // 此处调用 GDI 画图函数来将截取到的内容画在窗口上
        hdc = GetDC(画图的窗口句柄);       // 获取要画图的设备句柄
        TextOut(hdc, 10, 10, text, strlen(text));   // 在窗口上画文字
        TextOut(hdc, 10, 30, data, strlen(data));   // 参数分别是 目标设备, x坐标, y坐标, 字符串内容, 字符串长度
        ReleaseDC(画图的窗口句柄, hdc);        // 释放设备句柄
    }

    // 将消息继续往下传递
    return CallNextHookEx(myhook, nCode, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    /* 其他代码 */

    // 设置键盘全局监听
    myhook = SetWindowsHookEx(
        WH_KEYBOARD_LL, // 监听类型【键盘消息】
        KeyboardProc,   // 处理函数
        hInstance,      // 当前实例句柄
        0               // 监听线程ID(NULL为全局监听)
    );

    // 判断是否成功
    if(myhook == NULL)
    {      
        wsprintf(text, "键盘监听失败!error : %d \n", GetLastError());
        MessageBox(hwnd, text, TEXT("错误"), MB_OK);
    }

    /* 其他代码 */
}
注:其中在输出按键的时候,直接用 %c 输出了 p->vkCode 部分,这个实际上不是很准确。

顺便提一句,各位也不要用这个功能去做什么坏事,比如去监听QQ窗口的键盘消息然后偷到密码盗别人号之类的, 博主已经试过了 这个本身有带防护的,用户在输密码的时候,会有干扰的键盘消息也一起冒出来所以没那么简单能到到别人输的密码。至于写个程序去拦截别人的键盘还有鼠标消息让别人的电脑不能用的情况,这个确实很容易做到,而且貌似杀毒软件都没办法防,只能自己在自己的电脑上留个后门,怎么写后门?后面的网络编程会说这个。

键盘监听完整代码:

#include <windows.h>

HWND hgWnd;
HHOOK myhook;

/****************************************************************
  WH_KEYBOARD hook procedure
  鍵盤钩子处理过程
****************************************************************/
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{   
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
    const char *info = NULL;
    char text[50], data[20];

    PAINTSTRUCT ps;
    HDC hdc;

    if (nCode >= 0)
    {
        if      (wParam == WM_KEYDOWN)      info = "普通按鍵抬起";
        else if (wParam == WM_KEYUP)        info = "普通按鍵按下";
        else if (wParam == WM_SYSKEYDOWN)   info = "系統按鍵抬起";
        else if (wParam == WM_SYSKEYUP)     info = "系統按鍵按下";

        ZeroMemory(text, sizeof(text));
        ZeroMemory(data, sizeof(data));
        wsprintf(text, "%s - 键盘码 [%04d], 扫描码 [%04d]  ", info, p->vkCode, p->scanCode);
        wsprintf(data, "按鍵目測為: %c  ", p->vkCode);

        hdc = GetDC(hgWnd);         
        TextOut(hdc, 10, 10, text, strlen(text));
        TextOut(hdc, 10, 30, data, strlen(data));
        ReleaseDC(hgWnd,hdc);
    }
     
    return CallNextHookEx(myhook, nCode, wParam, lParam);
}

// 5. 窗口过程处理
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    hgWnd = hwnd;

    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;  // http://baike.baidu.com/view/1750396.htm
    HWND hwnd;
    MSG Msg;
    char text[30];

    const char szClassName[] = "myWindowClass";

    // 1. 设置注册窗口结构体
    wc.cbSize        = sizeof(WNDCLASSEX);              // 注册窗口结构体的大小
    wc.style         = 0;                               // 窗口的样式
    wc.lpfnWndProc   = WndProc;                         // 指向窗口处理过程的函数指针
    wc.cbClsExtra    = 0;                               // 指定紧跟在窗口类结构后的附加字节数
    wc.cbWndExtra    = 0;                               // 指定紧跟在窗口事例后的附加字节数
    wc.hInstance     = hInstance;                       // 本模块的实例句柄
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);     // 光标的句柄
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);        // 背景画刷的句柄
    wc.lpszMenuName  = NULL;                            // 指向菜单的指针
    wc.lpszClassName = szClassName;                     // 指向类名称的指针
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标

    // 2. 使用【窗口结构体】注册窗口
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 3. 创建窗口
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,       // 窗口的扩展风格
        szClassName,            // 指向注册类名的指针
        TEXT("窗口标题"),       // 指向窗口名称的指针
        WS_OVERLAPPEDWINDOW,    // 窗口风格
        CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高
        NULL,                   // 父窗口的句柄
        NULL,                   // 菜单的句柄
        hInstance,              // 应用程序实例的句柄
        NULL                    // 指向窗口的创建数据
        );

    if(hwnd == NULL)
    {
        MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 4. 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 设置键盘全局监听
    myhook = SetWindowsHookEx(
        WH_KEYBOARD_LL, // 监听类型【键盘】
        KeyboardProc,   // 处理函数
        hInstance,      // 当前实例句柄
        0               // 监听窗口句柄(NULL为全局监听)
    );

    if(myhook == NULL)
    {      
        wsprintf(text, "键盘监听失败!error : %d \n", GetLastError());
        MessageBox(hwnd, text, TEXT("错误"), MB_OK);
    }


    // 5. 消息循环
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
运行截图

键盘监听

设置监听【鼠标】消息

与键盘监听类似,各位直接看代码:

#include <windows.h>

HWND hgWnd;
HHOOK myhook;

/****************************************************************
  WH_KEYBOARD hook procedure
  鍵盤钩子处理过程
****************************************************************/
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{   
    LPMSLLHOOKSTRUCT p = (LPMSLLHOOKSTRUCT)lParam;
    POINT   pt = p->pt;
    DWORD   mouseData = p->mouseData;
    const char *info = NULL;
    char text[60], pData[50], mData[50];

    PAINTSTRUCT ps;
    HDC hdc;

    if (nCode >= 0)
    {
        if   (wParam == WM_MOUSEMOVE)       info = "鼠标移动    ";
        else if(wParam == WM_LBUTTONDOWN)   info = "鼠标【左键】按下";
        else if(wParam == WM_LBUTTONUP)     info = "鼠标【左键】抬起";
        else if(wParam == WM_LBUTTONDBLCLK) info = "鼠标【左键】双击";
        else if(wParam == WM_RBUTTONDOWN)   info = "鼠标【右键】按下";
        else if(wParam == WM_RBUTTONUP)     info = "鼠标【右键】抬起";
        else if(wParam == WM_RBUTTONDBLCLK) info = "鼠标【右键】双击";
        else if(wParam == WM_MBUTTONDOWN)   info = "鼠标【滚轮】按下";
        else if(wParam == WM_MBUTTONUP)     info = "鼠标【滚轮】抬起";
        else if(wParam == WM_MBUTTONDBLCLK) info = "鼠标【滚轮】双击";
        else if(wParam == WM_MOUSEWHEEL)    info = "鼠标【滚轮】滚动";

        ZeroMemory(text, sizeof(text));
        ZeroMemory(pData, sizeof(pData));
        ZeroMemory(mData, sizeof(mData));

        wsprintf( text, "当前状态: %10s   ", info);
        wsprintf(pData, "0x%x - X: [%04d], Y: [%04d]  ", wParam, pt.x, pt.y);
        wsprintf(mData, "附带数据: %16u   ", mouseData);

        hdc = GetDC(hgWnd);         
        TextOut(hdc, 10, 10,  text, strlen(text));
        TextOut(hdc, 10, 30, pData, strlen(pData));
        TextOut(hdc, 10, 50, mData, strlen(mData));
        ReleaseDC(hgWnd,hdc);
    }
     
    return CallNextHookEx(myhook, nCode, wParam, lParam);
}

// 5. 窗口过程处理
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{   
    hgWnd = hwnd;

    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;  // http://baike.baidu.com/view/1750396.htm
    HWND hwnd;
    MSG Msg;
    char text[30];

    const char szClassName[] = "myWindowClass";

    // 1. 设置注册窗口结构体
    wc.cbSize        = sizeof(WNDCLASSEX);              // 注册窗口结构体的大小
    wc.style         = 0;                               // 窗口的样式
    wc.lpfnWndProc   = WndProc;                         // 指向窗口处理过程的函数指针
    wc.cbClsExtra    = 0;                               // 指定紧跟在窗口类结构后的附加字节数
    wc.cbWndExtra    = 0;                               // 指定紧跟在窗口事例后的附加字节数
    wc.hInstance     = hInstance;                       // 本模块的实例句柄
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // 图标的句柄
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);     // 光标的句柄
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);        // 背景画刷的句柄
    wc.lpszMenuName  = NULL;                            // 指向菜单的指针
    wc.lpszClassName = szClassName;                     // 指向类名称的指针
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION); // 和窗口类关联的小图标

    // 2. 使用【窗口结构体】注册窗口
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 3. 创建窗口
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,       // 窗口的扩展风格
        szClassName,            // 指向注册类名的指针
        TEXT("窗口标题"),       // 指向窗口名称的指针
        WS_OVERLAPPEDWINDOW,    // 窗口风格
        CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高
        NULL,                   // 父窗口的句柄
        NULL,                   // 菜单的句柄
        hInstance,              // 应用程序实例的句柄
        NULL                    // 指向窗口的创建数据
        );

    if(hwnd == NULL)
    {
        MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // 4. 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 设置鼠标全局监听
    myhook = SetWindowsHookEx(
        WH_MOUSE_LL,    // 监听类型【鼠标】
        MouseProc,  // 处理函数
        hInstance,      // 当前实例句柄
        0               // 监听窗口句柄(NULL为全局监听)
    );

    if(myhook == NULL)
    {      
        wsprintf(text, "键盘监听失败!error : %d \n", GetLastError());
        MessageBox(hwnd, text, TEXT("错误"), MB_OK);
    }

    // 5. 消息循环
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
您需要登录后才可以回帖 登录 | 点击注册

本版积分规则

魔鬼作坊|易语言教程|易语言源码|易语言论坛|易语言视频教程| 论坛导航|免责申明|手机版||网站地图
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表魔鬼作坊立场!
任何人不得以任何方式翻录、盗版或出售本站视频,一经发现我们将追究其相关责任!
我们一直在努力成为最好的编程论坛!
Copyright© 2010-2019 All Right Reserved.
快速回复 返回顶部 返回列表