c - 低级鼠标钩子(Hook)获取光标位置和 hwnd

标签 c winapi mouse-hook

我有一个简单的问题。我使用来自 MSDN 创建窗口站点的窗口 api 创建了一个标准窗口。我希望程序做的是当我按下键盘上的某个键时更改鼠标光标所在的窗口标题。为此,我安装了一个低级鼠标 Hook ,如下所示:

LRESULT CALLBACK LowLevelMouseProc(__in  int nCode, __in  WPARAM wParam, __in  LPARAM lParam) {
    MSLLHOOKSTRUCT* p = (MSLLHOOKSTRUCT*)lParam;
    HWND hiWnd = WindowFromPoint(p->pt); //Get a handle to the top-most window
    ScreenToClient(hiWnd, &p->pt); //Converts the cursor position from screen to the specified window
    char buf[33];

    switch (wParam) {

    case WM_MOUSEMOVE:
        snprintf(buf, sizeof(buf) - 1, "X:%ld, Y:%ld", p->pt.x, p->pt.y); //Put the cursor coordinates into a char buffer
        SendMessage(hiWnd, WM_SETTEXT, 0, (LPARAM)buf); //Send a message to the other window to change the title
        break;
    }
    return CallNextHookEx(0, nCode, wParam, lParam);
}

调用鼠标 Hook 后,只有我的程序会更改文本。而且,文字是一堆汉字,而且不是一两个,而是一堆像这样的:

藡覶 跾 瑍痸碚 齫儽戃 羭聧蔩, 圪妀 跾 鶀嚵巆 堔埧娾 爂犤繵 摿斠榱 軥軱逴 潫 徖梜, 薍薝 

我是否必须搞乱前景窗口并获取背景窗口?或者当前鼠标位置所在的窗口?我认为

ScreenToClient(hiWnd, &p->pt)

感谢各位的帮助!

最佳答案

What I want the program to do is change the title of the window the mouse cursor is at when i press a key on the keyboard

那为什么要使用鼠标钩子(Hook)而不是键盘钩子(Hook)呢?在键盘 Hook 中,您可以使用 GetCursorPos()获取当前鼠标屏幕位置。

至于您的实际问题,您没有检查以确保 WindowFromPoint()甚至根本找不到一个窗口,您没有将正确对齐的内存指针传递给 WM_SETTEXT ,并且您没有考虑目标窗口是 Ansi 还是 Unicode。

尝试更多类似这样的事情:

键盘 Hook :

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if ((nCode == HC_ACTION) && (wParam == WM_KEYUP))
    {
        KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
        if (p->vkCode == ...) // whatever key you are looking for
        {
            POINT pt;
            GetCursorPos(&pt);

            HWND hiWnd = WindowFromPoint(pt);
            if (hiWnd)
            {
                ScreenToClient(hiWnd, &pt);

                if (IsWindowUnicode(hiWnd))
                {
                    LPWSTR buf = (LPWSTR) GlobalAlloc(GMEM_FIXED, 33 * sizeof(WCHAR));
                    if (buf)
                    {
                        snwprintf(buf, 33, L"X:%ld, Y:%ld", pt.x, pt.y);
                        SendMessageW(hiWnd, WM_SETTEXT, 0, (LPARAM)buf);
                        GlobalFree(buf);
                    }
                }
                else
                {
                    LPSTR buf = (LPSTR) GlobalAlloc(GMEM_FIXED, 33);
                    if (buf)
                    {
                        snprintf(buf, 33, "X:%ld, Y:%ld", pt.x, pt.y);
                        SendMessageA(hiWnd, WM_SETTEXT, 0, (LPARAM)buf);
                        GlobalFree(buf);
                    }
                }
            }
        }
    }

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

鼠标 Hook :

LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if ((nCode == HC_ACTION) && (wParam == WM_MOUSEMOVE))
    {
        MSLLHOOKSTRUCT* p = (MSLLHOOKSTRUCT*)lParam;

        HWND hiWnd = WindowFromPoint(p->pt);
        if (hiWnd)
        {
            POINT pt = p->pt;
            ScreenToClient(hiWnd, &pt);

            if (IsWindowUnicode(hiWnd))
            {
                LPWSTR buf = (LPWSTR) GlobalAlloc(GMEM_FIXED, 33 * sizeof(WCHAR));
                if (buf)
                {
                    snwprintf(buf, 33, L"X:%ld, Y:%ld", pt.x, pt.y);
                    SendMessageW(hiWnd, WM_SETTEXT, 0, (LPARAM)buf);
                    GlobalFree(buf);
                }
            }
            else
            {
                LPSTR buf = (LPSTR) GlobalAlloc(GMEM_FIXED, 33);
                if (buf)
                {
                    snprintf(buf, 33, "X:%ld, Y:%ld", pt.x, pt.y);
                    SendMessageA(hiWnd, WM_SETTEXT, 0, (LPARAM)buf);
                    GlobalFree(buf);
                }
            }
        }
    }

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

关于c - 低级鼠标钩子(Hook)获取光标位置和 hwnd,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32130361/

相关文章:

c - 我不明白为什么 HIWORD 宏使用 &0xFFFF 掩码?

c - 在 C 中编码 HTML 字符

c - 嵌套的 printf 语句工作

c - 二进制数表示

c++ - 如何在 DirectWrite 中使用默认 UI 字体绘制文本?

c++ - 在 Mouse Proc C++ Win32 中重复消息

c - return 语句实际上返回值还是将其存储在函数中?

c++ - 如何将一个窗口保持在另一个应用程序窗口的前面

c++ - WinApi:消息循环可以被异步过程调用中断吗?

c++ - 鼠标钩子(Hook)代码内部的调用方法导致访问冲突