2012-01-25 16 views
4

これに近い別の質問では、モーダルフォームを取得してメインフォーム内のワークエリア内に保持する答えが得られます。 これを達成する方法(Davidに感謝します)は、WMSizing、WMMoving、WMGetMaxMinInfo、および私の大量のWMShowwindowメッセージを捕捉しています。 私はメッセージ処理に閉じていない、私はそれが私が必要な結果を得ていないという原因をメッセージを管理する方法だと思う。子モダールフォームが最小化されたときにアプリケーション全体を最小化する

私のアプリケーションのすべてのフォームはモーダルです。しかし、同じ実行スレッドで多くを開くことができます。 (メインフォーム、フォーム1、フォーム2、フォーム3 ...フォームN)。 すべてのフォーム(1..N)がメインフォーム内のワークエリア内を移動します。最大化、復元、サイズ変更、移動...その作業領域の限界間。

しかし、アクティブなモーダルフォームの最小化ボタンをクリックしてからアプリケーション全体を最小化する方法や、タスクバーボタンをクリックする方法を管理することはできません。 アプリケーションはXPとW7で使用されます...私はDelphiXEで開発中です。

プロジェクトはここからダウンロードすることができます(Project files - メインフォーム、パネル、ボタン、SecondaryForm、ユニット、それ以上はありません)、ここで質問する前に見つけたすべての提案を試してみることができます。

これは、ワークエリア内にモーダルフォームを保持する元のユニットのソースコードです。

unit uFormularios; 

interface 

uses Classes, SysUtils, Windows, Messages, Forms, DBGrids, StdCtrls, Menus, Graphics, ComCtrls, Math; 

type 
    TForm_en_ventana = class(TForm) 
    private 
    inicializada: boolean; 
    bCentrada  : boolean; 
    bMaximizada : boolean; 
    ancho_original: integer; 
    alto_original : integer; 
    procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW; 
    procedure WMSizing(var msg: TMessage); message WM_SIZING; 
    procedure WMMoving(Var msg: TMessage); message WM_MOVING; 
    procedure WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo); message WM_GETMINMAXINFO; 
    public 
    constructor Create(AOwner: TComponent); override; 
    property centrada: boolean read bCentrada write bCentrada; 
    property maximizada: boolean read bMaximizada write bMaximizada; 
    end; 

procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE); 
procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer); 

var 
    ESPACIO_DE_TRABAJO, VENTANA_DE_TRABAJO: TRect; 

implementation 

constructor TForm_en_ventana.Create(AOwner: TComponent); 
begin 
    inherited; 
    centrada  := TRUE; 
    maximizada := false; 
    inicializada := false; 
end; 

Procedure TForm_en_ventana.WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo); 
begin 
    inherited; 
    with msg.MinMaxInfo^.ptMaxPosition do 
    begin 
     x := VENTANA_DE_TRABAJO.Left; 
     y := VENTANA_DE_TRABAJO.Top; 
    end; 
    with msg.MinMaxInfo^.ptMaxSize do 
    begin 
     x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left; 
     y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top; 
    end; 
    with msg.MinMaxInfo^.ptMaxTrackSize do 
    begin 
     x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left; 
     y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top; 
    end; 
    with msg.MinMaxInfo^.ptMinTrackSize do 
    begin 
     x := ancho_original; 
     y := alto_original; 
    end; 
end; 

procedure TForm_en_ventana.WMSizing(var msg: TMessage); 
var 
    R: PRect; 
begin 
    R  := PRect(msg.LParam); 
    R.Left := Max(R.Left, VENTANA_DE_TRABAJO.Left); 
    R.Right := Min(R.Right, VENTANA_DE_TRABAJO.Right); 
    R.Top := Max(R.Top, VENTANA_DE_TRABAJO.Top); 
    R.Bottom := Min(R.Bottom, VENTANA_DE_TRABAJO.Bottom); 
    Caption := 'Ancho: ' + inttostr(ancho_original) + ' - Alto: ' + inttostr(alto_original); 
end; 

procedure TForm_en_ventana.WMMoving(var msg: TMessage); 
var 
    R  : PRect; 
    dx, dy: integer; 
begin 
    R := PRect(msg.LParam); 
    dx := 0; 
    dy := 0; 
    if R.Left < VENTANA_DE_TRABAJO.Left then 
    dx := VENTANA_DE_TRABAJO.Left - R.Left; 
    if R.Right > VENTANA_DE_TRABAJO.Right then 
    dx := VENTANA_DE_TRABAJO.Right - R.Right; 
    if R.Top < VENTANA_DE_TRABAJO.Top then 
    dy := VENTANA_DE_TRABAJO.Top - R.Top; 
    if R.Bottom > VENTANA_DE_TRABAJO.Bottom then 
    dy := VENTANA_DE_TRABAJO.Bottom - R.Bottom; 
    OffsetRect(R^, dx, dy); 
