Run only one instance of your application: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 1: Line 1:
The question on how to make sure that your application is only started once by your users can be approached in several ways.
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
# Using mutexes
2. Using FindWindow WinAPI
# Using FindWindow WinAPI


=== Using mutexes ===
=== Using mutexes ===
Line 11: Line 11:


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
<pre>
Procedure Exit_Application
     integer iVoid
     integer iVoid
     If (ghMuteX) Move (CloseHandle(ghMutex)) to iVoid
     If (ghMuteX) Move (CloseHandle(ghMutex)) to iVoid
     move 0 to ghMuteX
     move 0 to ghMuteX
     Forward Send Exit_Application
     Forward Send Exit_Application
End_Procedure
End_Procedure
</pre>
And in a package that gets hit on startup:
And in a package that gets hit on startup:
// Constants
<pre>
Define ERROR_INVALID_HANDLE        for 6    //  taken from error.h of VS7
// Constants
Define ERROR_ALREADY_EXISTS        for 183<br/>
Define ERROR_INVALID_HANDLE        for 6    //  taken from error.h of VS7
Handle ghMuteX<br/>
Define ERROR_ALREADY_EXISTS        for 183<br/>
// external functions
Handle ghMuteX<br/>
#IFNDEF Get_CreateMuteX
// external functions
    External_Function CreateMuteX "CreateMutexA" Kernel32.dll Integer i1 Integer i2 Integer i3 Returns Integer
#IFNDEF Get_CreateMuteX
#ENDIF
    External_Function CreateMuteX "CreateMutexA" Kernel32.dll Integer i1 Integer i2 Integer i3 Returns Integer
#IFNDEF Get_CloseHandle
#ENDIF
    External_Function CloseHandle "CloseHandle" Kernel32.dll Integer i1 Returns Integer
#IFNDEF Get_CloseHandle
#ENDIF<br/>
  External_Function CloseHandle "CloseHandle" Kernel32.dll Integer i1 Returns Integer
// function to create a mutex
#ENDIF<br/>
Procedure Create_MuteX_Object
// function to create a mutex
    Integer iVoid iErr
Procedure Create_MuteX_Object
    String sID
  Integer iVoid iErr
    Move "Unique String For My Application" To sID
  String sID
    Move (CreateMuteX(0,1,AddressOf(sID))) To ghMuteX
  Move "Unique String For My Application" To sID
    If (ghMuteX <> ERROR_INVALID_HANDLE) Begin
  Move (CreateMuteX(0,1,AddressOf(sID))) To ghMuteX
        Move (GetLastError()) To iErr
  If (ghMuteX <> ERROR_INVALID_HANDLE) Begin
        If (iErr = ERROR_ALREADY_EXISTS) Begin  // program is already  
      Move (GetLastError()) To iErr
                                                // running
      If (iErr = ERROR_ALREADY_EXISTS) Begin  // program is already  
            Move (CloseHandle(ghMuteX)) To iVoid
                                              // running
            Move 0 To ghMuteX
          Move (CloseHandle(ghMuteX)) To iVoid
            // kill the application here if you do not want to allow  
          Move 0 To ghMuteX
            // multiple instances
          // kill the application here if you do not want to allow  
            ABORT
          // multiple instances
        End
          ABORT
        Else Send None  // program is not already running
      End
    End
      Else Send None  // program is not already running
    Else Send None  // rare error; object could not be created
  End
End_Procedure  // Create_MuteX_Object<br/>
  Else Send None  // rare error; object could not be created
// create the mutex
End_Procedure  // Create_MuteX_Object<br/>
Send Create_MuteX_Object
// create the mutex
Send Create_MuteX_Object
</pre>


=== Using FindWindow WinAPI ===
=== Using FindWindow WinAPI ===
Line 57: Line 61:


Usage in SRC:
Usage in SRC:
 
<pre>
  Use myPanel,pkg
  Use myPanel,pkg
  Object Main is a myPanel
  Object Main is a myPanel
 
</pre>


Source myPanel.pkg
Source myPanel.pkg
<pre>
  ////////////////////////////////////////////
  ////////////////////////////////////////////
  //
  //
Line 99: Line 104:
       End_Procedure // End_Construct_Object
       End_Procedure // End_Construct_Object
  End_class
  End_class
</pre>


The FindWindow technique is also discussed in the book [http://www.starzen.com/Products/DataFlexVDF/Books/tabid/56/Default.aspx Mastering Visual DataFlex] from Starzen.
The FindWindow technique is also discussed in the book [http://www.starzen.com/Products/DataFlexVDF/Books/tabid/56/Default.aspx Mastering Visual DataFlex] from Starzen.


[[Category: How To]]
[[Category: Tutorials]]
221

edits