4

これは MDI の性質に反するように聞こえます。MDI フォーム (FormStyle=fsMdiChild) をモーダルとして表示する必要がある場合があります。また、別の MDI フォームの Application.CreateForm と OnShow イベントの間の部分にもアクセスする必要があります。

Application.CreateForm(Form2,TForm2); // but don't set form2's visible property true.
Form2.caption:='not working example'; 
Form2.SomeMagicToSetVisibleTrue;

何か案は?

4

4 に答える 4

5

最初の問題の場合:次のように、CreateAsMDIなどの別のコンストラクターを追加します。

constructor TModalAndMDIForm.CreateAsMDI(AOwner: TComponent); 
begin 
  f_blChild := true; 
  GlobalNameSpace.BeginWrite; 
  try 
    inherited CreateNew(AOwner); 
    if(not(csDesigning in ComponentState)) then begin 
      Include(FFormState, fsCreating); 
      try 
        FormStyle := fsMDIChild; 
        if(not(InitInheritedComponent(self, TForm))) then 
          raise Exception.CreateFmt('Can't create %s as MDI child', [ClassName]); 
      finally 
        Exclude(FFormState, fsCreating); 
      end; 
    end; 
  finally 
    GlobalNameSpace.EndWrite; 
  end; 
end; 

通常のコンストラクターでは、変数f_blChildをfalseに設定し、継承されたcreateを呼び出します。

自明ではなく、さらに2つのことが必要です。

procedure TModalAndMDIForm.Loaded; 
begin 
  inherited; 
  if(f_blChild) then 
    Position := poDefault 
  else begin 
    Position := poOwnerFormCenter; 
    BorderStyle := bsDialog; 
  end; 
end; 
//----------------------------------------------------------------------------- 
procedure TModalAndMDIForm.DoClose(var Action: TCloseAction); 
begin 
  if(f_blChild) then 
    Action := caFree; 
  inherited DoClose(Action); 
end; 

これで、標準コンストラクターで作成された場合はフォームモーダルを呼び出し、CreateAsMDIで作成された場合はMDI子としてフォームを呼び出すことができます。

これをフォームの宣言に含める場合

property IsChild: boolean read f_blChild; 

フォームがMDIの子であるかどうかに応じて、isChildプロパティに問い合わせるだけで処理を実行することもできます。

2番目の問題については、Application.CreateFormを使用せずに、自分でフォームを作成してください。

ここに、モーダルとMDIの2つの作成があります。

//Modal 
frmDialog := TMyForm.Create(self); 
// Your Code
frmDialog.ShowModal; 
frmDialog.Release; 

//MDI-Child 
frmDialog := TMyForm.CreateChild(self); 
// Your code
frmDialog.Show;

私はこの回答をDelphiPraxisサイトの記事から翻訳しました。

于 2009-09-22T09:53:40.647 に答える
2

最も簡単な方法は、フォームの自明なサブクラスを作成し、設定することです。

FormStyle = fsMDIChild

Form.Visible = False

プロパティインスペクターで。これは試行錯誤済みです!

于 2009-09-22T22:40:01.923 に答える
1

少なくともDelphi2007および2009の場合、非表示のMDI子フォームを作成するのは簡単です。Visible初期のDelphiバージョン(プロパティインスペクターで設定することが不可能であったFalse)の場合、イベントのハンドラーを提供しOnCreate、クラスの保護されたフィールドにアクセスする必要があります。

procedure TMDIChild.FormCreate(Sender: TObject);
begin
  FFormState := FFormState - [fsVisible];
end;

これにより、MDI子の自動表示が無効になります。他の初期化が完了したら、単純Showにそれを実行するか、に設定VisibleすることができますTrue

モーダルMDI子フォームに関する質問には答えようとはしません。これは、Windowsプラットフォームの規則に違反しているためです。

于 2009-09-22T10:06:11.027 に答える
1

上記の回答は実際に必要な仕事をしません。次の理由により、最良の答えも間違っています。

  • 最初のフォームを開く;
  • それを最大化します。
  • ここで、このフォームが別のフォーム (mdi) を呼び出すとします。
  • 同じ方法で構築すると、バグのあるレイアウトが得られます... (子はmdiになりますが、最大化されませんが、最初のものはまだ最大化されます)。だからバギー状態。

本当に fsMDIChild か fsNormal かを実行時に決定する必要がある場合は、次のアプローチを適用する必要があります。

  1. デザインで fsNormal として保存されているフォームがあります(またはその逆)。
  2. InitializeNewForm メソッドをオーバーライドします。
  3. FFormStyle の値を fsMDIChild に設定します (以下を参照)。

...

TYourForm = class(TForm)
...
protected
  procedure InitializeNewForm; override;
...

procedure TYourForm.InitializeNewForm;
var
  FS: ^TFormStyle;
begin
  inherited;
  if DoYourCheckForMDI then
    begin
      FS := @FormStyle;
      FS^ := fsMDIChild;
    end;
end;
于 2015-04-17T13:54:51.363 に答える