2004. január 9., péntek

How to restore / set focus to an application after re-running the executable


Problem/Question/Abstract:

I'm trying to restore/ set focus to my app after re-running the exe. I've tried using the Windows.Setfocus(FormHandle) command without success. I've also tried using ShowWindow. Doing this doesn't set focus to the window. If the the window is minimizied it restores it to the screen ok but the application still believes it is minimized, thus you can't minimize the window. You can overcome this by first right clicking the app's taskbar button and selecting restore. The minimize button then works correctly.

Answer:

You have to deal with the first instances Application window, not with the main form.

{$R *.RES}

function AlreadyRunning: Boolean;
var
  wndmain, wndapp: HWND;
begin
  wndmain := FindWindow('TMDIForm', nil);
  {should really use a more unique classname}
  result := wndmain <> 0;
  if result then
  begin
    wndapp := GetWindowLong(wndmain, GWL_WNDPARENT);
    if IsIconic(wndapp) then
      SendMessage(wndapp, WM_SYSCOMMAND, SC_RESTORE, 0)
    else
      SetForegroundWindow(wndapp);
  end;
end;

begin
  if AlreadyRunning then
    Exit;
  Application.Initialize;
  Application.Title := 'J&S Library Manager';
  Application.CreateForm(TMDIForm, MDIForm);
  Application.CreateForm(TEditTextForm, EditTextForm);
  Application.CreateForm(TOptionForm, OptionForm);
  Application.CreateForm(TAboutBox, AboutBox);
  Application.Run;
end.

I have a deep aversion against directly manipulating a window from outside, so I usually don't restore/show the first instances window from the second instance but instead send a message to the first instances main form and have it restore/show itself in a handler for the message. Using WM_COPYDATA it is also easy to pass on a commandline to the first instance this way.

Nincsenek megjegyzések:

Megjegyzés küldése