Board index » delphi » D3: Cursor does not change to hourglass if form is disabled and messages are processed

D3: Cursor does not change to hourglass if form is disabled and messages are processed

I want to do some lengthy operation, during which:

  1. The cursor must have the shape of an hourglass
  2. Application.ProcessMessages must be run periodically to update the
     status bar with information concerning operation progress
  3. The form must be disabled, so that no click or similar events occur
     (or Applicaton.ProcessMessages would create a big mess)

So I tried the following:

procedure TForm1.DoSomeLengthyOperation(Sender: TObject);
var SavedCursor: TCursor;
    SavedEnabled: Boolean;
begin
  SavedCursor := Screen.Cursor;
  SavedEnabled := Enabled;
  try
    Screen.Cursor := crHourGlass;
    Enabled := False;
    { Do some lenghty operation,
      periodically setting Application.Hint and
      running Application.ProcessMessages }
  finally
    Screen.Cursor := SavedCursor;
    Enabled := SavedEnabled;
  end;
end;

However, this does not work well; the cursor is an arrow. If I don't
ProcessMessages, it does become an hourglass (but, of course, it does
not update the status bar). If I don't disable the form, again it does
become an hourglass (but the form responds and opens menus etc. even
during the operation).

Thanks a lot for your attention.

 

Re:D3: Cursor does not change to hourglass if form is disabled and messages are processed


Quote
> I want to do some lengthy operation, during which:

>   1. The cursor must have the shape of an hourglass
>   2. Application.ProcessMessages must be run periodically to update the
>      status bar with information concerning operation progress
>   3. The form must be disabled, so that no click or similar events occur
>      (or Applicaton.ProcessMessages would create a big mess)

> So I tried the following:

--snip--  

Quote

> However, this does not work well; the cursor is an arrow. If I don't
> ProcessMessages, it does become an hourglass (but, of course, it does
> not update the status bar). If I don't disable the form, again it does
> become an hourglass (but the form responds and opens menus etc. even
> during the operation).

Modify your code as follows:

procedure TForm1.DoSomeLengthyOperation(Sender: TObject);
var SavedCursor: TCursor;
    SavedOnMessage: TMessageEvent;
begin
  SavedCursor := Screen.Cursor;
  SavedEnabled := Enabled;
  SavedOnMessage := Application.OnMessage;
  try
    Screen.Cursor := crHourGlass;
    Application.OnMessage := DisableUIMessages;
    { Do some lenghty operation,
      periodically setting Application.Hint and
      running Application.ProcessMessages }
  finally
    Application.OnMessage := SavedOnMessage;
    Screen.Cursor := SavedCursor;
  end;
end;

where

Procedure Tform1.DisableUIMessages( var Msg: TMsg; var Handled: Boolean );
begin
  Case Msg.Message of
    WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST:
      Handled := True;
  End;    
end;

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitely requested!

Re:D3: Cursor does not change to hourglass if form is disabled and messages are processed


I worked around the problem, and I don't need anything, but here is what I
did, in case anyone is interested.

Quote
I wrote:
> I want to do some lengthy operation, during which:

>   1. The cursor must have the shape of an hourglass
>   2. Application.ProcessMessages must be run periodically to update the
>      status bar with information concerning operation progress
>   3. The form must be disabled, so that no click or similar events occur
>      (or Applicaton.ProcessMessages would create a big mess)

and suggested code that did not function well,

and Peter Below answered:

Quote
> Modify your code as follows:

> procedure TForm1.DoSomeLengthyOperation(Sender: TObject);
> var SavedCursor: TCursor;
>     SavedOnMessage: TMessageEvent;
> begin
>   SavedCursor := Screen.Cursor;
>   SavedOnMessage := Application.OnMessage;
>   try
>     Screen.Cursor := crHourGlass;
>     Application.OnMessage := DisableUIMessages;
>     { Do some lenghty operation,
>       periodically setting Application.Hint and
>       running Application.ProcessMessages }
>   finally
>     Application.OnMessage := SavedOnMessage;
>     Screen.Cursor := SavedCursor;
>   end;
> end;

> where

> Procedure Tform1.DisableUIMessages( var Msg: TMsg; var Handled: Boolean );
> begin
>   Case Msg.Message of
>     WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST:
>       Handled := True;
>   End;
> end;

Thanks for your response Peter. Nice try, but it too has problems; the
application responds to menu messages, i.e. it opens menus. The operating
system does not send WM_MOUSEMOVE or WM_MOUSECLICK on the menu bar, so not
only the pointer becomes an arrow, but it opens the menus too.

So what I did was give up with Application.Hint and directly set
StatusBar.SimpleText instead, and after that StatusBar.Update (instead of
ProcessMessages). Which is a bit of a mess, because the lenghty operation is
done by another procedure in another unit, which means it must be passed the
StatusBar as an argument -not very elegant. I see, however, that no
application actually does ProcessMessages in this case. For example, Microsoft
Word, when saving a file in foreground, does update the status bar, but does
not repaint the rest of the window; cover the window and uncover it while
saving, and you'll wait until finished saving to repaint.

Re:D3: Cursor does not change to hourglass if form is disabled and messages are processed


In article <3639E95C.A559A...@hydro.civil.ntua.gr>, Anthony Christofides
wrote:
Quote
> > Procedure Tform1.DisableUIMessages( var Msg: TMsg; var Handled: Boolean );
> > begin
> >   Case Msg.Message of
> >     WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST:
> >       Handled := True;
> >   End;
> > end;

> Thanks for your response Peter. Nice try, but it too has problems; the
> application responds to menu messages, i.e. it opens menus.

Yes, i see. The WM_NC* mouse messages are not in the range covered by
WM_MOUSEFIRST..WM_MOUSELAST. Easily fixed (even if you don't need it anymore
<g>):

Procedure Tform1.DisableUIMessages( var Msg: TMsg; var Handled: Boolean );
 begin
   Case Msg.Message of
     WM_KEYFIRST..WM_KEYLAST, WM_MOUSEFIRST..WM_MOUSELAST,
     WM_NCMOUSEMOVE..WM_NCMBUTTONDBLCLK:
       Handled := True;
   End;
 end;

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitely requested!

Other Threads