【问题标题】:Hook into Windows sizing events: hook is not called挂钩 Windows 大小调整事件:未调用挂钩
【发布时间】:2013-11-01 18:47:38
【问题描述】:

我正在尝试加入 Windows 的大小调整事件。我写了以下钩子:

__declspec(dllexport)
LRESULT CALLBACK HookProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
    MSG *msg = (MSG *)lParam;

    wchar_t text[1014];
    GetWindowText(msg->hwnd, text, 1024);

    if (wcscmp(text, L"Untitled - Notepad") == 0)
    {
        if (nCode == HCBT_MOVESIZE)
        {
            FILE *file;
            fopen_s(&file, "C:\\Users\\Me\\hooklog.txt", "a+");
            fprintf(file, "Move or size.\n");
            fclose(file);
        }
        else
        {
            FILE *file;
            fopen_s(&file, "C:\\Users\\Me\\hooklog.txt", "a+");
            fprintf(file, "Something else.\n");
            fclose(file);
        }
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

我正在尝试使用以下方式安装它:

HHOOK hhk = SetWindowsHookEx(WH_CBT, hookProc, hModule, 0);
DWORD err = GetLastError();

同样的技术适用于其他类型的钩子,但 WH_CBT 不起作用。调用后的所有变量(hookProchModulehhkerr0 em>) 所涉及的值合理且没有错误迹象。在日志文件中没有任何显示。

工作版

我注意到 nCode 的使用取决于钩子的类型,但我完全忘记检查其他参数;正如 Hans 注意到的那样,lParam 并没有为 WH_CBT 指向带有 nCode == HCBT_MOVESIZEMSG;相反,lParam 指向新的 RECT,并且可以从 wParam 检索 HWND

__declspec(dllexport)
LRESULT CALLBACK HookProcedure(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_MOVESIZE)
    {
        wchar_t text[1014];
        GetWindowText((HWND)wParam, text, 1024);

        if (wcscmp(text, L"Untitled - Notepad") == 0)
        {
            RECT *rect = (RECT *)lParam;

            FILE *file;
            fopen_s(&file, "C:\\Users\\Me\\hooklog.txt", "a+");
            fprintf(file, "Move or size (%d, %d, %d, %d) for target window.\n", rect->left, rect->right, rect->top, rect->bottom);
            fclose(file);
        }
        else
        {
            FILE *file;
            fopen_s(&file, "C:\\Users\\Me\\hooklog.txt", "a+");
            fprintf(file, "Move or size for some other window.\n");
            fclose(file);
        }
    }
    else
    {
        FILE *file;
        fopen_s(&file, "C:\\Users\\Me\\hooklog.txt", "a+");
        fprintf(file, "Something else.\n");
        fclose(file);
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

【问题讨论】:

  • 安装一个全局挂钩来监控一个窗口是多余的。使用过滤到拥有您关心的窗口的线程的可访问性挂钩。
  • 这将非常有用,我想知道是否有办法更有选择性,谢谢!只是为了确保我理解,您是在谈论 SetWinEventHookWinEvents 吗?我在文档中看到了这些,但不确定它们是否适合我的情况。
  • @damix911 是的,“过滤到线程的可访问性挂钩”意味着 SetWinEventHook

标签: winapi hook


【解决方案1】:

您认为传递的 lParam 是指向 MSG 的指针的假设是错误的。检查MSDN article 的回调,滚动到底部。您会看到,当 nCode == HCBT_MOVESIZE 时,lParam 是指向 RECT 的指针。

wParam 为您提供窗口句柄。

防御性代码,永远不要忽略 winapi 函数的返回值。

【讨论】:

  • 谢谢,我首先为 WH_GETMESSAGE 编写了一个功能挂钩,当我切换到 WH_CBT 时,我完全没有检查参数语义。
猜你喜欢
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
相关资源
最近更新 更多