有没有我可以使用的事件所以我会抓住ShowMessage屏幕上显示的那一刻?我还需要传递对TForm已显示消息的引用.
到目前为止我试过了OnDeactivate,但似乎ShowMessage并没有引起它......
在.NET中有一个关于Application的方法可以捕获每个MessageBox(Application.AddFilterMessage或类似这样的smth),我在delphi中需要这样的东西
我想要实现的是: 我必须抓住一个对话窗口出现的那一刻(或者只是一个模态窗口,但它并不那么舒服).我需要做几个指令.这些说明的目标是给我一个刚刚收到的DialogWindow的参考,所以我可以得到一些位于它上面的按钮.
在现代的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;
Run Code Online (Sandbox Code Playgroud)
请注意,实际的窗口类名称因系统而异.在XP上,类名将是TMessageForm因为对话框实际上是一个Delphi TForm.但是,在Vista上以后,该对话框是一个带窗口类名称的标准窗口消息框对话框#32770.
我已经在一次调用中显示了这个ShowMessage,但如果你想挂钩应用程序中显示的所有消息对话框,你可以在启动时安装它.
您还可以使用主窗体OnCreate事件中安装的应用程序范围的挂钩(已卸载OnDestroy):
procedure TMainForm.FormCreate(Sender: TObject);
begin
...
Application.HookMainWindow(ApplicationHook);
end;
procedure TMainForm.FormDestroy(Sender: TObject);
begin
...
Application.UnhookMainWindow(ApplicationHook);
end;
function TMainForm.ApplicationHook(var Message: TMessage): Boolean;
var
I: Integer;
begin
Result := False;
if (Message.Msg = WM_ENABLE) and not TWMEnable(Message).Enabled then // disabling
for I := 0 to Screen.FormCount - 1 do
with Screen.Forms[I] do
if Enabled and (ClassNameIs('TMessageForm') or // ShowMessage, MessageDlg
ClassNameIs('TForm') or // InputQuery
ClassNameIs('TMyLoginDialog')) then // your own dialogs, etc.
begin
Screen.Forms[I].Position := poScreenCenter; // for example
Result := True;
Break;
end;
end;
Run Code Online (Sandbox Code Playgroud)