here´s some code, quickly picked together from my project.
Maybe it helps you to use FileMapping.
Code: Select all
Global FilMapName.s = "MyUnique_MemName"
Global message_copy_id.l
Global MyClipboardMem.l, HandleMap.l, try2close.l
Structure MyStruct
b.l
s.s
Level.l
EndStructure
Global NewList CopyList.MyStruct()
Global NewList ThisList.MyStruct()
Procedure.l AllocateMemoryGlobal(name.s, Size.l); allocate shared memory (name has to be unique)
closeres = CloseHandle_(HandleMap)
;HandleMap = CreateFileMapping_(#INVALID_HANDLE_VALUE, 0, #PAGE_READWRITE, 0, Size, @name);#INVALID_HANDLE_VALUE ;$FFFFFFFF
HandleMap = CreateFileMapping_($FFFFFFFF, 0, 402653188, 0, Size, @name)
LastError = GetLastError_()
If LastError = #ERROR_ALREADY_EXISTS ; =183
i = 0
While closeres = 1
try2close = #True
PostMessage_(#HWND_BROADCAST, message_copy_id, 0, i)
i + 1
Delay(10)
closeres = CloseHandle_(HandleMap);: HandleMap = 0
Wend
HandleMap = CreateFileMapping_($FFFFFFFF, 0, 402653188, 0, Size, @name)
LastError = GetLastError_()
EndIf
If HandleMap
; If LastError = #ERROR_ALREADY_EXISTS ; =183
; Debug "#ERROR_ALREADY_EXISTS !!!!!!!!!!!!"
; EndIf
ProcedureReturn MapViewOfFile_(HandleMap, 983071, 0, 0 ,0);#FILE_MAP_WRITE ;983071
Else
ProcedureReturn 0
EndIf
EndProcedure
Procedure.l Txt2Mem(lpMem, txt$)
Protected tmpLen.l
tmpLen = Len(txt$)
CopyMemory(@tmpLen, lpMem, 4): lpMem + 4
If tmpLen
CopyMemory(@txt$, lpMem, tmpLen)
EndIf
lpMem + tmpLen
ProcedureReturn lpMem
EndProcedure
Procedure CopyListNode(Index.l)
If Not Index = -1
If CountList(ThisList())
SelectElement(ThisList(), Index)
*oldElement = @ThisList()
;ClearList(CopyList())
memLenNode = 0
aktEbene = ThisList()\Level
i=Index:nodes=0
memLenNode + 8 ;first variable will be length of whole memory and second will be number of nodes
Repeat
With ThisList()
memLenNode + 5 ; length in bytes of all longs and doubels etc. (not strings)
memLenNode + Len(\s) ;string nr 1
memLenNode + 1*4 ; for writing the length of the string (one long for each)
EndWith
nodes+1
i+1
Until NextElement(ThisList())=0 Or ThisList()\Level <= aktEbene
ChangeCurrentElement(ThisList(), *oldElement)
; SysInfo.SYSTEM_INFO
; GetSystemInfo_(@SysInfo)
; memLenNode = Round(memLenNode/SysInfo\dwPageSize, 1)*SysInfo\dwPageSize*
MyClipboardMem = AllocateMemoryGlobal(FilMapName, memLenNode*2)
CopyMemory(@memLenNode, MyClipboardMem, 4) ; write first length of memory
*ClipBoardPointer = MyClipboardMem + 4
CopyMemory(@nodes, *ClipBoardPointer, 4) ; then number of nodes
*ClipBoardPointer + 4
Repeat
With ThisList()
CopyMemory(@\b, *ClipBoardPointer, 4): *ClipBoardPointer + 1
*ClipBoardPointer = Txt2Mem(*ClipBoardPointer, \s)
CopyMemory(@\Level, *ClipBoardPointer, 8): *ClipBoardPointer + 4
EndWith
Until NextElement(ThisList())=0 Or ThisList()\Level <= aktEbene
unmapres = UnmapViewOfFile_(MyClipboardMem): MyClipboardMem = 0
ChangeCurrentElement(ThisList(), *oldElement)
Debug "nodes: " + Str(nodes)
PostMessage_(#HWND_BROADCAST, message_copy_id, memLenNode, nodes)
EndIf
EndIf
EndProcedure
Procedure.s GetTxtFromMem(lpSrcMem, *TxtLen)
Protected retTxt$
tmpTxtLen = PeekL(lpSrcMem)
MemOffset = tmpTxtLen+4
CopyMemory(@MemOffset, *TxtLen, 4)
If tmpTxtLen = 0
retTxt$ = ""
Else
retTxt$ = PeekS(lpSrcMem+4, tmpTxtLen)
EndIf
ProcedureReturn retTxt$
EndProcedure
Procedure CopyMem2CopyList(Mem, MemLen, nodes)
*ClipBoardPointer = Mem+8
tmpLen.l=0
i=0
ClearList(CopyList())
For i = 1 To nodes
;Repeat
;While *ClipBoardPointer < EndMem
AddElement(CopyList())
With CopyList()
\b = PeekB(*ClipBoardPointer):*ClipBoardPointer+1
\s = GetTxtFromMem(*ClipBoardPointer, @tmpLen):*ClipBoardPointer+tmpLen
\Level = PeekL(*ClipBoardPointer):*ClipBoardPointer+4
EndWith
;Wend
;Until *ClipBoardPointer >= EndMem
Next
EndProcedure
Procedure Proc_Copy(wParam, lParam)
;#####################################################################################################
;# with OpenFileMapping we can not recognize if the mapped file is from this instance or another one #
;#####################################################################################################
; ThisHandleMap = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, #False, FilMapName)
; If HandleMap
; MyClipboardMem = MapViewOfFile_(ThisHandleMap, #FILE_MAP_READ, 0, 0, *sender\wParam)
; CopyMem2CopyList(MyClipboardMem, *sender\wParam, *sender\lParam)
; unmapres = UnmapViewOfFile_(MyClipboardMem)
; closeres = CloseHandle_(HandleMap)
; closeres = CloseHandle_(ThisHandleMap)
; EndIf
If wParam = 0 And lParam = 0 And try2close = #False
;Debug "am here at Proc_Copy to close mapped file handle"
; if try2close = #true -> trying to close from this instance
; after MyClipboardMem is filled, but not read
; cause the posted message (message_copy_id) from this instance is
; receieved not before MyClipboardMem is filled,
; but before MyClipboardMem is read
; -> we don´t close the Mapped-File-Handle before try2close = #False
; we are here at Proc_Copy to close mapped file handle
; cause another instance has asked for starting to copy
; and does need free filemapping
unmapres = UnmapViewOfFile_(MyClipboardMem): MyClipboardMem = 0
closeres = CloseHandle_(HandleMap)
HandleMap = 0
ClearList(CopyList())
ProcedureReturn
ElseIf wParam = 0 And lParam
;Debug "am here at Proc_Copy for Nothing"
; *sender\lParam > 0 -> message_copy_id already posted so don´t close any more
ProcedureReturn
EndIf
;Debug "am here at Proc_Copy to copy"
;now we copy MyClipboardMem to the CopyList if the mapped file ALREADY EXISTS
If Not HandleMap
HandleMap = CreateFileMapping_($FFFFFFFF, 0, 402653188, 0, wParam, @FilMapName)
LastError = GetLastError_()
If HandleMap
If LastError = #ERROR_ALREADY_EXISTS ; =183
;Debug "created MyClipboardMem from other proc"
; -> we have MyClipboardMem from other proc cause LastError = #ERROR_ALREADY_EXISTS and HandleMap = 0
MyClipboardMem = MapViewOfFile_(HandleMap, 983071, 0, 0 ,0);#FILE_MAP_WRITE ;983071
;otherProc.b = #True
EndIf
Else
;Debug "no HandleMap from CreateFileMapping"
closeres = CloseHandle_(HandleMap)
HandleMap = 0
EndIf
Else
;Debug "created MyClipboardMem from THIS proc"
; we have MyClipboardMem from This proc cause HandleMap already exists
MyClipboardMem = MapViewOfFile_(HandleMap, 983071, 0, 0 ,0);#FILE_MAP_WRITE ;983071
;otherProc.b = #False
EndIf
;Debug "MyClipboardMem in Proc_Copy: " + Str(MyClipboardMem)
If MyClipboardMem
CopyMem2CopyList(MyClipboardMem, wParam, lParam)
unmapres = UnmapViewOfFile_(MyClipboardMem)
;Debug "unmapres: " + Str(unmapres) + " ###############"
MyClipboardMem = 0
try2close = #False ; MyClipboardMem is read so we can try to close mapped file next time we are asked to
EndIf
EndProcedure
Procedure InsertListNode(Index.l)
Protected tmpText$
If CountList(ThisList())
SelectElement(ThisList(), Index)
i=Index
ForEach CopyList()
AddElement(ThisList())
With ThisList()
\b = CopyList()\b
\s = CopyList()\s
\Level = CopyList()\Level
EndWith
i+1
AddGadgetItem(0, i, ThisList()\s, 0, ThisList()\Level)
Next
EndIf ;If CountList(ThisList())
EndProcedure
Procedure MyWindowCallback(WindowID, message, wParam, lParam)
result = #PB_ProcessPureBasicEvents
Select message
Case message_copy_id
Proc_Copy(wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
Procedure AddTreeData(any.b, txt$, SubLevel.l)
AddGadgetItem (0, -1, txt$, 0, SubLevel)
AddElement(ThisList()): ThisList()\b=any: ThisList()\s=txt$: ThisList()\Level=SubLevel
EndProcedure
If OpenWindow(0, 0, 0, 355, 180, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
; lets look if there is any copy-data from an earlier running instance
; mapped in memory and if, take it and free (unmap) the mapped memory
HandleMap = CreateFileMapping_($FFFFFFFF, 0, 402653188, 0, 16, @FilMapName)
If HandleMap
LastError = GetLastError_()
If LastError = #ERROR_ALREADY_EXISTS
MyClipboardMem = MapViewOfFile_(HandleMap, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
MemLen = PeekL(MyClipboardMem)
nodes = PeekL(MyClipboardMem+4)
CopyMem2CopyList(MyClipboardMem, MemLen, nodes)
UnmapViewOfFile_(MyClipboardMem): MyClipboardMem = 0
EndIf
EndIf
SetWindowCallback(@MyWindowCallback(), 0)
TreeGadget(0, 10, 10, 160, 160)
For a = 0 To 10
AddTreeData(a, "Normal Item "+Str(a), 0)
AddTreeData(a, "Node "+Str(a), 0)
AddTreeData(a, "Sub-Item 1", 1)
AddTreeData(a, "Sub-Item 2", 1)
AddTreeData(a, "Sub-Item 3", 1)
AddTreeData(a, "Sub-Item 4", 1)
AddTreeData(a, "File "+Str(a), 0)
Next
ButtonGadget(1, 180, 10, 160, 20, "Copy")
ButtonGadget(2, 180, 40, 160, 20, "Paste")
message_copy_id = RegisterWindowMessage_("MyCopyMessage")
Repeat
Event = WaitWindowEvent()
WindowID = EventWindow()
GadgetID = EventGadget()
GadgetEvent = EventType()
Select Event
Case #PB_Event_Gadget
Select GadgetID
Case 1
CopyListNode(GetGadgetState(0))
Case 2
InsertListNode(GetGadgetState(0))
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
EndIf