2

メインフォーム以外のアプリケーション内のすべてのフォームを閉じる機能があります

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 ダイアログを強制的に閉じるにはどうすればよいですか?

4

1 に答える 1

3

JVCL は、アプリケーション ハンドルを の 'hwndParent' パラメータに渡しますIDSObjectPicker.InvokeDialog。したがって、ダイアログはアプリケーション ウィンドウによって所有されます (VCL のような 'owner' とは異なり、ポップアップの親に似ています)。次に、ウィンドウを列挙して、アプリケーション ウィンドウが所有するウィンドウを見つけ、閉じるコマンドをポストします。

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;
于 2012-04-25T01:03:10.037 に答える