I know a solution that will take a few steps, but it will work quite
well, I think.
1) Drop a TApplicationEvents component on your mainform, give it a
nice name.
2) Add the following:
var RecallMessage: UINT;
to the top of your implementation part of the source of your mainform.
3) Using the TApplicationEvents component, add an OnMessage event to
your mainform with the following code:
if (RecallMessage <> 0) and (Msg.message = RecallMessage) then begin
Application.Restore;
Application.BringToFront;
Show;
Handled := True;
end;
4) At the end of your source of the main form, add the following code:
var
Mutex: THandle;
initialization
RecallMessage := RegisterWindowMessage('WM_Unique_Message_Name');
Mutex := CreateMutex(nil, True, 'Some Unique key');
if (Mutex = 0) then raise
Exception.Create(SysErrorMessage(GetLastError));
if (GetLastError = ERROR_ALREADY_EXISTS) then begin
PostMessage(HWND_BROADCAST, RecallMessage, 0, 0);
Application.Terminate;
end;
finalization
CloseHandle(Mutex);
This code will guarantee that there can be only one form active that
uses your main form. And if it gets called a second time, it will send
a message to the previous instance telling it to show itself, even if
it is minimized.
Of course, it can be a bit neater. But hey, it works! Stop complaining...
Okay, how it works...
I do two things. I register a global Windows message, which Windows
will make sure is unique. It is given an unique name (I hope you give
it an unique name!)
The next thing is generating a Mutex. Unfortunately, Windows doesn't
tell me if this message handle was previously created or not. Besides,
you cannot unregister it so until you reboot your system, this message
will have the same value every time. The mutex is used to check if it
finds a previous instance or not.
The CreateMutex() function will return a handle of a mutex, but that's
not really interesting. Just use it to free the mutex again when you
close your application again. Really, you don't need this handle. What
you need is the GetLastError value. If it's the first time the mutex
is created, it should be ERROR_SUCCESS. Otherwise, it will be
ERROR_ALREADY_EXISTS if a previous instance already exists. (Or
another error code if it failed to create the mutex, but I'm not
checking for that...)
If GetLastError = ERROR_ALREADY_EXISTS then I know there was a
previous instance. That means I have to send a message to this
previous instance. Since I don't know where it is, I just broadcast
the message to ALL windows. Then when the PostMessage broadcast is
done, I terminate the application before it's fully started.
The trick is of course having your application to respond to this
broadcasted message. For this I needed the TApplicationEvents
component to capture this message. And when I receive this message, I
just have to do some actions to make the mainform visible again.
Yes, it is that simple. :-)
With kind regards,
X Katja Bergman.
--- In [email protected], "fishsqzr" <[EMAIL PROTECTED]> wrote:
> I am trying to ensure that only one instance of an application will
> run. I have using the uDHSOneInstanceApp utility by Clément Dos.
> While the utility indeed prevents multiple instances of the app, it
> does not restore the current instance or make it the active app. A
> code snippet follows. Any idea why the calls to API don't work?
>
> FMutex := CreateMutex (nil, FALSE, FAppTitle );
>
> if WaitForSingleObject (FMutex, 0) = wait_TimeOut then begin
> // Found another instance
> SetWindowText(Application.Handle,''); // We must not found this
> one again ;)
>
> // Retrieving handle of the first instance;
> hRunningApp := FindWindow(nil,FAppTitle);
> if hRunningApp<>0 then begin
> //***FOLLOWING CODE DOES NOT SEEM TO WORK - Window not
> restored or set to focus
> if IsIconic(hRunningApp) then
> // First instance is minimized.. Restore it
> ShowWindow(hRunningApp,SW_RESTORE);
>
> BringWindowToTop(hRunningApp);
> SetForegroundWindow(hRunningApp);
> end;
------------------------ Yahoo! Groups Sponsor --------------------~-->
<font face=arial size=-1><a
href="http://us.ard.yahoo.com/SIG=12hd0688u/M=362131.6882499.7825260.1510227/D=groups/S=1705115362:TM/Y=YAHOO/EXP=1124464851/A=2889191/R=0/SIG=10r90krvo/*http://www.thebeehive.org
">Get Bzzzy! (real tools to help you find a job) Welcome to the Sweet Life
- brought to you by One Economy</a>.</font>
--------------------------------------------------------------------~->
-----------------------------------------------------
Home page: http://groups.yahoo.com/group/delphi-en/
To unsubscribe: [EMAIL PROTECTED]
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/delphi-en/
<*> To unsubscribe from this group, send an email to:
[EMAIL PROTECTED]
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/