How can I make the second instance of my program pass control back to the first instance?
delphi
Solution
You need to send a message to the other application to request that it shows itself.
First of all you need to find the other application's main window. There are many ways to do that. For instance you can use `FindWindow`. Or you can enumerate the top-level windows with `EnumWindows`. Typically you'd then check for matching window text and/or class name.
Once you've found the main window of the other instance, you need to give it the ability to set itself to be the foreground window. You need to call `AllowSetForegroundWindow`.
var
pid: DWORD;
....
GetWindowThreadProcessId(hwndOtherInstance, pid);
AllowSetForegroundWindow(pid);
Then send the window a user-defined message. For instance:
const
WM_RESTOREWINDOW = WM_APP;
....
SendMessage(hwndOtherInstance, WM_RESTOREWINDOW, 0, 0);
Finally, your other instance's main form needs to listen for this message.
type
TMainForm = class(TForm)
....
protected
procedure WMRestoreWindow(var Message: TMessage); message WM_RESTOREWINDOW;
....
end;
When it encounters the message it must do this:
procedure TMainForm.WMRestoreWindow(var Message: TMessage);
begin
inherited;
Visible := True;
Application.Restore;
Application.BringToFront;
end;
I'm a little sceptical of your mutex handling code. I don't understand the need for security attributes since you are creating it in the local namespace. But then I see a second call to `CreateMutex` that ignores the return value, but creates an object in the global namespace.
Problem
I have create an application with Delphi XE3. My application have a trayicon (I use TCoolTrayIcon for this) so when the user minimize it there is not a icon on taskbar but only on trayicon. To avoid more that one istance of my application I use this code: ``` procedure CreateMutexes(const MutexName: String); const SECURITY_DESCRIPTOR_REVISION = 1; var SecurityDesc: TSecurityDescriptor; SecurityAttr: TSecurityAttributes; MutexHandle: THandle; begin InitializeSecurityDescriptor(@SecurityDesc, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(@SecurityDesc, True, nil, False); SecurityAttr.nLength := SizeOf(SecurityAttr); SecurityAttr.lpSecurityDescriptor := @SecurityDesc; SecurityAttr.bInheritHandle := False; MutexHandle := CreateMutex(@SecurityAttr, False, PChar(MutexName)); if MutexHandle <> 0 then begin if GetLastError = ERROR_ALREADY_EXISTS then begin MessageBox(0, 'You cannot start more than one instance of ContLab.' + #13#10 + 'Use the instance has already started.', 'ContLab', mb_IconHand); CloseHandle(MutexHandle); Halt; end end; CreateMutex(@SecurityAttr, False, PChar('Global\' + MutexName)); end; ``` In this way when the user start application 2 times he get an error message and the second instance is terminate. Now I'd like not show the error message but open the main form of first instance of application and terminate the second instance. Is it possible?