Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect WindowState changes?

Tags:

forms

delphi

vcl

How can I detect WindowState changes for a TCustomForm descendant? I would like to be notified at any time the WindowState property is set with a different value.

I've checked if there was an event or a virtual method inside the setter but I didn't found nothing for achieving my goal.

function ShowWindow; external user32 name 'ShowWindow';

procedure TCustomForm.SetWindowState(Value: TWindowState);
const
  ShowCommands: array[TWindowState] of Integer =
    (SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED);
begin
  if FWindowState <> Value then
  begin
    FWindowState := Value;
    if not (csDesigning in ComponentState) and Showing then
      ShowWindow(Handle, ShowCommands[Value]);
  end;
end;
like image 521
Fabrizio Avatar asked Oct 18 '16 12:10

Fabrizio


People also ask

What is WindowState in Visual Basic?

A WindowState that determines whether a window is restored, minimized, or maximized. The default is Normal (restored).

Which property is used to open form in maximized state?

If you see all the Properties of Form in VB.NET, you will find WindowState Property. Set this property value to Maximized your Form will be open with FullScreen Mode.

What is the use of window state property in Visual Basic?

A FormWindowState that represents whether form is minimized, maximized, or normal. The default is FormWindowState.


1 Answers

The notification the OS sends to a window when its state has changed is a WM_SIZE message. It's not evident from the code quote you posted but the VCL already listens for WM_SIZE in TScrollingWinControl class (ascendant of TCustomForm) and calls the virtual Resizing procedure while handling the message.

So you can override this method of your form to get notified.

type
  TForm1 = class(TForm)
    ..
  protected
    procedure Resizing(State: TWindowState); override;

....

procedure TForm1.Resizing(State: TWindowState);
begin
  inherited;
  case State of
    TWindowState.wsNormal: ;
    TWindowState.wsMinimized: ;
    TWindowState.wsMaximized: ;
  end;
end;


Note that the notification can be sent multiple times for a given state, for instance while the window is being resized or while visibility is changing. You might need to track the previous value for detecting when the state is actually changed.


Depending on your requirements you can also use the OnResize event of the form. The difference is that, this event is fired before the OS notifies the window about the change. VCL retrieves window state information by calling GetWindowPlacement while TCustomForm is handling WM_WINDOWPOSCHANGING.

Below is an example using a flag to keep track of the previous window state.

  TForm1 = class(TForm)
    ..
  private
    FLastWindowState: TWindowState; // 0 -> wsNormal (initial value)

...

procedure TForm1.FormResize(Sender: TObject);
begin
  if WindowState <> FLastWindowState then
    case WindowState of
      TWindowState.wsNormal: ;
      TWindowState.wsMinimized: ;
      TWindowState.wsMaximized: ;
    end;
  FLastWindowState := WindowState;
end;
like image 187
Sertac Akyuz Avatar answered Sep 28 '22 04:09

Sertac Akyuz