Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Impossible to hide mouse cursor using ShowCursor(FALSE) immediately after application start

Tags:

c++

winapi

I need to hide mouse cursor immediately after application start. I am using ShowCursor(FALSE) for this. But often after ShowCursor(FALSE) the cursor remains on the screen until mouse move. I and other people reproduced this on different PCs with Windows from XP to 10. In order to reproduce this, just launch the application from Windows Explorer by double clicking the executable and ABSOLUTELY DON'T move the mouse while double clicking and after that. If the application is launched in any other way, the cursor is hidden, as expected. It seems that cursor, when it stays on the screen, belongs to Windows Explorer, sometimes in addition to cursor on the screen remains Explorer tooltip.

Code that does not always work:

#include <Windows.h>

LRESULT __stdcall WndProcFull(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg==WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pszCmdLine, int iCmdShow)
{
    MSG msg;
    HWND hWnd;
    PCWSTR pszFullName=L"FullWindow";
    WNDCLASSEX wc={sizeof (WNDCLASSEX), 0, WndProcFull, 0, 0, hInstance, 0, LoadCursor(0, IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 0, pszFullName, 0};
    RegisterClassEx(&wc);
    hWnd=CreateWindow(pszFullName, L"HideCursor", WS_POPUP | WS_MAXIMIZE | WS_VISIBLE, 0, 0, 0, 0, 0, 0, hInstance, 0);
    UpdateWindow(hWnd);
    ShowCursor(FALSE);
    while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
    return 0;
}

The source code is compiled in any VS.

The only thing that currently helps is to set the timer and, after timer interval expires, programmatically move mouse cursor, then it hides. But I would prefer to find more suitable and stable solution.

Code with workaround:

#include <Windows.h>

#define HIDECURSOR_TIMER_ID 1

LRESULT __stdcall WndProcFull(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_TIMER:
        POINT pt;
        GetCursorPos(&pt);
        SetCursorPos(pt.x+1, pt.y);
        KillTimer(hWnd, HIDECURSOR_TIMER_ID);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pszCmdLine, int iCmdShow)
{
    MSG msg;
    HWND hWnd;
    PCWSTR pszFullName=L"FullWindow";
    WNDCLASSEX wc={sizeof (WNDCLASSEX), 0, WndProcFull, 0, 0, hInstance, 0, LoadCursor(0, IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 0, pszFullName, 0};
    RegisterClassEx(&wc);
    hWnd=CreateWindow(pszFullName, L"HideCursor", WS_POPUP | WS_MAXIMIZE | WS_VISIBLE, 0, 0, 0, 0, 0, 0, hInstance, 0);
    UpdateWindow(hWnd);
    ShowCursor(FALSE);
    SetTimer(hWnd, HIDECURSOR_TIMER_ID, 200, 0);
    while (GetMessage(&msg, 0, 0, 0)) DispatchMessage(&msg);
    return 0;
}

200 ms is the minimum timeout value at which the cursor stable disappears.

like image 811
Mogod Avatar asked Mar 07 '26 21:03

Mogod


1 Answers

According the documentation:

If bShow is TRUE, the display count is incremented by one. If bShow is FALSE, the display count is decremented by one.

So to hide the cursor, you want something like this:

while(ShowCursor(FALSE) >= 0);
like image 111
ProXicT Avatar answered Mar 09 '26 10:03

ProXicT



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!