これに近い別の質問では、モーダルフォームを取得してメインフォーム内のワークエリア内に保持する答えが得られます。 これを達成する方法(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.
私を助けることができる誰かに感謝します!
...モーダルフォームでの最小化と復元メッセージをキャッチし、これを行います。メインフォームは無効になっており、UIアクションによって最小化することはできません。私はあなたがここで何をしようとしているのか尋ねなければならない。あなたの問題はすべて、あなたがシステムに対して戦っているという事実に由来しているようです。あなたは、このようなふるまいをすることを意図していません。 –
アクティブなフォームを最小限にしようとすると、アプリケーション全体が最小化する必要があります(アプリケーションとすべての開いたフォームがアクティブかどうかを確認してください)。 SIZE_MINIMIZINGを捕まえるためにWMSIZEメッセージをキャッチするように私はあなたが言うように試みます。 – Speaker
おそらく、開いているフォーム(main、form1、form2、form3、form_active)を追跡するグローバルリストを管理します。そして隠す、ショー...捕まえるwmshowwindowメッセージ(sc_minimize anf sc_restore上)?これは私のニーズに到達する「良い」方法ですか? – Speaker