Delphi プログラムからモーダル フォームまたはダイアログ(VCL またはシステムのネイティブ)を表示する方法は多数あるため、メッセージ処理にフックして、モーダル フォームまたはダイアログが表示されたときに送信されるメッセージをキャッチする必要があります。
そのために、 API 関数を使用してメッセージフックを設定できます。SetWindowsHookEx()
これはアプリケーションが非アクティブなときにのみ必要なので、アプリケーション イベントのハンドラーで設定し、OnDeactivate
アプリケーション イベントのハンドラーでリセットすることがOnActivate
できます。
var
gNextHook: HHOOK;
procedure TForm1.AppActivate(Sender: TObject);
begin
if gNextHook <> 0 then
UnhookWindowsHookEx(gNextHook);
gNextHook := 0;
end;
procedure TForm1.AppDeactivate(Sender: TObject);
begin
gNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @WndProcHook, 0,
GetCurrentThreadId);
end;
フック関数は、モーダル ダイアログまたはフォームが表示されたときに送信されるメッセージを監視FlashWindowEx()
し、正しいパラメーターで呼び出します。
function WndProcHook(nCode: integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT; stdcall;
var
DataPtr: PCWPStruct;
Fwi: TFlashWInfo;
begin
DataPtr := PCWPStruct(ALParam);
if (DataPtr^.message = WM_INITDIALOG)
or ((DataPtr^.message = CM_ACTIVATE) and (DataPtr^.lParam = 0) and (DataPtr^.wParam = 0))
then begin
Fwi.cbSize := SizeOf(TFlashWInfo);
// flash caption of new modal window
Fwi.hwnd := DataPtr^.hwnd;
Fwi.dwFlags := FLASHW_ALL or FLASHW_TIMERNOFG;
Fwi.uCount := 0;
Fwi.dwTimeout := 0;
FlashWindowEx(Fwi);
// uncomment this to flash task bar button as well
(*
Fwi.hwnd := Application.MainForm.Handle;
Fwi.dwFlags := FLASHW_TRAY or FLASHW_TIMERNOFG;
FlashWindowEx(Fwi);
*)
end;
Result := CallNextHookEx(gNextHook, nCode, AWParam, ALParam);
end;
WM_INITDIALOG
開くダイアログや保存ダイアログなどのネイティブ ダイアログでCM_ACTIVATE
送信されるものと、VCL フォームがモーダルに表示されたときに送信されるものを選択しました。キャッチする必要があるそのようなメッセージがさらにある可能性があります。上記のコードは、MessageDlg()
関数、Application.MessageBox()
関数、およびTOpenDialog
少なくとも機能します。
これらのダイアログには独自のタスクバー ボタンがないため、メイン フォームのタスクバー ボタンもフラッシュするコードを追加 (コメント アウト) しました。点滅が同期していないため、これは最適ではありません。
Windows XP 上の Delphi 2009 でテスト済み。すべてのエラー処理が省略されています。開始点としてのみ使用してください。