I have a delphi app that runs minimized to a tray icon. When the tray icon is double clicked the app opens a non-modal user interface form.
I have added logic to the app to detect whether it is already running. If it isn't running, it starts up and miminizes itself to the tray.
If it is already running, I want it to pass control to the first instance of itself and open the non-modal form, and then exit (the second instance). What's the best way to do this?
TIA R
Microsoft way is not flawless, so i do prefer old school:
const WM_KNOCK_KNOCK = WM_USER + 42;
{ or WM_USER + 265 or any number you like, consult PSDK documentation why WM_USER range }
{ or do RegisterWindowMessage }
{...}
procedure TMainForm.FormCreate(Sender: TObject);
var
Window: HWND;
begin
Window := FindWindow(PChar({MainForm.}ClassName), nil);
{
i neither remember how it works exactly nor have time to investigate right now,
so quick and dirty validity test follows:
}
Assert(not (HandleAllocated and (Window = Handle)), 'failed, use fallback');
{
if Window <> 0 then
begin
PostMessage(Window, WM_KNOCK_KNOCK, 0, 0);
Halt;
end;
{ regular initialization }
end;
Now, WM_KNOCK_KNOCK message handler of first instance performs wakeup routine.
i have little clue what exactly you do when you receive WM_LBUTTONUP (or perhaps WM_LBUTTONDBLCLK) in your Shell_NotifyIcon wrapper (Application.Restore, maybe?). As, Chris Thornton said, there is no such state as 'minimized to tray', it is artifical.
Fallback: if assertion fails, note what code depends only on class function ClassName
so could be easily moved out of FormCreate
and invoked before Application creates it.