mundodelphi

programacion en delphi

Controlar multiples instancias de nuestra aplicacion

Controling the number of application instances, controlar el numero de instancias de nuestra aplicacion en delphi

Prevenir que nuestra aplicación en delphi se execute dos instancias a la vez, el truco está separado por dos partes

creamos una unidad nueva i le llamamos 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/
********************************************
}

y justo en la inicialización de la aplicación

program Project1;

uses
Forms,  Unit1 in 'Unit1.pas' {Form1},  CheckPrevious in 'CheckPrevious.pas';

{$R *.res}

begin
//permetir solo una instancia
if not CheckPrevious.RestoreIfRunning(Application.Handle, 1) then
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.

Fuente: delphiabout.com
Descarga: codigo fuente

Tagged as: ,

1 Comment

  1. buen aporte mi estimado…

    vas por el buen camino.

    saludos

Leave a Response

Please note: comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Google Analytics Alternative