确定特定单元的模态对话框是否已打开 - Delphi

3

我有一个使用Delphi 7开发的应用程序,它会弹出模态对话框来处理一些情况。我现在想要从另一个单元中判断特定单元中的对话框是否打开,并关闭它。到目前为止,我尝试了以下代码:

Wnd := GetLastActivePopup(Application.Handle);
if (Wnd <> 0) and (Wnd <> Application.Handle) then
   PostMessage(Wnd, wm_close,0,0);

但是,它会关闭所有已打开的对话框。当我尝试指定特定的表单时,例如:
if (Wnd <> 0) and (Wnd <> FormTest.Handle) then

出现访问冲突错误。

我如何确定特定单元的对话框是否弹出?

4个回答

5
尝试通过循环遍历 Screen.Forms 列表,寻找所需的模态窗口,如果找到则关闭它。
var
  I: Integer;
  Frm: TForm;
begin
  for I := 0 to Screen.FormCount-1 do
  begin
    Frm := Screen.Forms[I];
    if fsModal in Frm.FormState then
    begin
      if Frm is TDesiredFormClass then
      // or: if Frm.ClassName = 'TDesiredFormClass' then
      // or: GetTypeData(PTypeInfo(Frm.ClassInfo))^.UnitName = 'DesiredUnitName' then
      // or: if (whatever other criteria you need) then
      begin
        Frm.Close; // sets ModalResult to mrCancel
        Break;
      end;
    end;
  end;
end;

2
if (Wnd <> 0) and (Wnd <> FormTest.Handle) then

这会导致访问违规,如果FormTest不是有效的实例引用。可能是以下两种情况之一:
  1. FormTest为nil,或者
  2. FormTest不是nil,但是指向已被销毁的对象。

1

0

有一个简单的解决方案可能会起作用。

你可以使用:

procedure TForm1.Button2Click(Sender: TObject);
var
  h: hwnd;
begin
  h := FindWindow(PChar('TForm1'), PChar('Form1'));
  if h <> 0 then  
    PostMessage(h, WM_CLOSE, 0,0);
end;

使用 FindWindow 可以很好地识别 TForm1 窗口是否有句柄。显然,FindWindow 将在整个操作系统系统中寻找窗口。现在,如果您想要更快的速度,可以使用 @Remy 的解决方案,它只会寻找应用程序的表单。

来自 MSDN:

FindWindow 函数:

检索类名和窗口名称与指定字符串匹配的顶级窗口的句柄。此函数不搜索子窗口。此函数不执行区分大小写的搜索。

要搜索子窗口,请使用以下函数:

FindWindowEx 函数:

检索类名和窗口名称与指定字符串匹配的窗口的句柄。该函数从指定子窗口之后开始搜索子窗口。此函数不执行区分大小写的搜索。

这些是两个函数的链接,分别为:FindWindowFindWindowEx


不好意思,我说错了。我的意思是这不是解决问题的方法。即便如此,你通常会使用 EnumWindows 获取所有顶级窗口而不是使用 FindWindow 获取第一个。无论如何,一个整个桌面的解决方案肯定不是这里所要求的。 - David Heffernan
这是我的答案中指出的:“显而易见的是,FindWindow将在整个操作系统系统中寻找窗口。” 这也是我建议使用@Remy的答案的原因。 - EProgrammerNotFound
当然。我从来不明白为什么人们会接受那些没有回答他们所问问题的答案。 - David Heffernan
如果我是你,我就不会费心了。如果提问者想要接受这个答案,那就是他们的选择。你确实指出了答案中的缺陷。任何仔细阅读的人都会意识到,在运行多个应用程序实例时运行此代码的危险。 - David Heffernan
不会出现问题,我认为findwindow在寻找窗口时会优先在同一线程和进程中查找。所有我进行的测试中,操作系统都关闭了正确的窗体。显然,这只是一个猜测,我没有任何文档来证明它。 - EProgrammerNotFound
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接