Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to run my application only once? 3

Status
Not open for further replies.

TimSNL

Programmer
Sep 11, 2001
119
AU
Hello.

Once again I consult the Oracle of Global Intelligence ...

I need to make sure that only one instance of my application is runnung on the desktop.
If the user doubble-clicks the icon to start my application and it is already running, I want to bring the instance that is already running to the front instead of opening anther one.

I thought I saw a thread here about this once, but I could not find it in the search.

Thankyou for your help.

Tim Dover
SNL Computing
 
BTecho's right. Mutex would do the job. Also as an option you could try finding you main for by class name and/or caption using FindWindow/FindWindowEx.
Code:
// example of usin mutex
const AppMutexName = 'MyApplicationMutex'
begin
  if (CreateMutex(nil, True, pChar(AppMutexName)) = ERROR_ALREADY_EXISTS) then
  begin
    ShowMessage('Can''t run the second instance of application');
    Application.Terminate;
  end;
...
end;
HTH

--- markus
 
Or you could write a flag into the registry. on startup and
on closing clear the flag.

writebool(SECTION,'Running',runflag);

On open the app checks to se if the flag is set and terminates if it is.
Otherwise it sets it.

You can extend this approach to allow several copies to run and keep check of how many they are, what resorces they are using etc

Steve
 
hi

I think CreateMutex is the best option.

sggaunt, this wouldn't work properly if the app crashes as the flag will not get reset.

lou

 
Try this:

Code goes on the view source of the project:

var
Hwnd: THandle;
pc: PChar;
begin
pc := PChar(('My application'));
Hwnd := FindWindow('TfrmMain', pc);
if Hwnd = 0 then
begin
Application.Initialize;
Application.Title := 'My application';
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
end else
SetForegroundWindow(Hwnd);
end;


Works for what we do...

 
Awarnica, in your case you have to set your form's caption to blank at design time or close you main form in delphi everytime you start your app, cos FindWindow also finds a form that is being designed :) Been there, seen that...

Cheers.

--- markus
 
Yes, actually is our case we use the lines:


pc := PChar(APPLICATION_TITLE);

&

Application.Title := APPLICATION_TITLE



where APPLICATION TITLE is a constant containing the name of the application plus a version tag.

But for simplicity here I left it out.

BTW I have seen the error you spoke of, hence the use of the constants. Good point, I had forgotten about that error (and it drove me nuts when I tested it the first time!)

Andrew
 
The Oracle of Global Intelligence has spoken.

This humble programmer bows low in thankfulness and awe.
 
awarnica

This one is also going to be very useful to me (especially after weev's comment)

I seem to have a problem though

Any attempt to assign anything other than a string constant to application.title seems to result in Uncompilable code
e.g Application.Title := 'my program'; is fine
Application.Title := ACONSTANT; Greys out the Run arrow

And attemping to edit the project options brings up an 'Application.createform is missing or incorrect' error.

(Oddly the build does seem to complete, though the execuatbles don't exhibit the correct only one behaviour when run directly, they cannot be run from the interface as I said)

Steve



 
Here is my actual code:

where PROGRAM_NAME : = 'WEP'

var
Hwnd: THandle;
pc: PChar;
begin
pc := PChar((PROGRAM_NAME) + ' ' + GetVersionFormatted);
Hwnd := FindWindow('TfrmMain', pc);
if Hwnd = 0 then
begin
Application.Initialize;
Application.Title := 'WEP';
Application.Run;
end else
SetForegroundWindow(Hwnd);
end.

You have to make sure that the pc variable is entirely inside the PChar function.

Post your code if you will and we can take a look at exactly what it is.

Andrew
 
{ Thanks awarnica. Ok Here it is, but now working OK.

I will mention a few points to aid others who might try it.
You must include 'Windows' in the uses clause or FindWindow wont work.
Thanks to McMerfy who in answer to my second post pointed out that
Application.Title must be set after Application.run,
he dosnt say why this is? but it does seeem to work.
Finaly to get it to do the job the constant APPLICATION_TITLE must be set to
the 'Form' variable not just any value, in this case I called the form 'TestForm'
}

program Project1;

uses
Forms,Windows,Dialogs,
Unit1 in 'Unit1.pas' {TestForm};

{$R *.RES}

const APPLICATION_TITLE = 'TestForm';

var HWnd: THandle;
pc : PChar;

begin
pc := PChar(APPLICATION_TITLE);
HWnd := FindWindow('TTestForm', pc);
if Hwnd = 0 then
begin
Application.Initialize;
Application.CreateForm(TTestForm, TestForm);
Application.Run;
Application.Title := APPLICATION_TITLE;
end
else
begin
showmessage('You can only run one copy of '+ APPLICATION_TITLE);
SetForegroundWindow(HWnd);
end;
end.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top