2016-10-18 8 views
5

TCustomFormの子孫のWindowStateの変更を検出するにはどうすればよいですか? WindowStateプロパティが別の値で設定されているときは、いつでも通知を受けたいと思います。WindowStateの変更を検出するにはどうすればよいですか?

セッターの中にイベントや仮想メソッドがあるかどうかを確認しましたが、目標を達成するために何も見つかりませんでした。

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; 

答えて

7

状態が変更されたときにOSがウィンドウに送信する通知は、WM_SIZEメッセージです。あなたが投稿したコード見積もりからは明らかではありませんが、VCLは既にTScrollingWinControlクラス(ascendのTCustomForm)にWM_SIZEをリッスンし、メッセージを処理している間に仮想Resizingプロシージャを呼び出します。

したがって、フォームのこのメソッドをオーバーライドして、通知を受けることができます。

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; 


ウィンドウがサイズ変更されている間に、または視認性が変化している間、通知は、例えば、所与の状態のために複数回送信することができることに留意されたいです。状態が実際に変更されたときを検出するには、前の値を追跡する必要があります。


要件に応じて、フォームのOnResizeイベントを使用することもできます。違いは、OSが変更についてウィンドウに通知する前に、このイベントが発生することです。 VCLはGetWindowPlacementを呼び出してウィンドウ状態情報を取得しますが、TCustomFormWM_WINDOWPOSCHANGINGを処理しています。

以下は、フラグを使用して前のウィンドウの状態を追跡する例です。

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; 
関連する問題