[WinAPI] 使用 CBT 钩子来修改系统原生 MessageBox 按钮的文本

陪她去流浪 桃子 2016年12月02日 编辑 阅读次数:2609

以下示例通过安装一个 CBT(Computer-based Training)钩子来监听窗口激活事件,并达到修改 Windows 原生 MessageBox 函数按钮文本的功能。例子比较简单,就不多作详细介绍啦。

#include <cstdio>
#include <windows.h>
#include <locale.h>

static HHOOK g_hCbtHook;

static LRESULT __stdcall CbtHook(int code, WPARAM wParam, LPARAM lParam)
{
    if(code == HCBT_ACTIVATE) {
        HWND hWnd = HWND(wParam);
        wchar_t tt[128];
        if(::GetWindowText(hWnd, tt, _countof(tt)) && ::wcscmp(tt, L"测试测试") == 0) {
            ::SetDlgItemText(hWnd, IDABORT, L"不取消");
            ::SetDlgItemText(hWnd, IDRETRY, L"不重试");
            ::SetDlgItemText(hWnd, IDIGNORE, L"不忽略");
            ::UnhookWindowsHookEx(g_hCbtHook);
            g_hCbtHook = nullptr;
        }
    }
    return ::CallNextHookEx(g_hCbtHook, code, wParam, lParam);
}

int main()
{
    setlocale(LC_ALL, "chs");

    g_hCbtHook = ::SetWindowsHookEx(WH_CBT, CbtHook, ::GetModuleHandle(nullptr), ::GetCurrentThreadId());

    int r = ::MessageBox(nullptr, L"有没有发现 MessageBox 的按钮文本改变了?点一个试试吧。", L"测试测试", MB_ABORTRETRYIGNORE | MB_ICONINFORMATION);

    wprintf(L"你选择了:%s\n", r == IDABORT ? L"取消" : r==IDRETRY ? L"重试" : L"忽略");

    return r;
}

标签:WinAPI · hook