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