最新のDelphiバージョンでは、現代のWindowsバージョンでは、ShowMessage
がWindowsダイアログウィンドウになります。 WH_CBT
フックを使用して、そのダイアログウィンドウのアクティブ化をキャッチすることができます。
function CBTProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
wnd: HWND;
ClassName: string;
begin
if nCode=HCBT_ACTIVATE then
begin
wnd := wParam;
SetLength(ClassName, 256);
SetLength(ClassName, GetClassName(wnd, PChar(ClassName), Length(ClassName)));
if (ClassName='#32770') or (ClassName='TMessageForm') then
Beep;
end;
Result := CallNextHookEx(0, nCode, wParam, lParam);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Hook: HHOOK;
begin
Hook := SetWindowsHookEx(WH_CBT, CBTProc, HInstance, GetCurrentThreadId);
if Hook=0 then
RaiseLastOSError;
try
ShowMessage('hello');
finally
if not UnhookWindowsHookEx(Hook) then
RaiseLastOSError;
end;
end;
実際のウィンドウクラス名は、システムによって異なります。 XPでは、ダイアログは実際にはDelphi TForm
なので、クラス名はTMessageForm
になります。しかし、Vista以降では、ダイアログはウィンドウクラス名#32770
を持つ標準的なウィンドウメッセージボックスダイアログです。
これは、ShowMessage
への1回の呼び出しでラッピングされていますが、アプリに表示されているすべてのメッセージダイアログボックスをフックする場合は、これを起動時にインストールできます。
デビッドのコードがあなたが望むことをするかもしれませんが、私の最初の考えは、あなたが何かを回避する方法を探しているかもしれないということです。なぜあなたがこれを行う必要があるかによって、より良い方法があるかもしれません。これはデバッグのステップですか、誤った第三者のコントロール、テスト手順、または何かの回避策ですか? – MikeD
多分あなたは[TApplication.OnModalBegin](http://docwiki.embarcadero.com/VCL/en/Forms.TApplication.OnModalBegin)や[TApplicationEvents.OnModalBegin](http://docwiki.embarcadero.com/VCL/)を使うことができます。 ja/AppEvnts.TApplicationEvents.OnModalBegin)? –
@UlrichGerhardt私はこれが(明らかに)Delphi 2010以降のための最良の答えだと信じています。 –