Run only one instance of your application
The question on how to make sure that your application is only started once by your users can be approached in several ways.
- Using mutexes
- Using FindWindow WinAPI
- Using Atoms
Using mutexes
Dalton Pulsipher says: "We use a MuteX object to do this. Just attach one to your program and on startup check if it already exists on the system. Here is the code if you want to go that route."
In the SRC file within the panel object put this piece of code:
Procedure Exit_Application
integer iVoid
If (ghMuteX) Move (CloseHandle(ghMutex)) to iVoid
move 0 to ghMuteX
Forward Send Exit_Application
End_Procedure
And in a package that gets hit on startup:
// Constants
Define ERROR_INVALID_HANDLE for 6 // taken from error.h of VS7
Define ERROR_ALREADY_EXISTS for 183
Handle ghMuteX
// external functions
#IFNDEF Get_CreateMuteX
External_Function CreateMuteX "CreateMutexA" Kernel32.dll Integer i1 Integer i2 Integer i3 Returns Integer
#ENDIF
#IFNDEF Get_CloseHandle
External_Function CloseHandle "CloseHandle" Kernel32.dll Integer i1 Returns Integer
#ENDIF
// function to create a mutex
Procedure Create_MuteX_Object
Integer iVoid iErr
String sID
Move "Unique String For My Application" To sID
Move (CreateMuteX(0,1,AddressOf(sID))) To ghMuteX
If (ghMuteX <> 0) Begin
Move (GetLastError()) To iErr
If (iErr = ERROR_ALREADY_EXISTS) Begin // program is already
// running
Move (CloseHandle(ghMuteX)) To iVoid
Move 0 To ghMuteX
// kill the application here if you do not want to allow
// multiple instances
ABORT
End
Else Send None // program is not already running
End
Else Send None // rare error; object could not be created
End_Procedure // Create_MuteX_Object
// create the mutex
Send Create_MuteX_Object
Dave Robinson says - A warning: We found CodeJock skinning broke this, though YMMV.
Using FindWindow WinAPI
Leslie Brennan says:
Usage in SRC:
Use myPanel,pkg Object Main is a myPanel
Source myPanel.pkg
////////////////////////////////////////////
//
// 05/24/2007
// Panel Class from Pieter van Dieren to check
// to make sure program is only run one time.
//
/////////////////////////////////////////////
Use dfPanel.pkg
Class myPanel is a Panel
// DoCheckProgramActive
// Checks if the program already is active.
// If so, it activates the running application and closes this one.
Procedure DoCheckProgramActive
String sTitle
Handle hWnd
Integer iVoid
Register_Object Main
Get Label of Main to sTitle
Move (FindWindow("",sTitle)) to hWnd
If (hWnd) Begin
Send Stop_Box (sTitle + " Already is Running and Can only be Started Once.") "Error:"
Move (ShowWindow(hWnd,SW_MAXIMIZE)) to iVoid // 9 =SW_RESTORE SW_NORMAL
Move (SetForegroundWindow(hWnd)) to iVoid
Abort
End
End_Procedure // DoCheckProgramActive
// End_Construct_Object
Procedure End_Construct_Object
Send DoCheckProgramActive
Forward Send End_Construct_Object
End_Procedure // End_Construct_Object
End_class
The FindWindow technique is also discussed in the book Mastering Visual DataFlex from Starzen.
Dave Robinson says: The FindWindow method depends on the Title in the program taskbar being known and consistent.