Question

Good day to all!

I want to emulate work of different forms in my app as different programms.
All forms have its own button on TaskBar, mainform of app is invisible and Application.ShowMainForm := false.

But if I show two forms, then open some programm that overlay both forms, then open first form (second form is behind some programm), then close first form, the second form activates and restores in front of some programm.

I understand that it restores because after closing first form my app keep active state and that's why first visible form is shown. How can I prevent restoring second form? It seems that I need send to back my app after closing, but I don't know how.

@David Heffernan
It's actually Windows that is behind all of that. When one of your forms is closed, Windows has to decide where to move the focus too. And it chooses to move it to another top-level window in your process, since a visible one exists. It makes this happen by sending the window that it selects a WM_SETFOCUS message. No doubt you can intercept this and stop it happening

I have tried to intercepr WM_SETFOCUS on my window, but there is no such message.

type
  TfMyForm = class(TForm)  
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FOldWindowProc: TWndMethod;
    procedure NewWindowProc(var Message: TMessage);
  end;

implementation

procedure TfMyForm.FormCreate(Sender: TObject);
begin
  FOldWindowProc := WindowProc;
  WindowProc := NewWindowProc;
end;

procedure TfMyForm.NewWindowProc(var Message: TMessage);
begin
  if Message.Msg = WM_SETFOCUS then
    Beep;
  FOldWindowProc(Message);
end;
Was it helpful?

Solution

Here is solution I have found myself.

procedure SwitchToPreviousWindow(AHandle: HWND);
var PrevWindow: HWND;
begin
  PrevWindow := GetNextWindow(AHandle, GW_HWNDNEXT);
  while PrevWindow <> NULL do
  begin
    if IsWindowVisible(PrevWindow) then
    begin
      SetForegroundWindow(PrevWindow);
      Exit;
    end;
    PrevWindow := GetNextWindow(PrevWindow, GW_HWNDNEXT);
  end;
end;

procedure TfMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SwitchToPreviousWindow(Self.Handle);
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top