0

これは私がトレイで見つけたアプローチです...:

http://www.programmersheaven.com/mb/delphikylix/257563/257563/how-can-i-make-a-system-tray-flash/

同じ手法がダイアログでも機能しますか(実際には、追加のパラメーターを持つフォームであるため)?または、ハンドル/アドレス/インターフェイスを取得してオーバーロードしたり、FlashWindow(Ex)メソッドで関数をオーバードライブしたりするなど、はるかに高速なメソッドでそれを行うことができますか?

つまり、たとえばShowMessage()、FlashWindowEx()メソッドを使用してウィンドウ/ダイアログをフラッシュすることはできますか?可能であれば、上記のリンクの例を使用して実行できますか?

どうか、最善の方向を示すか、私の疑問を明確にしてください。

ありがとう。

質問の定式化が悪いことをお詫びします。

4

2 に答える 2

2

同じ手法が、ダイアログ ボックスを含むすべてのトップ レベル ウィンドウに適用されます。ウィンドウのハンドルを取得できる場合は、それを に渡すことができますFlashWindowEx

于 2009-12-29T21:48:14.350 に答える
1

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 でテスト済み。すべてのエラー処理が省略されています。開始点としてのみ使用してください。

于 2009-12-30T11:35:41.093 に答える