AsuYuHomepage
トップページ サイトの説明 子供の成長記録 JM BAR Delphi リンク集
Home>>プログラミング>>Tips&Tricks>>メニュー項目を動的に追加する
Delphi Tips
Delphi Win32API
ダウンロード

Delphi Tips & Tricks

メニュー項目を動的に追加する

 Windowsは、APIレベルでメニューハンドルを使用してのメニュー操作をサポートしています。しかしメニューごとに識別子を指定したり、イベントもその識別子で振り分けなかったりと普段Delphiを使っているとなかなか大変です。Delphiなら実行時のメニュー操作もメニュー項目のコンポーネントであるTMenuItem介して簡単にできるんです。

 あとは使う人のアイデアしだいで様々なことができるのではないでしょうか。
//メニューの動的追加操作のサンプルです
//フォーム上のコンポーネントの数だけ、メニューの項目として追加します
//追加するメニューにはフォームに貼り付けただけののTPopupMenuを使っています
procedure TForm1.MenuItemClick(Sender :TObject);
var
  Control :TControl;
begin
  //クリックされたメニュー項目のタグにより対応するコントロールのEnableを切り替え
  Control := (FindComponent
             (Components[(Sender as TMenuItem).Tag].Name) as TControl);
  Control.Enabled := not Control.Enabled;
end;

//フォームが所有するコンポーネントの数だけメニュー項目の動的追加
procedure TForm1.Button1Click(Sender: TObject);
var
  i  :integer;
  MI :TMenuItem;
begin
  for i :=0 to ComponentCount-2 do begin
    MI :=TMenuItem.Create(Self);
    MI.Caption   :=Inttostr(i)+': '+Components[i].Name+ ' '+
                   Components[i].ClassName;
    MI.Name      :='mi'+Components[i].Name;
    MI.Tag       :=i;
    MI.AutoCheck :=true;
    Mi.OnClick   :=Form1.MenuItemClick;  //イベントの動的割り当て
    PopupMenu1.Items.Add(MI);            //ポップアップメニューに追加
  end;
end;

 メニュー項目を追加するには、TMainMenuやTPopupMenuの内部コンポーネントであるTMenuItemを使います。TMenuItemというのは1つのメニュー項目に対応していて、CaptionやImageのほかにチェックマークの有無や、ラジオアイテムの有無などの情報を持っています。
 サンプルでやっていることは単純でコードによりTMenuItemを作成した後各種パラメータを設定しメニューに追加しているだけです。動的に生成したTMenuItemの解放はコンストラクタで指定した Self =Form1が破棄してくれるのでイベント内で TMenuItem を free する必要はありません。
 またこれと似たような動作をする物に NewItem関数があります。定義だけ抜粋しておきますので興味のある方は検索してみてください。
function NewItem(const ACaption: string;  //項目に表示される文字列
                  AShortCut: TShortCut;    //ショートカット(使用しない場合 0)
                  AChecked: Boolean;       //チェックマークの有無
                  AEnabled: Boolean;       //使用可否
                  AOnClick: TNotifyEvent;  //項目をクリックしたときのイベント
                  hCtx: THelpContext;      //ヘルプ(使用しない場合 0)
                  const AName: string)     //コンポーネントのNameプロパティ
                  : TMenuItem;