Author: Jonas Bilinkevicius
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.
1 2 {$R *.RES}3 4 function AlreadyRunning: Boolean;
5 var6 wndmain, wndapp: HWND;
7 begin8 wndmain := FindWindow('TMDIForm', nil);
9 {should really use a more unique classname}10 result := wndmain <> 0;
11 if result then12 begin13 wndapp := GetWindowLong(wndmain, GWL_WNDPARENT);
14 if IsIconic(wndapp) then15 SendMessage(wndapp, WM_SYSCOMMAND, SC_RESTORE, 0)
16 else17 SetForegroundWindow(wndapp);
18 end;
19 end;
20 21 begin22 if AlreadyRunning then23 Exit;
24 Application.Initialize;
25 Application.Title := 'J&S Library Manager';
26 Application.CreateForm(TMDIForm, MDIForm);
27 Application.CreateForm(TEditTextForm, EditTextForm);
28 Application.CreateForm(TOptionForm, OptionForm);
29 Application.CreateForm(TAboutBox, AboutBox);
30 Application.Run;
31 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.