Win32 钩子回调示例

51 篇文章 0 订阅
29 篇文章 0 订阅

CWinHook.h

#pragma once
#include <windows.h>

class CWinHook
{
public:
    CWinHook();
    ~CWinHook();

    // WH_CALLWNDPROC 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nc-winuser-hookproc
    // 安装一个挂钩过程,用于在系统将消息发送到目标窗口过程之前监视消息
    static LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_CALLWNDPROCRET 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nc-winuser-hookproc
    // 安装一个挂钩过程,该过程在目标窗口过程处理消息后监视消息
    static LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_CBT 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/cbtproc
    // 安装用于接收对 CBT 应用程序有用的通知的挂钩过程
    static LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_DEBUG 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/debugproc
    // 安装可用于调试其他挂钩过程的挂钩过程
    static LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_SHELL 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/debugproc
    // 安装一个挂钩过程,用于接收对 shell 应用程序有用的通知
    static LRESULT CALLBACK ShellProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_FOREGROUNDIDLE 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/foregroundidleproc
    // 安装将在应用程序的前台线程变为空闲状态时调用的挂钩过程。 此挂钩可用于在空闲时间执行低优先级任务
    static LRESULT CALLBACK ForegroundIdleProc(int nCode, DWORD wParam, LONG lParam);

    // WH_GETMESSAGE 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/getmsgproc
    // 每当 GetMessage 或 PeekMessage 函数从应用程序消息队列中检索消息时,系统都调用此函数
    // GetMsgProc 钩子过程可以查看或修改消息
    static LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_KEYBOARD 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/keyboardproc
    // 安装用于监视击键消息的挂钩过程
    static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_KEYBOARD_LL 
    // 仅限全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/keyboardproc
    // 安装用于监视击键消息的挂钩过程
    static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_MOUSE 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/messageproc
    // 安装监视鼠标消息的挂钩过程
    static LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_MOUSE_LL 
    // 仅限全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/messageproc
    // 安装用于监视低级别鼠标输入事件的挂钩过程
    static LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_MSGFILTER 
    // 线程或全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/messageproc
    // 安装用于监视低级别鼠标输入事件的挂钩过程
    static LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam);

    // WH_SYSMSGFILTER 
    // 仅限全局
    // https://learn.microsoft.com/zh-cn/windows/win32/winmsg/sysmsgproc
    // 安装用于监视低级别鼠标输入事件的挂钩过程
    static LRESULT CALLBACK SysMsgProc(int nCode, WPARAM wParam, LPARAM lParam);

private:
    static HHOOK           m_hHook;            //钩子句柄
};

CWinHook.cpp

#include "CWinHook.h"

HHOOK CWinHook::m_hHook;

CWinHook::CWinHook()
{

}

CWinHook::~CWinHook()
{

}

