メニューアイテムにサブメニューを追加する
動的にメニューアイテムにサブメニュー項目を追加します。
拙作 MICapture のタスクトレー常駐モード時に実行中のアプリケーションリストを表示するために使用しました。
実行中のアプリケーションリスト取得方法はNifty FDELPHI会議室の発言を参考に(というかママ)しました。
以下のプログラムでは、ポップアップメニューの表示イベントで、メニューアイテム ListSel にサブメニューとして実行中のアプリケーション一覧を追加しています。
private
// 追加したサブメニューの選択イベント処理用
procedure ListSelClick(Sender: TObject);
var
//実行中のアプリケーション(Windows)列挙用
EnumWin: array[0..128] of string;
EnumTtl: array[0..128] of string;
EnumHdl: array[0..128] of THandle;
EnumWinN: integer;
// ウィンドウハンドルから,EXEファイル名を取得する
function GetExeFileName(Wnd: HWND): String;
var
ProccessID: Longint;
hSnapShot: THandle;
ProcessEntry32: TProcessEntry32;
begin
Result:= '';
GetWindowThreadProcessId(Wnd, @ProccessID);
hSnapShot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
try
ProcessEntry32.dwSize:= SizeOf(TProcessEntry32);
if Process32First(hSnapShot, ProcessEntry32) then
repeat
if ProcessEntry32.th32ProcessID = ProccessID then
Result:= String(ProcessEntry32.szExeFile);
until Process32Next(hSnapShot, ProcessEntry32) = False;
finally
CloseHandle(hSnapShot);
end;
end;
// WindowsAPIコールバック関数 ウィンドウの列挙
function EnumWindowsProc(Wnd: HWND; lParam: Longint): Bool; stdcall;
export;
var
lpszCaption: array [0..255] of Char;
lpClassName: array[0..512] of Char;
ExeFileName: String;
begin
Result:= True;
if (GetWindow(Wnd, GW_OWNER) = 0) and IsWindowVisible(Wnd) then
begin
GetWindowText(Wnd, lpszCaption, SizeOf(lpszCaption));
GetClassName(Wnd, lpClassName, SizeOf(lpClassName));
ExeFileName:= GetExeFileName(Wnd);
if EnumWinN < 128 then
begin
EnumWin[EnumWinN] := ExeFileName;
EnumTtl[EnumWinN] := lpszCaption;
EnumHdl[EnumWinN] := Wnd;
Inc(EnumWinN);
end;
end;
end;
// 追加したサブメニューが選択されたときのイベント
procedure TMainForm.ListSelClick(Sender: TObject);
var
SubMnu: TMenuItem;
ActiveWin: integer;
Iconic: ioolean;
begin
// SubMnu に選択されたサブメニューアイテムを取得して
// ActiveWin に何番目のアイテムが選択されたのかを得る
SubMnu := Sender as TMenuItem;
ActiveWin := ListSel.IndexOf(SubMnu);
if ActiveWin > -1 then
begin
// この場合は、選択されたアプリケーションがアイコン状態なら
// 元に戻したうえで、キャプチャ用タイマーを起動している
// ファイル履歴処理など必要に応じた処理をここに書く
Iconic := IsIconic(EnumHdl[ActiveWin]);
if Iconic then
OpenIcon(EnumHdl[ActiveWin]);
SetForegroundWindow(EnumHdl[ActiveWin]);
Timer1.Interval := DelayTime;
end;
end;
// ポップアップメニューのアイテム ListSel にサブメニューとして
// 実行中のアプリケーション一覧を追加する
procedure TMainForm.PopupMenu1Popup(Sender: TObject);
var
i: integer;
SubMnu: TMenuItem;
begin
EnumWinN := 0;
EnumWindows(@EnumWindowsProc, 0);
// 一旦サブメニューを削除する
for i := 0 to ListSel.Count - 1 do
ListSel.Delete(0);
for i := 0 to EnumWinN - 1 do
begin
// メニューを追加する。この場合は Caption と OnClick のみ設定
// 必要に応じて他のプロパティも設定する。
SubMnu := TMenuItem.Create(Self);
if EnumTtl[i] <> '' then
SubMnu.Caption := Format('%2d: ', [i+1]) + EnumTtl[i]
else
SubMnu.Caption := Format('%2d: ', [i+1]) + EnumWin[i];
SubMnu.OnClick := ListSelClick;
ListSel.Add(SubMnu);
end;
end;