Code: Select all
;======================================================================
; Module: OnlyOne.pbi
;
; Author: Thomas (ts-soft) Schulz
; Date: Feb 16, 2014
; Version: 1.2
; Target Compiler: PureBasic 5.2+
; Target OS: All
; License: Free, unrestricted, no warranty whatsoever
; Use at your own risk
;======================================================================
; History:
; Version 1.2
; - Removed the autoclean on #PB_Event_CloseWindow
; + ReleaseOne() to remove Timer and delete LockFile
; + changed Example to reflect the changes
; Version 1.1
; + IsWindow() in CloseWinCB()
; + Compiler OS Directive for PostEvent in CloseWinCB()
;
; Version 1.0
; change timestamp to filedate
; + some optimise
;
; Version 0.9
; + timestamp for lockfile (lockfile is outdated after 5 minutes)
; + PostEvent to CloseWinCB()
; Version 0.8
; + unbind timer
; + some small corrections
;
; Version 0.7
; + some sanichecks
; + removetimer
; + unbindevent
;
; Version 0.6
; + createmutex for windows, to make sure it works after crash (lockfile not deleted!)
DeclareModule OnlyOne
EnableExplicit
Declare.i InitOne(wID, ; ID of the main window.
OnlyOneName.s, ; Unique name for Lockfile.
CustomEvent = #PB_Event_FirstCustomValue, ; User-defined event in which the parameters are processed.
TimerID = 1, ; TimerID to use.
TimeOut = 2000) ; Interval in ms, to check the passed parameter queries.
Declare.i ReleaseOne() ; Delete LockFile and removes Timer.
Declare.s GetParameters() ; The parameter string, separated with #LF$
EndDeclareModule
Module OnlyOne
Global.i Event, win, timer
Global.s LockFile, Paras
Procedure TimerCB()
Static oldtime = 0
If oldtime = 0 : oldtime = Date() : EndIf
Protected FF, time
If FileSize(LockFile) > 0
FF = ReadFile(#PB_Any, LockFile)
If FF
Paras = ""
While Not Eof(FF)
Paras + ReadString(FF) + #LF$
Wend
CloseFile(FF)
FF = CreateFile(#PB_Any, LockFile)
If FF
CloseFile(FF)
EndIf
PostEvent(Event)
EndIf
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
CompilerDefault
Else
time = AddDate(oldtime, #PB_Date_Minute, 3)
If time < Date()
oldtime = Date()
SetFileDate(LockFile, #PB_Date_Modified, Date())
EndIf
CompilerEndSelect
EndIf
EndProcedure
Procedure.i ReleaseOne()
RemoveWindowTimer(win, timer)
UnbindEvent(#PB_Event_Timer, @TimerCB(), win, timer)
ProcedureReturn DeleteFile(LockFile)
EndProcedure
Procedure.s GetParameters()
ProcedureReturn Paras
EndProcedure
Procedure InitOne(wID, OnlyOneName.s, CustomEvent = #PB_Event_FirstCustomValue, TimerID = 1, TimeOut = 2000)
Protected.i FF, i, j, time, result = #False
If Not IsWindow(wID)
Debug "You have to open a window, before you call this function!"
ProcedureReturn #False
EndIf
win = wID
timer = TimerID
Event = CustomEvent
LockFile = GetTemporaryDirectory() + OnlyOneName
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
Protected Mutex = CreateMutex_(0, 0, OnlyOneName)
If GetLastError_() = #ERROR_ALREADY_EXISTS
ReleaseMutex_(Mutex)
CloseHandle_(Mutex)
Else
DeleteFile(LockFile)
EndIf
CompilerDefault
time = AddDate(GetFileDate(LockFile, #PB_Date_Modified), #PB_Date_Minute, 5)
If time < Date()
DeleteFile(LockFile)
EndIf
CompilerEndSelect
If FileSize(LockFile) = -1
FF = CreateFile(#PB_Any, LockFile)
If FF
CloseFile(FF)
AddWindowTimer(wID, TimerID, TimeOut)
BindEvent(#PB_Event_Timer, @TimerCB(), wID, TimerID)
j = CountProgramParameters()
If j
For i = 0 To j
Paras + ProgramParameter(i) + #LF$
Next
Paras = Left(Paras, Len(Paras) - 1)
PostEvent(Event)
EndIf
HideWindow(wID, #False)
result = #True
EndIf
Else
FF = OpenFile(#PB_Any, LockFile, #PB_File_Append)
If FF
j = CountProgramParameters()
If j
For i = 1 To j
Paras + ProgramParameter(i - 1) + #LF$
Next
Paras = Left(Paras, Len(Paras) - 1)
WriteStringN(FF, Paras)
EndIf
CloseFile(FF)
EndIf
End
EndIf
ProcedureReturn result
EndProcedure
EndModule
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
Enumeration #PB_Event_FirstCustomValue
#Event_NewParams
EndEnumeration
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Test", #PB_Window_SystemMenu | #PB_Window_Invisible)
ListViewGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20)
OnlyOne::InitOne(0, "Example_Application", #Event_NewParams)
Define i, j, paras.s
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
OnlyOne::ReleaseOne()
Break
Case #Event_NewParams
SetActiveWindow(0)
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
SetForegroundWindow_(WindowID(0))
CompilerEndIf
paras = OnlyOne::GetParameters()
j = CountString(paras, #LF$)
For i = 1 To j
AddGadgetItem(0, -1, StringField(paras, i, #LF$))
Next
EndSelect
ForEver
CompilerEndIf