LRESULT CALLBACK CWinHook::CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < 0)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 指定消息是否由当前进程发送
    BOOL fCurThreadSend = wParam;

    // 有关消息的详细信息
    LPCWPSTRUCT pStruct = (LPCWPSTRUCT)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < 0)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 指定消息是否由当前进程发送
    BOOL fCurThreadSend = wParam;

    // 有关消息的详细信息
    LPCWPRETSTRUCT pStruct = (LPCWPRETSTRUCT)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 即将移动窗口或调整其大小
    if(HCBT_MOVESIZE == nCode)
    {
        //指定要移动或调整大小的窗口的句柄
        HWND hWnd = (HWND)wParam;
        LPRECT pRect = (LPRECT)lParam;
    }

    // 窗口即将最小化或最大化
    if(HCBT_MINMAX == nCode)
    {
        //指定要最小化或最大化的窗口的句柄
        HWND hWnd = (HWND)wParam;
        int nCmdShow = lParam;
    }

    // 系统已从 系统消息队列 中检索WM_QUEUESYNC消息,将忽略返回值
    if(HCBT_QS == nCode)
    {

    }

    // 即将创建一个窗口
    if (HCBT_CREATEWND  == nCode)
    {
        //指定新窗口的句柄
        HWND hWndNew = (HWND)wParam;
        LPCBT_CREATEWND pStruct = (LPCBT_CREATEWND)lParam;
    }

    // 一个窗口即将被销毁
    if (HCBT_DESTROYWND == nCode)
    {
        //指定要销毁的窗口的句柄
        HWND hWndDestroy = (HWND)wParam;
    }

    // 系统即将激活窗口
    if (HCBT_ACTIVATE == nCode)
    {
        //指定要激活的窗口的句柄
        HWND hWndActivate = (HWND)wParam;
        LPCBTACTIVATESTRUCT pStruct = (LPCBTACTIVATESTRUCT)lParam;
    }

    // 系统已从系统消息队列中删除鼠标消息,将忽略返回值
    if (HCBT_CLICKSKIPPED == nCode)
    {

    }

    // 系统已从系统消息队列中删除键盘消息,将忽略返回值
    if (HCBT_KEYSKIPPED == nCode)
    {
        WORD wVk = wParam;

    }

    // 即将执行系统命令
    if (HCBT_SYSCOMMAND  == nCode)
    {

    }


    // 窗口即将接收键盘焦点
    if (HCBT_SETFOCUS  == nCode)
    {
        HWND hWndFocusGaining = (HWND)wParam;
        HWND hWndFocusLosing = (HWND)lParam;
    }

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::DebugProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 即将调用的挂钩类型
    int idHook = wParam;

    // 要传递给目标挂钩过程的参数
    LPDEBUGHOOKINFO pStruct = (LPDEBUGHOOKINFO)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 已创建顶级的无所有者窗口。
    if (HSHELL_WINDOWCREATED == nCode)
    {
    }

    // 一个顶级的、无所有者的窗口即将被销毁。
    if (HSHELL_WINDOWDESTROYED == nCode)
    {

    }

    // shell 应激活其main窗口
    if (HSHELL_ACTIVATESHELLWINDOW  == nCode)
    {

    }

    // 激活已更改为其他顶级的无所有者窗口
    if (HSHELL_WINDOWACTIVATED == nCode)
    {
        HWND hWnd = (HWND)wParam;
        BOOL fFullScreen = lParam;
    }

    // 窗口正在最小化或最大化。 系统需要窗口的最小化矩形的坐标
    if (HSHELL_GETMINRECT == nCode)
    {
        HWND hWnd = (HWND)wParam;
        LPRECT pRect = (LPRECT)lParam;
    }

    // 任务栏中窗口的标题已重绘
    if (HSHELL_REDRAW == nCode)
    {
        HWND hWnd = (HWND)wParam;
        BOOL fFlashing = lParam;
    }

    // 用户已选择任务列表
    if (HSHELL_TASKMAN == nCode)
    {

    }

    // 键盘语言已更改或加载了新的键盘布局
    if (HSHELL_LANGUAGE == nCode)
    {
        HWND hWnd = (HWND)wParam;
    }

    // 
    if (HSHELL_SYSMENU == nCode)
    {

    }

    if (HSHELL_ENDTASK == nCode)
    {

    }

    // 辅助功能状态已更改
    if (HSHELL_ACCESSIBILITYSTATE == nCode)
    {

    }

    // 用户完成了输入事件
    if (HSHELL_APPCOMMAND == nCode)
    {
        HWND hWnd = (HWND)wParam;
    }

    // 正在替换顶级窗口
    if (HSHELL_WINDOWREPLACED == nCode)
    {
        HWND hWnd = (HWND)wParam;
        HWND hWndNew = (HWND)lParam;
    }

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::ForegroundIdleProc(int nCode, DWORD wParam, LONG lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }


    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 消息尚未从队列中删除
    if (PM_NOREMOVE == wParam)
    {

    }

    // 消息已从队列中删除
    if (PM_REMOVE == wParam)
    {

    }

    LPMSG pMsg = (LPMSG)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    WORD wVkCode = wParam;

    // https://learn.microsoft.com/zh-cn/windows/win32/inputdev/about-keyboard-input
    typedef struct _KEYSTATUS
    {
        DWORD wRepeat : 16;         //重复计数, 该值是用户按住键后重复击键的次数
        DWORD wScan : 8;            //扫描代码, 此值取决于 OEM
        DWORD fExtended : 1;        //指示键是扩展键,例如功能键还是数字键盘上的键。 如果键是扩展键,则值为 1;否则为 0
        DWORD Reserved : 4;         //保留
        DWORD fContext : 1;         //上下文代码。 如果 Alt 键关闭,则值为 1;否则为 0
        DWORD fPrevious : 1;        //上一个键状态。 如果在发送消息之前键关闭,则值为 1;如果键已打开,则为 0
        DWORD fTransition : 1;      //转换状态。 如果按下键,则值为 0;如果释放键,则值为 1
    }KEYSTATUS;
    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    switch (wParam)
    {
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
        break;
    }

    LPKBDLLHOOKSTRUCT pStruct = (LPKBDLLHOOKSTRUCT)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // wParam 和 lParam 参数包含有关鼠标消息的信息,并且鼠标消息尚未从消息队列中删除
    if (HC_NOREMOVE == nCode)
    {

    }

    LPMOUSEHOOKSTRUCT pStruct = (LPMOUSEHOOKSTRUCT)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    switch (wParam)
    {
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:
    case WM_MOUSEMOVE:
    case WM_MOUSEWHEEL:
        break;
    }

    LPMSLLHOOKSTRUCT pStruct = (LPMSLLHOOKSTRUCT)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::MessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 当动态数据交换管理库 (DDEML) 等待同步事务完成时发生输入事件
    if (MSGF_DDEMGR == nCode)
    {

    }

    // 输入事件发生在消息框或对话框中
    if (MSGF_DIALOGBOX == nCode)
    {

    }

    // 输入事件发生在菜单中
    if (MSGF_MENU == nCode)
    {

    }

    // 输入事件发生在滚动条中
    if (MSGF_SCROLLBAR == nCode)
    {

    }

    UNREFERENCED_PARAMETER(wParam);
    LPMSG pMsg = (LPMSG)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK CWinHook::SysMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode < HC_ACTION)
    {
        return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
    }

    // 输入事件发生在消息框或对话框中
    if (MSGF_DIALOGBOX == nCode)
    {

    }

    // 输入事件发生在菜单中
    if (MSGF_MENU == nCode)
    {

    }

    // 输入事件发生在滚动条中
    if (MSGF_SCROLLBAR == nCode)
    {

    }

    UNREFERENCED_PARAMETER(wParam);
    LPMSG pMsg = (LPMSG)lParam;

    return ::CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值