end; 

procedure TForm_en_ventana.WMShowWindow(var Message: TWMShowWindow); 
begin 
    if inicializada then 
    Exit; 
    inicializada   := TRUE; 
    ancho_original  := Width; 
    alto_original   := Height; 
    Constraints.MinHeight := Height; 
    Constraints.MinWidth := Width; 
    if centrada then 
    begin 
     Left := (((VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left) - Width) div 2) + VENTANA_DE_TRABAJO.Left; 
     Top := (((VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top) - Height) div 2) + VENTANA_DE_TRABAJO.Top; 
    end; 
    if maximizada then 
    SendMessage(Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0); 
end; 

procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer); 
begin 
    VENTANA_DE_TRABAJO.Left := izq; 
    VENTANA_DE_TRABAJO.Right := der; 
    VENTANA_DE_TRABAJO.Top := arr; 
    VENTANA_DE_TRABAJO.Bottom := aba; 
end; 

procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE); 
begin 
    LockWindowUpdate(TForm(F).Handle); 
    TForm(F).Left := ESPACIO_DE_TRABAJO.Left; 
    if MaximoAncho = 0 then 
    TForm(F).Width := ESPACIO_DE_TRABAJO.Right 
    else 
    begin 
     if ESPACIO_DE_TRABAJO.Right < MaximoAncho then 
     TForm(F).Width := ESPACIO_DE_TRABAJO.Right 
     else 
     TForm(F).Width := MaximoAncho; 
    end; 
    TForm(F).Top := ESPACIO_DE_TRABAJO.Top; 
    if MaximaAltura = 0 then 
    TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom 
    else 
    begin 
     if ESPACIO_DE_TRABAJO.Bottom < MaximaAltura then 
     TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom 
     else 
     TForm(F).Height := MaximaAltura; 
    end; 
    if ((MaximoAncho <> 0) or (MaximaAltura <> 0)) and (Centrado) then 
    begin 
     TForm(F).Left := (ESPACIO_DE_TRABAJO.Right - TForm(F).Width) div 2; 
     TForm(F).Top := (ESPACIO_DE_TRABAJO.Bottom - TForm(F).Height) div 2; 
    end; 
    LockWindowUpdate(0); 
end; 

initialization 

SystemParametersInfo(SPI_GETWORKAREA, 0, @ESPACIO_DE_TRABAJO, 0); 
VENTANA_DE_TRABAJO := ESPACIO_DE_TRABAJO; 

end. 

私を助けることができる誰かに感謝します!

+0

...モーダルフォームでの最小化と復元メッセージをキャッチし、これを行います。メインフォームは無効になっており、UIアクションによって最小化することはできません。私はあなたがここで何をしようとしているのか尋ねなければならない。あなたの問題はすべて、あなたがシステムに対して戦っているという事実に由来しているようです。あなたは、このようなふるまいをすることを意図していません。 –

+0

アクティブなフォームを最小限にしようとすると、アプリケーション全体が最小化する必要があります(アプリケーションとすべての開いたフォームがアクティブかどうかを確認してください)。 SIZE_MINIMIZINGを捕まえるためにWMSIZEメッセージをキャッチするように私はあなたが言うように試みます。 – Speaker

+0

おそらく、開いているフォーム(main、form1、form2、form3、form_active)を追跡するグローバルリストを管理します。そして隠す、ショー...捕まえるwmshowwindowメッセージ(sc_minimize anf sc_restore上)?これは私のニーズに到達する「良い」方法ですか? – Speaker

答えて

1

だけで私はあなたがモーダルフォームを持っている場合、これは避けられないと思う

procedure TTheModalForm.WMSysCommand(var Msg: TWMSysCommand); 
begin 
    if (fsModal in FormState) or not Application.MainForm.Visible then 
    begin 
    case Msg.CmdType of 
     SC_MINIMIZE: 
     begin 
     ShowWindow(Application.Handle, SW_SHOWMINNOACTIVE); 
     end; 

     SC_RESTORE: 
     begin 
     ShowWindow(Application.Handle, SW_SHOWNORMAL); 
     inherited; 
     end; 

    else 
     inherited; 
    end; 
    end 
    else 
    inherited; 
end; 
関連する問題