Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 获取对对话框窗口窗体(ShowMessage、MsgDialog等)的引用_Delphi_Events - Fatal编程技术网

Delphi 获取对对话框窗口窗体(ShowMessage、MsgDialog等)的引用

Delphi 获取对对话框窗口窗体(ShowMessage、MsgDialog等)的引用,delphi,events,Delphi,Events,是否有任何事件可供我使用,以便我能够捕捉屏幕上出现ShowMessage的时刻?我还需要传递一个对显示消息的TForm的引用 到目前为止,我尝试了OnDeactivate,但似乎,ShowMessage并没有引起它 在.NET中,应用程序上有一种方法可以捕获每个MessageBox(Application.AddFilterMessage或类似的smth),我需要在delphi中使用类似的方法 我想要实现的是: 我必须抓住一个对话框窗口出现的时刻(或者只是一个模式窗口,但它不是那么舒服)。那么我

是否有任何事件可供我使用,以便我能够捕捉屏幕上出现
ShowMessage
的时刻?我还需要传递一个对显示消息的
TForm
的引用

到目前为止,我尝试了
OnDeactivate
,但似乎,
ShowMessage
并没有引起它

在.NET中,应用程序上有一种方法可以捕获每个MessageBox(Application.AddFilterMessage或类似的smth),我需要在delphi中使用类似的方法

我想要实现的是:
我必须抓住一个对话框窗口出现的时刻(或者只是一个模式窗口,但它不是那么舒服)。那么我需要做几个指示。这些说明的目的是让我参考刚刚收到的DialogWindow,例如,我可以在上面找到一些按钮。

在现代Delphi版本中,在现代Windows版本中,
ShowMessage
会生成一个Windows对话框窗口。您可以使用
WH\u CBT
hook捕捉该对话框窗口的激活

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上,类名将是
TMessageForm
,因为该对话框实际上是一个Delphi
TForm
。但是,在Vista和更高版本上,该对话框是一个标准窗口消息框对话框,窗口类名为
#32770


我已经展示了一个对
ShowMessage
的调用,但是如果你想挂接应用程序中显示的所有消息对话框,你可以在启动时安装它。

你也可以使用安装在主窗体的
OnCreate
事件中的应用程序范围的钩子(在
OnDestroy
中卸载):


有和。我还没有真正尝试过它们,所以我无法评论您是否可以在这些事件中获取所有者和/或模态表单。

为什么不直接使用OnActiveFormChange

procedure TForm3.FormCreate(Sender: TObject);
begin
  Screen.OnActiveFormChange := ScreenActiveFormChange;
end;

procedure TForm3.ScreenActiveFormChange(Sender: TObject);
begin
  if Screen.ActiveForm is TOKRightDlg then
    Screen.ActiveForm.Caption := 'Found';
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  with TOKRightDlg.Create(nil) do
  try
    ShowModal;
  finally
    Free;
  end;
end;

事实上,我想隐藏我的应用程序中显示的所有消息。但是我还需要得到dialogbox窗口的一个实例。我已经读到,我无法使用手柄+1获取它
ShowMessage
(对话框)创建一个窗口类
TMessageForm
。我还认为您需要在
CBTProc
中调用
Result:=CallNextHookEx
。\32770类是通过
MessageBox
(Windows)创建的。@jacekwiecieńhook proc中的
wnd
局部变量是被激活窗口的句柄。@David Heffernan我意识到这可能是一个不切实际的问题。我用一个表单创建了一个测试项目。我想把我所有的通讯都挂上。我应该把函数CBTProc放在哪里?虽然David的代码可能会满足您的需求,但我的第一个想法是,您可能正在寻找解决某些问题的方法。可能有更好的方法,这取决于你为什么需要这样做。这是一个调试步骤,一个解决错误的第三方控制、测试程序或其他问题的方法吗?也许你可以使用or?@UlrichGerhardt我相信这是最好的答案,适用于(显然)Delphi 2010及更高版本。在第一次测试后,OnModalBegin看起来很有希望。你应该把它作为答案发布,以防我让它工作:)OnModalBegin不错,但它不会捕获显示windows对话框的直接调用,也不会让事件处理程序知道任何有关正在激活的模式表单的信息。我不确定这是否适用于现代Delphi。在现代Delphi中,
ShowMessage
生成一个标准窗口消息框,而不是
TForm
的后代。但是如果你想钩住一个
t表单
,那么这个代码看起来不错。@Delphi XE2中的DavidHeffernan:
ShowMessage
MessageDlg
仍然使用
TMessageForm
。您可能是指
MessageBox
API。这不会包含在
屏幕表单中,因此您需要针对这种情况使用不同的策略。啊,这取决于操作系统。在WindowsV6及更高版本上,情况并非如此。我想你是在XP上运行的。@DavidHeffernan我是在Windows7 Ultimate 64位上运行的。你是在运行WindowsClassic主题吗?你只需要阅读代码就可以看到发生了什么。如果要转换,请查找
。检查(6)并在
Vcl.Dialogs.pas
中使用最新的CommonDialogs
。目前,您的代码在某些情况下无法工作。
procedure TForm3.FormCreate(Sender: TObject);
begin
  Screen.OnActiveFormChange := ScreenActiveFormChange;
end;

procedure TForm3.ScreenActiveFormChange(Sender: TObject);
begin
  if Screen.ActiveForm is TOKRightDlg then
    Screen.ActiveForm.Caption := 'Found';
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  with TOKRightDlg.Create(nil) do
  try
    ShowModal;
  finally
    Free;
  end;
end;