Click here to Skip to main content
16,022,352 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
See more:
I use the following lines of code frequently in my win32 application ,but rather than show an hour glass or any other cursor to indicate to the users that they should wait, the cursor simply disappears and re-appears at the end of the time consuming operation as an arrow cursor. How do I correct this?

C++
 HCURSOR hCursor = LoadCursor(hInst, IDC_WAIT);
 HCURSOR hOldCursor = SetCursor(hCursor);

 //Some time consuming operations

SetCursor(hOldCursor);


What I have tried:

I have tried to figure out what was going on again and again.
Posted

There are a few things to bear in mind when changing the cursor. The cursor may only be set in the thread to which the window that processes the messages belongs. When working on a long operation, a thread is usually started to keep the interface usable for the user so that he can continue to press the stop button, for example. Considering this, there is another problem, because the cursor is automatically reset to the normal appearance when it is moved over the window and thus triggers other events.

The solution is a status variable that stores the status of the long operation. The cursor can then be continuously set to the wait cursor in the WM_SETCURSOR message as long as the long operation is running.

Overall, it could look like this:
C++
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static bool g_LongOpRunning = false;

switch (message) {
  case WM_START_LONG_OPERATION: {
      g_LongOpRunning = true;

      // Change cursor to wait cursor
      SetCursor(LoadCursor(NULL, IDC_WAIT));

      // start thread 
      std::thread(ThreadFunction, hWnd).detach();
  }
  break;
  case WM_LONG_OPERATION_COMPLETE:
      g_LongOpRunning = false;
      break;
  case WM_SETCURSOR:
      if (g_LongOpRunning) {
          SetCursor(LoadCursor(NULL, IDC_WAIT));
          return TRUE;
      }
      break;
  // ...
 
Share this answer
 
v2
Since you have tagged your question with C++ but not MFC, I would go with a combination of the previous two solutions. What that means is writing your own excursion class to do this. Here is one way that can be done.
C++
class WaitCursor
{
public:  // members
    HCURSOR m_hOldCursor   { nullptr };

public:  // methods
    WaitCursor()      // constructor
    {
        HCURSOR hc = LoadCursor( NULL, IDC_WAIT );
        m_hOldCursor = SetCursor( hc );
    }

    ~WaitCursor()     // destructor
    {
        SetCursor( m_hOldCursor );
    }
};
This can be used exactly as shown in Solution 2. The previous cursor will be restored when the object falls out of scope and is destroyed. The important thing here is MFC is not required to use this class.

BTW - the reason the cursor becomes invisible is you are trying to load the resource from your app's instance and apparently it does not exist there.
 
Share this answer
 
v2
Comments
merano99 14-Jun-24 15:25pm    
It's nicely packaged, but does it really solve the problem? I suspect that the suspended message processing is causing additional problems due to the long OP. The window is not updated and the mouse pointer is probably not displayed.
Rick York 14-Jun-24 16:43pm    
I think the reason for his problem is in my "BTW" comment. Every time I use a wait cursor suspension of the message loop isn't a problem because changing the cursor forces it to be redrawn.
Since you are going to load a predefined system cursor then replace
Quote:
HCURSOR hCursor = LoadCursor(hInst, IDC_WAIT);
With
C
HCURSOR hCursor = LoadCursor(NULL, IDC_WAIT);
See the documentation[^].
 
Share this answer
 
Comments
merano99 14-Jun-24 15:22pm    
You are right that a cursor with an instance handle would have to come from the application's resources, while NULL would use a system cursor. I suspect that the suspended message processing is causing additional problems due to the long OP. The window is not updated and the mouse pointer is probably not displayed. I have further suggestions, see my solution.
[no name] 2-Jul-24 5:21am    
i had this problem before, then i uninstalled the current version backrooms game and that's okay by now.
Try using CWaitCursor Class | Microsoft Learn[^]:

BOOL SomeLengthyProcess()
{
   CWaitCursor wait;
   //Do the lengthy processing.
   Sleep(1000);

   AfxMessageBox(_T("Some result")); //This changes the cursor.
   wait.Restore();                   //Restore the Wait cursor.
   //Continue Processing.
   Sleep(1000);

   //The destructor changes the cursor back to Regular cursor.
   return TRUE;
}
 
Share this answer
 
Comments
Rick York 14-Jun-24 12:44pm    
This is definitely the way to go however, I don't see MFC in the tags for the question so it might not be an option for this person.
Ștefan-Mihai MOGA 14-Jun-24 13:42pm    
I guess you are right.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900