The most common solution being the creation of a 'named mutex', however this method doesn't provide any functionality to inform the original application that an instance was attempted.
This little procedure (windows only) not only tests if the same program in running, it will also post a message to that programs message queue informing the application that another instance was started.
Very useful for tray apps where the program will appear from the tray if the user double clicks the program icon on the desktop.
Code:
Code: Select all
Procedure CheckAndPost(uniquename$,wmessage=#WM_APP,autopost=1)
Protected fn$="Global\"+uniquename$,tmp
RtlAdjustPrivilege_(30,1,0,@tmp)
Protected fm=CreateFileMapping_(#INVALID_HANDLE_VALUE,#Null,#PAGE_READWRITE|#SEC_COMMIT,0,4,@fn$)
If fm
tmp=GetLastError_()
Protected *vm=MapViewOfFile_(fm,#FILE_MAP_ALL_ACCESS,0,0,4)
If *vm
If tmp=#ERROR_ALREADY_EXISTS
tmp=PeekL(*vm)
If autopost
PostThreadMessage_(tmp,wmessage,-1,-1)
EndIf
ProcedureReturn tmp
Else
PokeL(*vm,GetCurrentThreadId_())
EndIf
EndIf
EndIf
EndProcedure
Code: Select all
If CheckAndPost("my app name")
End
EndIf
Global WINSTYLE=#PB_Window_ScreenCentered|#PB_Window_SystemMenu
If Not OpenWindow(1,#PB_Ignore,#PB_Ignore,300,300,"Single Instance",WINSTYLE)
End
EndIf
Repeat
Select WaitWindowEvent(10)
Case #PB_Event_CloseWindow
Break
Case #WM_APP
If EventlParam()=-1 And EventwParam()=-1
MessageRequester("Single Instance","running")
EndIf
EndSelect
ForEver
The wmessage parameter is the message that will be posted to the running application, it defaults to #WM_APP but I prefer to create my own unique message using RegisterWindowsMessage() with the same unique string I pass to this procedure plus "_running", this way I only need check for that in the message loop (lparam and wparam are not needed).
autopost is self explanatory, put a 0 here and the routine wont post the message to the application.
The function will return 0 (not running) or the threadID of the running program, handy if you want to post more messages, etc.
Hope you like.
PS. I didn't check the forums before posting this, so if I've duplicated an existing method, appologies.