ShowCursor(FALSE) does not work

2019-03-17 01:52发布

问题:

I know this may sound to be a duplicate question but trust me it's not.

I have referred this question, but was not of much help as I am trying with a console application and the answerer himself tells he does not know the reason why ShowCursor(FALSE) does not work for console applications.

This thread did not help me either.

Here are the things I tried:

Using ShowCursor():

while(ShowCursor(false)>=0); //did not work

I first suspected that it was because of this statement in the msdn : When Windows starts up, it checks if you have a mouse. If so, then the cursor show count is initialized to zero; otherwise, it is initialized to negative one I thought maybe in the latest windows, it doesn't recognize the connected mouse or the trackpad as an installed mouse and maybe that's why it didn't work. The following code shows it is not the case:

void UsingShowCursor()
{
    CURSORINFO info;
    info.cbSize = sizeof(CURSORINFO);
    cout << ShowCursor(FALSE);
    cout << ShowCursor(FALSE);
    cout << ShowCursor(FALSE);
    GetCursorInfo( &info ); //info.flags is CURSOR_SHOWING
}

Because I get -1, -2, -3. That means the initial show cursor count is obviously 0 and it does identify the installed mouse.

And another thing to note is that the GetCursorInfo() also tells that the cursor is showing.

Using SetCursor()

void UsingSetCursor()
{
    HCURSOR prev = SetCursor(NULL);
    int i = 0;
    while(i++<10)
    {
        cout<<i<<endl;
        Sleep(1000);
    }
    if( SetCursor(prev) == NULL ) //check if the previos cursor was NULL
        cout<<"cursor was hidden and shown after 10 secs\n";
}

Doesn't work either. This also did not work:

SetCursor(LoadCursor(NULL, NULL));

Edit:

Using LoadImage

Did not work either.

void UsingLoadImage()
{
    // Save a copy of the default cursor
    HANDLE arrowHandle = LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED);
    HCURSOR hcArrow = CopyCursor(arrowHandle);

    HCURSOR noCursorHandle = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR,1,1,LR_SHARED); //a single pixel thick cursor so that it wont be visible

    HCURSOR noCursor = CopyCursor(noCursorHandle);
    SetSystemCursor(noCursor, OCR_NORMAL);
    int i =0 ;
    while(i++<10)
    {
        cout<<i<<endl;
        Sleep(1000);
    }
    //revert to previous cursor
    SetSystemCursor(hcArrow, OCR_NORMAL);
    DestroyCursor(hcArrow);
}

What can be the mistake? How can we hide the mouse for a console application?

回答1:

You can use LoadImage() to achieve what you want. Here is the modified working version of the function UsingLoadImage() you quoted in the question. You have to include a cursor resource file to your visual studio project. Download the cursor from here or create your own.

Resource Files->Add->Existng Item and browse to the nocursor.cur file.

void UsingLoadImage()
{
    // Save a copy of the default cursor
    HANDLE arrowHandle = LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED);
    HCURSOR hcArrow = CopyCursor(arrowHandle);

    // Set the cursor to a transparent one to emulate no cursor
    HANDLE noCursorHandle = LoadImage(GetModuleHandle(NULL), L"nocursor.cur", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE); //worked
    //HANDLE noCursorHandle = LoadCursorFromFile(L"nocursor.cur"); //this also worked

    HCURSOR noCursor = CopyCursor(noCursorHandle);
    SetSystemCursor(noCursor, OCR_NORMAL);
    int i =0 ;
    while(i++<10)
    {
        cout<<i<<endl;
        Sleep(1000);
    }
    SetSystemCursor(hcArrow, OCR_NORMAL);
    DestroyCursor(hcArrow);
}

This would replace the normal arrow cursor with the transparent one. If you want to hide all the other cursor like the text, loading, hand cursors etc you have to hide them individually. If you don't want that to be the case, then you should opt out of the console application as many commenters have pointed out.

Hope this helps.