Terry
Terry

Reputation: 274

Focussing the right window

The scenario is that I have a 'main app' and a 'helper app'. The 'helper app' pops up on a keyboard hook, does it's stuff, then refocuses the main app window. The problem is that if the main app pops up a modal dialog when helper is active, and the helper then refocuses the wrong window, the modal dialog is hidden and the main app appears 'frozen'.

Any suggestions of strategies to solve this?

Upvotes: 4

Views: 1059

Answers (2)

Sertac Akyuz
Sertac Akyuz

Reputation: 54832

It looks like the modal form of the 'main app' is not owned by the main app window, otherwise the modal form would stay above the main form at all times. So, possibly, either there's no MainFormOnTaskbar property for the Delphi version that it was compiled, or it is not set. Then it must be the hidden application window that owns the windows.

You can test if the main app window is disabled when closing your 'helper app' form (that would be the case if there's a modal form), and restore the last active popup window that is owned by the hidden application window if it is.

var
  Wnd: HWND;     // handle to 'main app's main form
  mWnd: HWND;    // handle to possible modal form
  AppWnd: HWND;  // handle to hidden Application window
begin
  ..

  if not IsWindowEnabled(Wnd) then begin  // test if there's a modal form
    AppWnd := GetWindowLong(Wnd, GWL_HWNDPARENT); // TApplication window handle
    mWnd := GetLastActivePopup(AppWnd); // most recently active popup window

      // restore focus to mWnd     

  end else
    // restore focus to Wnd

(Don't forget to include tests for the result of the API functions of course.)

Upvotes: 1

NGLN
NGLN

Reputation: 43664

Try Application.Restore or Application.RestoreTopMosts. And when that modal dialog is shown by a WinAPI call, then also try Application.Normalize(All)TopMosts before.

Now, this could be sufficient, but in my own application which hides the application handle from the taskbar, it doesn't and I needed the following routine which is the handler of a TApplicationEvents.OnActivate event:

procedure TMainForm.AppEventsActivate(Sender: TObject);
var
  TopWindow: HWND;
begin
  TopWindow := GetLastActivePopup(Application.Handle);
  if (TopWindow <> 0) and (TopWindow <> Application.Handle) then
  begin
    BringToFront;
    SetForegroundWindow(TopWindow);
  end;
end;

Clarification: the code in Application.BringToFront is almost the same, but it does not guarantee to also show the main form in the background. I.e. Application.BringToFront may show only the modal dialog.

Upvotes: 0

Related Questions