Code : Tout sélectionner
#TH32CS_SNAPHEAPLIST = %0001
#TH32CS_SNAPPROCESS = %0010
#TH32CS_SNAPTHREAD = %0100
#TH32CS_SNAPMODULE = %1000
#TH32CS_SNAPALL = %1111
Structure PROCESSENTRY32
dwSize.l
cntUsage.l
th32ProcessID.l
*th32DefaultHeapID.l
th32ModuleID.l
cntThreads.l
th32ParentProcessID.l
pcPriClassBase.l
dwFlags.l
szExeFile.b[#MAX_PATH]
th32MemoryBase.l
th32AccessKey.l
EndStructure
DataSection
Instance_Buffer:
Data.l 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Data.l 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Data.l 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Data.l 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Data.l 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Data.l 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
End_Instance_Buffer:
EndDataSection
Global MainInstance.l
Procedure.l CountProcesses(ExeFile.s)
Protected Count.l, Proc32.PROCESSENTRY32, Temp.s
Protected Kernel32ID.l, PSapiID.l, SnapshotID.l
ExeFile = LCase(ExeFile)
Proc32\dwSize = SizeOf(PROCESSENTRY32)
Kernel32ID = OpenLibrary(#PB_Default, "kernel32.dll")
If Kernel32ID
PSapiID = OpenLibrary(#PB_Default, "psapi.dll")
SnapshotID = CallFunction(Kernel32ID, "CreateToolhelp32Snapshot", #TH32CS_SNAPPROCESS, #Null)
If SnapshotID
If CallFunction(Kernel32ID, "Process32First", SnapshotID, Proc32)
Repeat
If PSapiID
ProcessID = OpenProcess_(#PROCESS_QUERY_INFORMATION|#PROCESS_VM_READ, #False, Proc32\th32ProcessID)
Temp = Space(#MAX_PATH)
CallFunction(PSapiID, "GetModuleFileNameExA", ProcessID, #Null, Temp, #MAX_PATH)
Temp = Trim(Temp)
CloseHandle_(ProcessID)
Else
Temp = PeekS(@Proc32\szExeFile, #MAX_PATH)
EndIf
If LCase(Temp) = ExeFile
If Count = 0
MainInstance = Proc32\th32ProcessID
EndIf
Count + 1
EndIf
Until CallFunction(Kernel32ID, "Process32Next", SnapshotID, Proc32) = #False
EndIf
CloseHandle_(SnapshotID)
EndIf
CloseLibrary(PSapiID)
CloseLibrary(Kernel32ID)
EndIf
ProcedureReturn Count
EndProcedure
Procedure.s GetExeFile()
Protected Location.s
Location = Space(#MAX_PATH)
GetModuleFileName_(#Null, Location, #MAX_PATH)
ProcedureReturn location
EndProcedure
Procedure.l WriteMainInstanceBuffer(Length.l)
Protected Write.l, ProcessID.l
If Length > 0 And Length <= (?End_Instance_Buffer - ?Instance_Buffer)
ProcessID = OpenProcess_(#PROCESS_ALL_ACCESS, #False, MainInstance)
If ProcessID
Write = WriteProcessMemory_(ProcessID, ?Instance_Buffer, ?Instance_Buffer, Length, #Null)
CloseHandle_(ProcessID)
EndIf
EndIf
ProcedureReturn Write
EndProcedure
;-example
;create or get a custom message
Global WM_MYAPPCUSTOMMESSAGE
WM_MYAPPCUSTOMMESSAGE = RegisterWindowMessage_("my_app_custom_message")
;check for existing process
If CountProcesses( GetExeFile() ) > 1
DefType.s param, params
;get all params in a new line
Repeat
param = ProgramParameter()
If params
params + #CRLF$
EndIf
params + param
Until param = #NULL$
If params
;send the string to the buffer
PokeS(?Instance_Buffer, params)
WriteMainInstanceBuffer(Len(params))
;send the custom message
SendMessage_(#HWND_BROADCAST, WM_MYAPPCUSTOMMESSAGE, "GET_PARAMS", Len(params))
Else
;send a 'no param' message
SendMessage_(#HWND_BROADCAST, WM_MYAPPCUSTOMMESSAGE, "NO_PARAMS", 0)
EndIf
;only one instance so just end
End
EndIf
;here starts the "MainInstance" program
;this var is used for small stats ^^
Global nMessages
;procedure where you receive the custom message
Procedure WindowCallback(WindowID.l, Message.l, wParam.l, lParam.l)
If Message = WM_MYAPPCUSTOMMESSAGE
nMessages + 1
CustomMessage.s = PeekS(wParam)
;get the program parameter if any
If CustomMessage = "GET_PARAMS"
Text.s = "Here is a new custom message :" + #CRLF$ + PeekS(?Instance_Buffer, lParam)
ElseIf CustomMessage = "NO_PARAMS"
Text.s = "Here is a 'no param' message !" + #CRLF$
EndIf
;update gadgets' text
Text = GetGadgetText(1) + Text
SetGadgetText(1, Text)
SetGadgetText(0, "Custom messages : " + Str(nMessages))
SetForegroundWindow_( WindowID() )
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
;the only once running program
If OpenWindow(0,0,0,320,280,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Instance") And CreateGadgetList(WindowID())
;gadgets to get the result of the custom message
TextGadget (0,10,10,300, 20,"No custom message received")
StringGadget(1,10,40,300,230,"",#PB_String_MultiLine|#PB_String_ReadOnly)
;without this line, nothing is possible
SetWindowCallback( @WindowCallback() )
Repeat
;enjoy
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf