简体   繁体   中英

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

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.

When the CreateWindow function returns, the window is still not displayed on screen. You should call the ShowCursor function in early window creation time immediately after it has been realized. IMHO the best place is when processing the WM_CREATE message. Code would become:

#include <Windows.h>

LRESULT __stdcall WndProcFull(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg==WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    else if (uMsg == WM_CREATE) {
        ShowCursor(FALSE);
    }
    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;
}

That way you really hide the cursor as soon as the window has been created and realized.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM