How do I close open OLE dialogs
Question
I have a function that closes all the forms in the application apart from the main form
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;
Called from the main form:
CloseOpenForms(Self);
It works fine as long as there are no active OLE dialogs (e.g. TJvObjectPickerDialog).
How can I force these non modal OLE dialogs to close?
Solution
JVCL passes the application handle to 'hwndParent' parameter of IDSObjectPicker.InvokeDialog
, hence the dialog is owned (not like 'owner' as in VCL, but more like popup parent) by the application window. Then you can enurate windows to find out the ones owned by the application window and post them a close command.
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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow