Search code examples
c++windowscursordwm

HCURSOR from another window, possible?


I'm looking for draw HCURSOR in my window. The cursor has to be the real cursor from another window (HWND).

Here is my code:

GetCursorPos(&pos);
ScreenToClient(hwnd, &pos);
DrawIcon(hdcMemDC, pos.x, pos.y,GetCursor());

It draw a cursor on my window, but it's not the "real" Windows cursor. Example, when on another window i got a hand mouse icon, mine doesn't change.

So i would like to know if it's possible to handle the "real" cursor from a specified window (HWND) and draw it. Something like GetCursorOf(hwnd, &myCursorInfo) would be cool.


Solution

  • This code will get the cursor of any window. It will then create a thread and that thread will constantly draw the cursor onto our window.

    #if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
    #elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
    #endif
    
    #include <tchar.h>
    #include <windows.h>
    
    DWORD WINAPI BltThreadProc(void *lpParam)
    {
        while(true)
        {
            if (!IsIconic((HWND)lpParam)) //if our window isn't minimised, then we get the cursor and draw it.. Makes no sense drawing on a minimised window.
            {
                CURSORINFO Info = {0};
                Info.cbSize = sizeof(Info);
                GetCursorInfo(&Info);
    
                HDC hDC = GetDC((HWND)lpParam);
                DrawIconEx(hDC, 0, 0, Info.hCursor, 0, 0, 0, (HBRUSH)GetStockObject(COLOR_BACKGROUND), DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
                ReleaseDC((HWND)lpParam, hDC);
            }
    
            Sleep(1);
        }
        return 0;
    }
    
    LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_CREATE:
            {
                CreateThread(NULL, 0, BltThreadProc, hwnd, 0, 0);
            }
            break;
    
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
    
            default:
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow)
    {
        HWND hwnd;
        MSG messages;
        WNDCLASSEX wincl;
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = _T("CLS");
        wincl.lpfnWndProc = WindowProcedure;
        wincl.style = CS_DBLCLKS;
        wincl.cbSize = sizeof(WNDCLASSEX);
        wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;
        wincl.cbClsExtra = 0;
        wincl.cbWndExtra = 0;
        wincl.hbrBackground = (HBRUSH)GetStockObject(COLOR_BACKGROUND);
    
        if (!RegisterClassEx (&wincl))
            return 0;
    
        hwnd = CreateWindowEx(0, _T("CLS"), _T("Title"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
        ShowWindow(hwnd, nCmdShow);
        while (GetMessage(&messages, NULL, 0, 0))
        {
            TranslateMessage(&messages);
            DispatchMessage(&messages);
        }
        return messages.wParam;
    }