GTwoD
asked on
Creating a Single instance of an Application
Hi
Up until now I have been using the following code to create a single instnce of my apps, but for some unknown reason it does not seem to work:-s. I will stop a second instnce from beeing created but will not bring the from forward. can anyone tell me what I am do wrong?
program PGLIWMan;
uses
Forms,windows,
VTDevManFM in 'VTDevManFM.pas' {ManFRM},
VTGUITypes in '..\VTGUITypes.pas',
TDeviceManager in '..\TDeviceManager.pas',
CommonRoutines in 'G:\MyDocs\Delphi Source\Useful\CommonRoutin es.pas';
{$R *.RES}
var
Hmutex:Thandle;
begin
HMutex:= CreateMutex(nil,false,'Man FRM');
if WaitForSingleObject(hmutex ,0) <> wait_TimeOut then
begin
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa nFRM,ManFR M);
Application.Run;
end
else
begin
setForegroundWindow(Hmutex );
end;
end.
I am using Delphi 5, drop me a line if you want more info
Up until now I have been using the following code to create a single instnce of my apps, but for some unknown reason it does not seem to work:-s. I will stop a second instnce from beeing created but will not bring the from forward. can anyone tell me what I am do wrong?
program PGLIWMan;
uses
Forms,windows,
VTDevManFM in 'VTDevManFM.pas' {ManFRM},
VTGUITypes in '..\VTGUITypes.pas',
TDeviceManager in '..\TDeviceManager.pas',
CommonRoutines in 'G:\MyDocs\Delphi Source\Useful\CommonRoutin
{$R *.RES}
var
Hmutex:Thandle;
begin
HMutex:= CreateMutex(nil,false,'Man
if WaitForSingleObject(hmutex
begin
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa
Application.Run;
end
else
begin
setForegroundWindow(Hmutex
end;
end.
I am using Delphi 5, drop me a line if you want more info
https://www.experts-exchange.com/questions/20425481/How-to-create-single-instance-application-in-Delphi.html
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
program PGLIWMan;
uses
Forms,
SysUtils,
Windows,
Messages,
VTDevManFM in 'VTDevManFM.pas' {ManFRM};
{$R *.res}
var
hFileMap, Handle: Cardinal;
FMapPt: Pointer;
begin
hFileMap := CreateFileMapping($FFFFFFF F, // $FFFFFFFF get's memory file
nil, // no security attributes
PAGE_READWRITE,// read/write access
0, // size: high 32-bits
2048, // size: low 32-bits
'Q_21080749'); // name of map object
if (GetLastError = ERROR_ALREADY_EXISTS) then
begin
if (ParamCount > 0) then
begin
FMapPt := MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
if FMapPt <> nil then
begin
Handle := Cardinal(FMapPt^);
if FileExists(ParamStr(1)) then
StrCopy(Pointer(Integer(FM apPt)+4), PChar(ParamStr(1)));
UnmapViewOfFile(FMapPt);
SendMessage(Handle, WM_USER+432, 0, 0);
end;
end;
CloseHandle(hFileMap);
Exit;
end;
Application.Initialize;
Application.Title := 'Single Instance Application';
Application.CreateForm(TMa nFRM, ManFRM);
Application.Run;
CloseHandle(hFileMap);
end.
//........
unit VTDevManFM;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TManFRM = class(TForm)
Edit1: TEdit;
private { Private declarations }
procedure GetFileName(var Msg : TMessage); message WM_USER + 432;
public { Public declarations }
end;
var
ManFRM: TManFRM;
implementation
{$R *.dfm}
procedure TManFRM.GetFileName(var Msg : TMessage);
var
hFileMap: Cardinal;
FMapPt: Pointer;
AryChar2: Array[0..2043] of Char;
begin
hFileMap := OpenFileMapping(FILE_MAP_W RITE, False, 'Q_21080749');
FMapPt := MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
if (FMapPt <> nil) then
begin
StrCopy(@AryChar2[0],Point er(Integer (FMapPt)+4 ));
// OpenFile(AryChar2); {OpenFile is your apps procedure to open files}
UnmapViewOfFile(FMapPt);
end;
CloseHandle(hFileMap);
end;
end.
uses
Forms,
SysUtils,
Windows,
Messages,
VTDevManFM in 'VTDevManFM.pas' {ManFRM};
{$R *.res}
var
hFileMap, Handle: Cardinal;
FMapPt: Pointer;
begin
hFileMap := CreateFileMapping($FFFFFFF
nil, // no security attributes
PAGE_READWRITE,// read/write access
0, // size: high 32-bits
2048, // size: low 32-bits
'Q_21080749'); // name of map object
if (GetLastError = ERROR_ALREADY_EXISTS) then
begin
if (ParamCount > 0) then
begin
FMapPt := MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
if FMapPt <> nil then
begin
Handle := Cardinal(FMapPt^);
if FileExists(ParamStr(1)) then
StrCopy(Pointer(Integer(FM
UnmapViewOfFile(FMapPt);
SendMessage(Handle, WM_USER+432, 0, 0);
end;
end;
CloseHandle(hFileMap);
Exit;
end;
Application.Initialize;
Application.Title := 'Single Instance Application';
Application.CreateForm(TMa
Application.Run;
CloseHandle(hFileMap);
end.
//........
unit VTDevManFM;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TManFRM = class(TForm)
Edit1: TEdit;
private { Private declarations }
procedure GetFileName(var Msg : TMessage); message WM_USER + 432;
public { Public declarations }
end;
var
ManFRM: TManFRM;
implementation
{$R *.dfm}
procedure TManFRM.GetFileName(var Msg : TMessage);
var
hFileMap: Cardinal;
FMapPt: Pointer;
AryChar2: Array[0..2043] of Char;
begin
hFileMap := OpenFileMapping(FILE_MAP_W
FMapPt := MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
if (FMapPt <> nil) then
begin
StrCopy(@AryChar2[0],Point
// OpenFile(AryChar2); {OpenFile is your apps procedure to open files}
UnmapViewOfFile(FMapPt);
end;
CloseHandle(hFileMap);
end;
end.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi thanks for the responses
Workshop_alex do you have example of the code what you taled about?
Workshop_alex do you have example of the code what you taled about?
ASKER
Another point the code for bring the window forward has worked before in other apps, but not now any ideas?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi all realised with a couple of yours help what I did wrong the
I like the look of Hotrod's suggestion it is simple and effective, but it did not stop muliple instances
but it did inspire me write my own...
var
Hmutex:Thandle;
HWindow:Thandle;
begin
HMutex:= CreateMutex(nil,false,'Man FRM');
HWindow:= FindWindow('TManFrm');
if WaitForSingleObject(hmutex ,0) <> wait_TimeOut then
begin
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa nFRM,ManFR M);
Application.Run;
end
else
begin
setForegroundWindow(HWindo w);
end;
end.
So I have split the point to those who has suggested FindWindow.
I like the look of Hotrod's suggestion it is simple and effective, but it did not stop muliple instances
but it did inspire me write my own...
var
Hmutex:Thandle;
HWindow:Thandle;
begin
HMutex:= CreateMutex(nil,false,'Man
HWindow:= FindWindow('TManFrm');
if WaitForSingleObject(hmutex
begin
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa
Application.Run;
end
else
begin
setForegroundWindow(HWindo
end;
end.
So I have split the point to those who has suggested FindWindow.
ASKER
Repost...(Sorry)
var
Hmutex:Thandle;
HWindow:Thandle;
begin
HMutex:= CreateMutex(nil,false,'Man FRM');
//forgot to add nil as paramtre
HWindow:= FindWindow('TManFrm',nil);
if WaitForSingleObject(hmutex ,0) <> wait_TimeOut then
begin
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa nFRM,ManFR M);
Application.Run;
end
else
begin
setForegroundWindow(HWindo w);
end;
end.
var
Hmutex:Thandle;
HWindow:Thandle;
begin
HMutex:= CreateMutex(nil,false,'Man
//forgot to add nil as paramtre
HWindow:= FindWindow('TManFrm',nil);
if WaitForSingleObject(hmutex
begin
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa
Application.Run;
end
else
begin
setForegroundWindow(HWindo
end;
end.
a better approach would be:
// Will try to create a named mutex
CreateMutex(nil, false, ManFRM);
// if it failed then there is another instance running
if GetLastError = ERROR_ALREADY_EXISTS then begin
// There is an error, so it exist another ManFRM instance running
// Send all windows our custom message - only our other
// instance will recognise it, and restore itself
SendMessage(HWND_BROADCAST , RegisterWindowMessage('Man FRM'), 0, 0);
Halt(0);
end;
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa nFRM,ManFR M);
Application.Run;
// Will try to create a named mutex
CreateMutex(nil, false, ManFRM);
// if it failed then there is another instance running
if GetLastError = ERROR_ALREADY_EXISTS then begin
// There is an error, so it exist another ManFRM instance running
// Send all windows our custom message - only our other
// instance will recognise it, and restore itself
SendMessage(HWND_BROADCAST
Halt(0);
end;
Application.Initialize;
Application.Title := 'VT Manager';
Application.CreateForm(TMa
Application.Run;