Question

If I have a ButtonClick event which sets Cursor := crHourglass, Application.ProcessMessages, then use a TOpenDialog to choose a file, and then do something CPU-intensive, the cursor behaves differently depending on whether it is over the existing control when the Open Dialog closes. If the cursor is over the control then the cursor remains as an hourglass; if it's outside the application completely and then moved into the area while the intensive process is still taking place, the cursor remains as an arrow. One cannot click or do anything so it's confusing to the user to get an arrow but not be able to do anything with it.

Stepping through the debugger shows the Cursor is -11 everywhere it should be. Using Screen.Cursor instead of Cursor has the same effect.

Is there a solution?

procedure TMyForm.LoadButtonClick(Sender: TObject);
begin
  Cursor := crHourglass;
  Application.ProcessMessages;
  if OpenDialog.Execute then begin
    // Do something intensive
    // Cursor = crHourglass here but what is displayed is different
  end;
  Cursor := crDefault;
end;
Was it helpful?

Solution

First, make sure to set the cursor only while the CPU-intensive operation is active. Don't change the cursor while choosing a file — you never see any other programs do that, after all.

Second, when you say Cursor in your code, you're referring to the form's property. You might wish to use Screen.Cursor instead so that your entire program displays the same cursor.

Third, there's no need to call Application.ProcessMessages. Messages are going to be processed as soon as you display a dialog box anyway, and besides, there are no particular messages you need processed.

Finally, consider protecting the cursor changes with a try-finally block so that problems in your processing don't leave the cursor in the wrong state:

if OpenDialog.Execute then begin
  Screen.Cursor := crHourglass;
  try
    // TODO: something intensive
  finally
    Screen.Cursor := crDefault;
  end;
end;

If the operation really uses a lot of time, consider moving it off to another thread. Then you don't have to worry about the GUI being unresponsive, and so you won't have to change the cursor in the first place.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top