メニューに子フォームの一覧を作成するには

解決


ファル  2005-04-09 00:27:36  No: 14160

MDIフォームで複数の子フォームが開いている時、
特定の子フォームのキャプションを指定してアクティブにしたいと思います。
Excelのように[ウィンドウ]メニューの中に開いているフォームの
一覧を作成し、これをクリックすることによって実現したいのですが、
MDIChildrenを使って取得したフォーム名をメニュー内で一覧にするには
どうすればよろしいでしょうか?
メニューの更新の仕方とイベントハンドラをどうするかをお教え下さい。


  2005-04-09 03:12:07  No: 14161

このようなかんじでしょうか?
Form1のButton1をクリックする度に子フォームを作成し、メニューを追加します。
メニューを選択すると、対応する子フォームがアクティブになります。

//親フォーム
type
  TForm1 = class(TForm)
    Button1: TButton;
    MainMenu1: TMainMenu;
    WindowMenu: TMenuItem;
    procedure Button1Click(Sender: TObject);
// 省略

procedure TForm1.Button1Click(Sender: TObject);
var
  Frm2: TForm2;
begin
  Frm2 := TForm2.Create(Self);
  try
    Frm2.Show;
  except
    Frm2.Free;
  end;
end;

//子フォーム
type
  TForm2 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FMItem: TMenuItem;
    procedure CustomMenuItemClick(Sender: TObject);
// 省略

procedure TForm2.FormCreate(Sender: TObject);
begin
  Self.Caption := '子フォーム' + IntToStr(Form1.MDIChildCount);
  FMItem := TMenuItem.Create(Form1);
  FMItem.Caption := Self.Caption;
  FMItem.OnClick := CustomMenuItemClick;
  Form1.WindowMenu.Add(FMItem);
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  try
    Form1.WindowMenu.Delete(Form1.WindowMenu.IndexOf(FMItem));
    FMItem.Free;
  except
  end;
end;

procedure TForm2.CustomMenuItemClick(Sender: TObject);
begin
  SendMessage(Form1.ClientHandle, WM_MDIACTIVATE, Self.Handle, 0);
end;


りおりお  2005-04-09 03:19:54  No: 14162

> FMItem := TMenuItem.Create(Form1);

Owner を self にしておくと、自分が死ぬと自動的にメニューから除かれる。


通りすがり  2005-04-09 03:20:20  No: 14163

そんなことしなくても、親フォームのオブジェクトインスペクタで、WindowMenuという項目を設定してやればいいと思います。

Delphiメニュー→ファイル→新規作成→その他→プロジェクトタブ→MDIアプリケション

がサンプルになると思います。


ファル  2005-04-09 08:21:41  No: 14164

皆さんありがとうございます。
通りすがりさんの方法が手間要らずで助かります。
サンプルでの動作も確認できました。
しかし……
fsMDIFormとなっているメイン(親)フォームのWindowMenuプロパティを
設定するだけでは、自分のアプリでは動作しませんでした。
WindowMenuプロパティでメニュー項目を指定する以外に、
何らかの条件があるのでしょうか?
よろしくお願いします。


通りすがり  2005-04-09 08:50:21  No: 14165

すいません。そこまでは分かりません。
一応、サンプルではなく、1からMDIを作って動かしてみましたが、私の環境では動作しました。
前に
http://www.geocities.co.jp/SiliconValley-Bay/3828/a14.html
を読んでて知ったことなので私もなんとも....

ただ、WindowMenuに指定するMenuItemは、最上位(?)というか、普通のメインメニューとして表示されているものでなければならないみたいです。
それと、そのMenuItemは1個以上のMenuItemを持っている必要があるみたいです。


ファル  2005-04-09 09:10:05  No: 14166

> そのMenuItemは1個以上のMenuItemを持っている必要があるみたいです。
どうやらこれがミソだったようです。
何もアイテムがなかったところにセパレータを追加しただけで機能しました。
無事解決です。
皆さんありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加