Title: Prevent Multiple instance (Don't use it if you don't mean it...)
Question: First of all I wan't to say one thingy... I know there has been several posts regarding the multiple instance prevention problem. I guess I've read them all, but I've never found them 100% the way I like. This one is fully tested, and works the way I like it to work...
Answer:
{
This object has been tested on Win2000. It works fine even if your application crashes or if you terminate the process!
Usage:
In the begining of your .dpr file, write something like this:
--------
Const
MyUniqueID : String = 'MyApplicationsUniqueID';
Begin
IF (MultipleInstance.IsAllreadyStarted(MyUniqueID)) Then
Begin
IF (MultipleInstance.ShowApplication(MyUniqueID)) Then Exit;
End;
MultipleInstance.SetAppHandle(MyUniqueID, Application.Handle);
// Let the form creation and other stuff go here...
End;
--------
}
Unit MultipleInstancePrevention;
Interface
Uses Forms, Windows;
Type
TMultipleInstance = Class(TObject)
Public
Function IsAllreadyStarted(UniqueID: String) : Boolean;
Function ShowApplication(UniqueID: String) : Boolean;
Procedure SetAppHandle(UniqueID: String; AppHandle: THandle);
End;
Var
MultipleInstance : TMultipleInstance;
Implementation
Function GetAppHandle(UniqueID: String) : THandle;
Var
MapHandle : THandle;
MapData : Pointer;
MustInit : Boolean;
Begin
Result := 0;
MapHandle := CreateFileMapping($FFFFFFFF, NIL, PAGE_READWRITE, 0, SizeOf(THandle), pChar(UniqueID));
IF (MapHandle 0) Then
Begin
MustInit := (GetLastError() ERROR_ALREADY_EXISTS);
MapData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
IF (Assigned(MapData)) Then
Begin
IF (MustInit) Then
Begin
Result := 0;
Try
Move(Result, MapData^, SizeOf(THandle))
Except
End;
End
Else
Begin
Try
Move(MapData^, Result, SizeOf(THandle));
Except
Result := 0;
End;
End;
//
End;
End;
End;
Procedure TMultipleInstance.SetAppHandle(UniqueID: String; AppHandle: THandle);
Var
MapHandle : THandle;
MapData : Pointer;
Begin
MapHandle := CreateFileMapping($FFFFFFFF, NIL, PAGE_READWRITE, 0, SizeOf(THandle), pChar(UniqueID));
IF (MapHandle 0) Then
Begin
MapData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
IF (Assigned(MapData)) Then
Begin
Try
Move(AppHandle, MapData^, SizeOf(THandle));
Except
End;
End;
End;
End;
Function TMultipleInstance.IsAllreadyStarted(UniqueID: String) : Boolean;
Var
AppHandle : THandle;
Begin
AppHandle := GetAppHandle(UniqueID);
Result := (IsWindow(AppHandle)) and (AppHandle 0);
End;
Function TMultipleInstance.ShowApplication(UniqueID: String) : Boolean;
Var
AppHandle : THandle;
Begin
Result := False;
AppHandle := GetAppHandle(UniqueID);
IF (AppHandle 0) Then
Begin
Result := IsWindow(AppHandle);
IF (Result) Then
Begin
ShowWindow(AppHandle, SW_SHOWNORMAL);
SetForegroundWindow(AppHandle);
BringWindowToTop(AppHandle);
End;
End;
End;
Initialization
MultipleInstance := TMultipleInstance.Create;
Finalization
IF (Assigned(MultipleInstance)) Then MultipleInstance.Free;
End.