1. Home
  2. Computing & Technology
  3. Delphi Programming

{
Article: 

Controling the number of application instances

http://delphi.about.com/library/weekly/aa100703a.htm

In this article you'll learn how to "run-once enable" 
a Delphi application that can check for its previous 
(running) instance. Along the process, several techniques 
of implementing such a check will be discussed; as well 
as how to bring your already running application to the 
foreground, if a user tries to run it "one more time". By 
the end of the article you'll have a copy-to-go code to 
control the behavior of your application's multiple instances: 
with the option to limit the number of running instances. 
}

Download zipped source

Project1.dpr

program Project1; uses Forms, Unit1 in 'Unit1.pas' {Form1}, CheckPrevious in 'CheckPrevious.pas'; {$R *.res} begin //only two instances alowed if not CheckPrevious.RestoreIfRunning(Application.Handle, 2) then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end; end.

CheckPrevious.pas

unit CheckPrevious; interface uses Windows, SysUtils; function RestoreIfRunning( const AppHandle : THandle; MaxInstances : integer = 1) : boolean; implementation type PInstanceInfo = ^TInstanceInfo; TInstanceInfo = packed record PreviousHandle : THandle; RunCounter : integer; end; var MappingHandle: THandle; InstanceInfo: PInstanceInfo; MappingName : string; RemoveMe : boolean = True; function RestoreIfRunning( const AppHandle : THandle; MaxInstances : integer = 1) : boolean; begin Result := True; MappingName := StringReplace( ParamStr(0), '\', '', [rfReplaceAll, rfIgnoreCase]); MappingHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TInstanceInfo), PChar(MappingName)); if MappingHandle = 0 then RaiseLastOSError else begin if GetLastError <> ERROR_ALREADY_EXISTS then begin InstanceInfo := MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TInstanceInfo)); InstanceInfo^.PreviousHandle := AppHandle; InstanceInfo^.RunCounter := 1; Result := False; end else //already runing begin MappingHandle := OpenFileMapping( FILE_MAP_ALL_ACCESS, False, PChar(MappingName)); if MappingHandle <> 0 then begin InstanceInfo := MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TInstanceInfo)); if InstanceInfo^.RunCounter >= MaxInstances then begin RemoveMe := False; if IsIconic(InstanceInfo^.PreviousHandle) then ShowWindow(InstanceInfo^.PreviousHandle, SW_RESTORE); SetForegroundWindow(InstanceInfo^.PreviousHandle); end else begin InstanceInfo^.PreviousHandle := AppHandle; InstanceInfo^.RunCounter := 1 + InstanceInfo^.RunCounter; Result := False; end end; end; end; end; (*RestoreIfRunning*) initialization //nothing special here //we need this section because we have the //finalization section finalization //remove this instance if RemoveMe then begin MappingHandle := OpenFileMapping( FILE_MAP_ALL_ACCESS, False, PChar(MappingName)); if MappingHandle <> 0 then begin InstanceInfo := MapViewOfFile(MappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TInstanceInfo)); InstanceInfo^.RunCounter := -1 + InstanceInfo^.RunCounter; end else RaiseLastOSError; end; if Assigned(InstanceInfo) then UnmapViewOfFile(InstanceInfo); if MappingHandle <> 0 then CloseHandle(MappingHandle); end. (*unit CheckPrevious*) { ******************************************** Zarko Gajic About.com Guide to Delphi Programming http://delphi.about.com email: delphi.guide@about.com free newsletter: http://delphi.about.com/library/blnewsletter.htm forum: http://forums.about.com/ab-delphi/start/ ******************************************** }

Explore Delphi Programming

More from About.com

  1. Home
  2. Computing & Technology
  3. Delphi Programming

©2008 About.com, a part of The New York Times Company.

All rights reserved.