cwinapimouse-hook

Low level mouse hook getting cursor position and hwnd


I have a quick question. I created a standard window with the window api from the MSDN creating a window site. 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. To do so i've installed a low level mouse hook like so:

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);
}

Upon calling the mouse hook, Only my program changes text. Also, the text is a bunch of Chinese Characters, And not one or two, but a bunch like so:

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

Do I have to mess around with the foreground window and instead get the background window? Or window where current mouse pos is at? I would assume that

ScreenToClient(hiWnd, &p->pt)

Thanks for the help guys!


Solution

  • 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

    Then why are you using a mouse hook instead of a keyboard hook? In a keyboard hook, you can use GetCursorPos() to get the current mouse screen position.

    As for your actual problem, you are not checking to make sure WindowFromPoint() is even finding a window at all, you are not passing a properly-aligned memory pointer to WM_SETTEXT, and you are not taking into account whether the destination window is Ansi or Unicode.

    Try something more like this instead:

    Keyboard 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);
    }
    

    Mouse 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);
    }