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

4 回答 4

4

尝试遍历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;
于 2013-08-27T17:19:58.523 回答
2
if (Wnd <> 0) and (Wnd <> FormTest.Handle) then

如果 FormTest 不是有效的实例引用,这将导致访问冲突。任何一个:

  1. FormTest 为零,或
  2. FormTest 不是零,而是指一个已被销毁的对象。
于 2013-08-27T07:57:43.330 回答
1

您可以使用GetClassName函数检查窗口的类名

于 2013-08-27T07:51:26.770 回答
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;

它可以很好地识别是否有 TForm1 窗口的句柄。这里最明显的就是FindWindow会在整个 OS 系统中寻找窗口。现在,如果你想要更快的东西,你可以使用@Remy 解决方案,它只会寻找应用程序的表单。

来自 MSDN:

查找窗口功能:

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

要搜索子窗口,请使用以下功能:

FindWindowEx 函数:

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

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

于 2013-08-27T19:59:59.970 回答