Run only one instance of your application: Difference between revisions

From DataFlex Wiki
Jump to navigationJump to search
No edit summary
Line 10: Line 10:
Here is the code if you want to go that route."
Here is the code if you want to go that route."


In the SRC file within the panel Object put this piece of code:
In the SRC file within the panel object put this piece of code:
  Procedure Exit_Application
  Procedure Exit_Application
     integer iVoid
     integer iVoid
     If (ghMuteX) Move (CloseHandle(ghMutex)) to iVoid
     If (ghMuteX) Move (CloseHandle(ghMutex)) to iVoid
     move 0 to iVoid
     move 0 to ghMuteX
     Forward Send Exit_Application
     Forward Send Exit_Application
  End_Procedure
  End_Procedure
Line 20: Line 20:
  // Constants
  // Constants
  Define ERROR_INVALID_HANDLE        for 6    //  taken from error.h of VS7
  Define ERROR_INVALID_HANDLE        for 6    //  taken from error.h of VS7
  Define ERROR_ALREADY_EXISTS        for 183
  Define ERROR_ALREADY_EXISTS        for 183<br/>
//
  Handle ghMuteX<br/>
  Handle ghMuteX
  // external functions
  // external functions
  #IFNDEF Get_CreateMuteX
  #IFNDEF Get_CreateMuteX
Line 29: Line 28:
  #IFNDEF Get_CloseHandle
  #IFNDEF Get_CloseHandle
     External_Function CloseHandle "CloseHandle" Kernel32.dll Integer i1 Returns Integer
     External_Function CloseHandle "CloseHandle" Kernel32.dll Integer i1 Returns Integer
  #ENDIF
  #ENDIF<br/>
  // function to create a mutex
  // function to create a mutex
  Procedure Create_MuteX_Object
  Procedure Create_MuteX_Object
Line 49: Line 48:
     End
     End
     Else Send None  // rare error; object could not be created
     Else Send None  // rare error; object could not be created
  End_Procedure  // Create_MuteX_Object
  End_Procedure  // Create_MuteX_Object<br/>
  // create the mutex
  // create the mutex
  Send Create_MuteX_Object
  Send Create_MuteX_Object
=== Using FindWindow WinAPI ===
=== Using FindWindow WinAPI ===



Revision as of 08:01, 24 October 2007

The question on how to make sure that your application is only started once by your users can be approached in several ways.

1. Using mutexes 2. Using FindWindow WinAPI

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 <> ERROR_INVALID_HANDLE) 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

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.