如何关闭打开的OLE对话框

时间:2012-04-24 08:33:08

标签: windows delphi ole jedi

我有一个函数可以关闭应用程序中除主窗体之外的所有窗体

procedure CloseOpenForms(const Component: TComponent);
var
  i: Integer;
begin
  for i := 0 to pred(Component.ComponentCount) do
  begin
    CloseOpenForms(Component.Components[i]);

    if Component.Components[i] is TForm then
    begin
      TForm(Component.Components[i]).OnCloseQuery := nil;

      TForm(Component.Components[i]).Close;
    end;
  end;
end;

从主要表格调用:

CloseOpenForms(Self);

只要没有活动的OLE对话框(例如TJvObjectPickerDialog),它就可以正常工作。

如何强制关闭这些非模态OLE对话框?

1 个答案:

答案 0 :(得分:3)

JVCL将应用程序句柄传递给IDSObjectPicker.InvokeDialog的'hwndParent'参数,因此对话框拥有(不像VCL中的'owner',但更像是popup parent)应用程序窗口然后,您可以使用Windows来查找应用程序窗口所拥有的窗口并发布一个关闭命令。

procedure CloseOpenForms(const AComponent: TComponent);

  function CloseOwnedWindows(wnd: HWND; lParam: LPARAM): BOOL; stdcall;
  begin
    Result := TRUE;

    if (GetWindow(wnd, GW_OWNER) = HWND(lParam)) and (not IsVCLControl(wnd)) then
    begin
      if not IsWindowEnabled(wnd) then      // has a modal dialog of its own
        EnumWindows(@CloseOwnedWindows, wnd);

      SendMessage(wnd, WM_CLOSE, 0, 0);
    end;
  end;

  procedure CloseOpenFormsRecursive(const RecComponent: TComponent);
  var
    i: Integer;
  begin
    for i := 0 to pred(RecComponent.ComponentCount) do
    begin
      CloseOpenFormsRecursive(RecComponent.Components[i]);

      if RecComponent.Components[i] is TForm then
      begin
        TForm(RecComponent.Components[i]).OnCloseQuery := nil;

        TForm(RecComponent.Components[i]).Close;
      end;
    end;
  end;

begin
  EnumWindows(@CloseOwnedWindows, Application.Handle);

  CloseOpenFormsRecursive(AComponent)
end;