Jump to content

Drag and Drop with Explorer


Recommended Posts

  • 3 years later...

DoDragDropGUI.au3

#include"DoDragDrop.au3"
#include<ClipBoard.au3>
#include<WindowsConstants.au3>

Global Const $DROPFILES = "DWORD pFiles; int pt[2]; int fNC; int fWide;"

;===============================================================================
;
; Function Name:   _CreateHDROP_FORMATETC()
; Description::    Creates a FORMATETC-structure with the needed values to do a HDROP (Drag Files like explorer)
; Parameter(s):    none
; Requirement(s):  COM/OLE UDF
; Return Value(s): FORMATETC DLL-structure
; Author(s):       prog@ndy
;
;===============================================================================
;
Func _CreateHDROP_FORMATETC()
    Local $FMTETC = DllStructCreate($tagFORMATETC)
        DllStructSetData($FMTETC,1,$CF_HDROP)
        DllStructSetData($FMTETC,2,0)
        DllStructSetData($FMTETC,3,$DVASPECT_CONTENT)
        DllStructSetData($FMTETC,4,-1)
        DllStructSetData($FMTETC,5,$TYMED_HGLOBAL)
    Return $FMTETC
EndFunc

;===============================================================================
;
; Function Name:   _CreateDROPFILES
; Description::    Creates a DROPFILES-structure
; Parameter(s):    $Files - Pipe-separated list of files to copy: example: C:\File1.bin|D:\AnotherFile.dat
; Requirement(s):  COM/OLE UDF
; Return Value(s): HGLOBAL-Pointer to a DROPFILES structure
; Author(s):       prog@ndy
;
;===============================================================================
;
Func _CreateDROPFILES($Files)
    $Files = String($Files)

    $hMem = _MemGlobalAlloc(_DragDrop_SIZEOF($DROPFILES) + ((StringLen($Files)+2)*2),$GPTR)
    $Files = StringSplit($Files,"|")
    $stDROPFILES = DllStructCreate($DROPFILES,$hMem)
    $hPtr = $hMem + DllStructGetSize($stDROPFILES)
    DllStructSetData($stDROPFILES, "fWide", 1)
    DllStructSetData($stDROPFILES, 1, DllStructGetSize($stDROPFILES))
    For $i = 1 To $Files[0]
        $next = DllStructCreate("wchar[" & StringLen($Files[$i])+1 & "]", $hPtr)
        DllStructSetData($next,1,$Files[$i] & ChrW(0))
        $hPtr += (StringLen($Files[$i])+1)*2
    Next
    $next = DllStructCreate("wchar[1]", $hPtr)
    DllStructSetData($next,1,ChrW(0))
    Return $hMem
EndFunc

;===============================================================================
;
; Function Name:   _CreateDROPFILES_STGMEDIUM
; Description::    Creates a STGMEDIUM with a DROPFILES-structure
; Parameter(s):    $Files - Pipe-separated list of files to copy: example: C:\File1.bin|D:\AnotherFile.dat
; Requirement(s):  COM/OLE UDF
; Return Value(s): STGMEDIUM-DLLStruct
; Author(s):       prog@ndy
;
;===============================================================================
;
Func _CreateDROPFILES_STGMEDIUM($Files)
    Local $STGMD = DllStructCreate($tagSTGMEDIUM)
    DllStructSetData($STGMD,1,$TYMED_HGLOBAL)
    Local $DF = _CreateDROPFILES($Files)
    If Not $DF Then Return SetError(1,0,0)
    DllStructSetData($STGMD,2,$DF)
    Return $STGMD
EndFunc


#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>

Global $hDragDropGUI ,$iListView,  $_GLOB_fDragInitiated=False

; do on Startup
    _OLEInitialize()
    ; init DropSource Handler
    Global $objIDropSource = _CreateIDropSource()
Global Const $DI_GETDRAGIMAGE = "ShellGetDragImage"
Global Const $WM_DI_GETDRAGIMAGE = _WinAPI_RegisterWindowMessage($DI_GETDRAGIMAGE)

Global Const $CFSTR_PERFORMEDDROPEFFECT = "Performed DropEffect"
Global Const $CF_PERFORMEDDROPEFFECT = _WinAPI_RegisterWindowMessage($CFSTR_PERFORMEDDROPEFFECT)

Global Const $tagSHDRAGIMAGE = "long sizeDragImage[2];long ptOffset[2]; ptr hbmpDragImage; dword crColorKey;"

Global $CLSID_DragDropHelper = _GUID("4657278A-411B-11D2-839A-00C04FD918D0")
Global $IID_IDragSourceHelper = _GUID("DE5BF786-477A-11D2-839D00C04FD918D0")
Global $IID_IDropTargetHelper =  _GUID("4657278B-411B-11D2-839A00C04FD918D0")
Global $IDragSourceHelper_vTable = $IUnknown_vTable & "ptr InitializeFromBitmap; ptr InitializeFromWindow;"



Func _SetBMP(ByRef $IDragSourceHelper, ByRef $IDataObject)
    Local $SHDRAGIMAGE = DllStructCreate($tagSHDRAGIMAGE)
;~  Local $deskDC = _WinAPI_GetDC(_WinAPI_GetDesktopWindow())
;~  Local $hBMP = _WinAPI_CreateCompatibleBitmap($deskDC,96,96)
;~  _WinAPI_ReleaseDC(_WinAPI_GetDesktopWindow(),$deskDC)
    Local $hBMP = _WinAPI_LoadImage(0,"C:\Windows\Feder.bmp",0,0,0,$LR_LOADFROMFILE)
    DllStructSetData($SHDRAGIMAGE,"hbmpDragImage",$hBMP)
    DllStructSetData($SHDRAGIMAGE,"sizeDragImage",96,1)
    DllStructSetData($SHDRAGIMAGE,"sizeDragImage",96,2)
    DllStructSetData($SHDRAGIMAGE,"ptOffset",45,1)
    DllStructSetData($SHDRAGIMAGE,"ptOffset",69,2)
    DllStructSetData($SHDRAGIMAGE,"crColorKey",0x00FF00FF)
    _ObjFuncCall($HRESULT, $IDragSourceHelper, "InitializeFromBitmap", "ptr", DllStructGetPtr($SHDRAGIMAGE), "ptr", _ObjGetObjPtr($IDataObject))
EndFunc


_Main()

; Author: Prog@ndy
Func _MemGlobalGetValue($hMem, $DataType, $Offset=0)
    If _MemGlobalSize($hMem) < __MemArray_SIZEOF($DataType) Then Return SetError(1,0,0)
    Local $hPtr = _MemGlobalLock($hMem)
    If Not $hPtr Then Return SetError(2,0,0)
    Local $Data = DllStructGetData(DllStructCreate($DataType,$hPtr+$Offset),1)
    If @error Then Return SetError(1,_MemGlobalUnlock($hMem))
    _MemGlobalUnlock($hMem)
    Return $Data
EndFunc

Func OnAutoItExit()
    ; release the DropSource Handler
    _ReleaseIDropSource($objIDropSource)
    _OLEUnInitialize()
EndFunc

Func MY_GETDRAGIMAGE($hWnd, $Msg, $wParam, $lParam)
    Local $SHDRAGIMAGE = DllStructCreate($tagSHDRAGIMAGE,$lParam)
;~  Local $deskDC = _WinAPI_GetDC(_WinAPI_GetDesktopWindow())
;~  Local $hBMP = _WinAPI_CreateCompatibleBitmap($deskDC,96,96)
;~  _WinAPI_ReleaseDC(_WinAPI_GetDesktopWindow(),$deskDC)
    Local $hBMP = _WinAPI_LoadImage(0,"C:\Windows\Feder.bmp",0,0,0,$LR_LOADFROMFILE)
    DllStructSetData($SHDRAGIMAGE,"hbmpDragImage",$hBMP)
    DllStructSetData($SHDRAGIMAGE,"sizeDragImage",128,1)
    DllStructSetData($SHDRAGIMAGE,"sizeDragImage",128,2)
    DllStructSetData($SHDRAGIMAGE,"ptOffset",45,1)
    DllStructSetData($SHDRAGIMAGE,"ptOffset",69,2)
    DllStructSetData($SHDRAGIMAGE,"crColorKey",0x00FF00FF)

    Return True
EndFunc

Func _Main()

    Local $hGUI, $hItemChild, $hImage, $iImage, $hItem, $hListView, $btnDelete, $btnExit

    $hGUI = GUICreate("DragDrop Example", 400, 450,-1,-1,Default,0)
    GUICtrlCreateLabel("Drag files to the ListView and drop them" & @CRLF &" ... ... or the other way round ;)", 10,10,380,60)
    GUICtrlSetFont(-1,14,600)
    $hDragDropGUI = GUICreate("DropOnlyHere",380,300,10,80,$WS_CHILD,BitOR($WS_EX_ACCEPTFILES,$WS_EX_CONTROLPARENT),$hGUI)
        ; This Child-GUI is a work-around, so you can only drop files in this area
        $iListView = GUICtrlCreateListView("Dropped files",0,0,380,300,$LVS_SHOWSELALWAYS)
        $hListView = GUICtrlGetHandle($iListView)
        _GUICtrlListView_SetColumnWidth($hListView,0,$LVSCW_AUTOSIZE_USEHEADER)
        GUISetState()
    GUISwitch($hGUI)
    $btnDelete = GUICtrlCreateButton("Remove selected items from list",10,400,200,40)
    $btnExit = GUICtrlCreateButton("Exit",330,400,60,40)
;~      Const $WM_DROPFILES = 0x233
        GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES")
        GUIRegisterMsg($WM_NOTIFY, "MY_NOTIFY")
        GUIRegisterMsg($WM_DI_GETDRAGIMAGE, "MY_GETDRAGIMAGE")
    GUISetState()

    Global $IDragSourceHelper = _ObjCoCreateInstance($CLSID_DragDropHelper,$IID_IDragSourceHelper,$IDragSourceHelper_vTable)

    ; Loop until user exits
    While 1

        If $_GLOB_fDragInitiated Then
            $_GLOB_fDragInitiated = False

            ; Array needed for FORMATETC
            Local $FMTETCs[1] = [_CreateHDROP_FORMATETC()]

            ; get the Filenames to a pipe separated list.
            Local $Items = _GUICtrlListView_GetSelectedIndices($iListView,True)
            Local $Files = ""
            For $i = 1 To $Items[0]
                $Files &= _GUICtrlListView_GetItemText($iListView,$Items[$i]) & "|"
            Next
            $Files = StringTrimRight($Files,1)

            ; Array needed for STGMEDIUM
            Local $STGMDs[1] = [_CreateDROPFILES_STGMEDIUM($Files)]

            ; Create the Object with FORMATETC and STGMEDIUM (Attention: if you use multiple ones, the corresponding FMTETC and STGMD must be at the same position in the Array)
            $objIDataSource = _CreateIDataObject($FMTETCs,$STGMDs)
            If Not _ObjGetObjPtr($objIDataSource) Then ; Just continue, if the creation has failed
                _ReleaseStgMedium($STGMDs[0]) ; but first delete the created STGMedium
                ContinueLoop
            EndIf
                _SetBMP($IDragSourceHelper,$objIDataSource)
;~              Local $ptr = _IUnknown_QueryInterface($objIDataSource, $IID_IDataObject)
;~              $ptr = _ObjCreateFromPtr($ptr,$IDataObject_vTable)

;~              $result = _ObjFuncCall($HRESULT, $IDragSourceHelper, "InitializeFromWindow", "ptr", $hGUI, "ptr", 0, "ptr", _ObjGetObjPtr($ptr ))
            ; Perform the DragDrop operation
            Local $Effect
            Local $result = _DoDragDrop($objIDataSource, $objIDropSource,  BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), $Effect)
;~          Local $result = _SHDoDragDrop($hGUI, $objIDataSource, $objIDropSource,  BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), $Effect)
            ; check the result
            If $result = $DRAGDROP_S_DROP Then

                $Effect = _GetUnoptimizedEffect($objIDataSource, $Effect)

                Switch $Effect
                    Case $DROPEFFECT_MOVE ; items moved
                        ; Delete the items that were moved
                        For $i = $Items[0] To 1 Step -1
                            $File = _GUICtrlListView_GetItemText($hListView,$Items[$i])
                            If Not FileExists($File) Then
                                _GUICtrlListView_DeleteItem($hListView,$Items[$i])
                            EndIf
                        Next
                        MsgBox(0, '', "Move")
                    Case $DROPEFFECT_COPY ; items copied
                        MsgBox(0, '', "Copy")
                    Case $DROPEFFECT_LINK ; links created
                        MsgBox(0, '', "Link")
                    Case $DROPEFFECT_NONE ; on Win 9x nothing, but NT/2000 and above have MOVE-operaion here, too
                        ; on NT/200 and above, a move-action will also return DROPEFFECT_NONE. So you have to check that manually:
                        Local $deletedAnything=False
                        If @OSType = "WIN32_NT" Then ; just for the "new" NT-Systems

                            Local $File
                            For $i = $Items[0] To 1 Step -1
                                $File = _GUICtrlListView_GetItemText($hListView,$Items[$i])
                                If Not FileExists($File) Then ; if the file has been moved,...
                                    _GUICtrlListView_DeleteItem($hListView,$Items[$i]) ; delete it from LV
                                    $deletedAnything = True ; set the deleted flag to TRUE
                                EndIf
                            Next
                            If $deletedAnything Then MsgBox(0, '', "Workaround detect: Move") ; if something was deleted --> MOVE
                        EndIf
                        If $deletedAnything = False Then
                            MsgBox(0, '', "Nothing Done")
                        EndIf
                EndSwitch
            ElseIf $result = $DRAGDROP_S_CANCEL Then
                MsgBox(0, '', "DoDragDrop cancelled")
            Else
                MsgBox(0, '', "Error on DoDragDrop")
            EndIf

            _ReleaseIDataObject($objIDataSource) ; release the DataObject
            ; DO NOT RELEASE THE STGMEDIUM, since it belongs to the IDataObject

        EndIf ; $_GLOB_fDragInitiated

        Switch GUIGetMsg()

            Case $GUI_EVENT_CLOSE, $btnExit
                ExitLoop
            Case $btnDelete
                _GUICtrlListView_DeleteItemsSelected($hListView)
        EndSwitch
    WEnd

    _IUnknown_Release($IDragSourceHelper)
    GUIDelete()
EndFunc   ;==>_Main

; Prog@ndy
Func _GetUnoptimizedEffect(ByRef $objIDataSource, $Effect)
    Local $FormatEtc = _CreateHDROP_FORMATETC()
    DllStructSetData($FormatEtc,1,$CF_PERFORMEDDROPEFFECT)
    Local $result = _ObjFuncCall($HRESULT, $objIDataSource, "QueryGetData",  "ptr", DllStructGetPtr($FormatEtc))
    If $S_OK = $result[0] Then
        Local $StgMedium = DllStructCreate($tagSTGMEDIUM)
        $result = _ObjFuncCall($HRESULT, $objIDataSource, "GetData",  "ptr", DllStructGetPtr($FormatEtc), "ptr", DllStructGetPtr($StgMedium))
        If $S_OK = $result[0] Then
            $Effect = _MemGlobalGetValue(DllStructGetData($StgMedium,"hGlobal"),"dword")
        EndIf
        _ReleaseStgMedium($StgMedium)
    EndIf
    Return $Effect
EndFunc


Func _SHDoDragDrop($hWnd, ByRef $objIDataSource, ByRef $objIDropSource, $dwDropEffects, ByRef $dwPerformedEffect)
    Local $result = DllCall("shell32.dll",$HRESULT,"SHDoDragDrop", "hwnd", $hWnd, "ptr", _ObjGetObjPtr($objIDataSource),"ptr", _ObjGetObjPtr($objIDropSource), "dword", BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), "dword*", 0)
    $dwPerformedEffect = $result[5]
    Return $result[0]
EndFunc



Func MY_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    If $hWnd = $hDragDropGUI And $wParam=$iListView Then
        Local $NMHDR = DllStructCreate($tagNMHDR,$lParam)

        Switch DllStructGetData($NMHDR,"Code")
            Case $LVN_BEGINDRAG
                $_GLOB_fDragInitiated = True
                Return False
        EndSwitch
    EndIf

EndFunc

; copied from http://www.autoitscript.com/forum/index.php?s=&showtopic=60308&view=findpost&p=453731
; modified by Prog@ndy
Func WM_DROPFILES($hWnd, $uMsg, $wParam, $lParam)
    Local $tDrop, $aRet, $iCount, $iSize
;string buffer for file path

;get file count
    $aRet = DllCall("shell32.dll", "int", "DragQueryFileW", "ptr", $wParam, "uint", 0xFFFFFFFF, "ptr", 0, "uint", 0)
    $iCount = $aRet[0]
;get file paths
    Local $CurInfo = GUIGetCursorInfo($hDragDropGUI)
    If IsArray($CurInfo) And $CurInfo[4] = $iListView Then
        For $i = 0 To $iCount-1
            $iSize = DllCall("shell32.dll", "uint", "DragQueryFileW","ptr", $wParam,"uint", $i,"ptr", 0,"uint", 0)
            $tDrop = DllStructCreate("wchar[" & $iSize[0]+1 & "]")
            $aRet = DllCall("shell32.dll", "uint", "DragQueryFileW","ptr", $wParam,"uint", $i,"ptr", DllStructGetPtr($tDrop),"uint", $iSize[0]+1)
        ;ConsoleWrite(DllStructGetData($tDrop, 1) & @CRLF)
            If _GUICtrlListView_FindText($iListView,DllStructGetData($tDrop, 1),-1,False) = -1 Then  _GUICtrlListView_AddItem($iListView,DllStructGetData($tDrop, 1))
        Next
    EndIf
;finalize
    DllCall("shell32.dll", "int", "DragFinish", "ptr", $wParam)
    Return
EndFunc

 

DoDragDrop.au3

#include <memory.au3>
#include <Misc.au3>
#include <WinAPIConstants.au3>
#include "MemArray.au3"
#include "objbase.au3"
#include <Misc.au3>

;+------------------------------------------------------------------------+
;|                                                                        |
;| UDF for OLE-DragDrop                                                   |
;| Author: Prog@ndy                                                       |
;|                                                                        |
;+------------------------------------------------------------------------+

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;!!                                                                      !!
;!! VARIABLES AND FUNCTIONS WITH DOUBLE UNDERSCORE ARE INTERNAL USE ONLY !!
;!!                                                                      !!
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Global Const $MK_LBUTTON = 1

Global Const $DRAGDROP_S_DROP = 0x40100
Global Const $DRAGDROP_S_CANCEL = 0x40101
Global Const $DRAGDROP_S_FIRST = 0x40100
Global Const $DRAGDROP_S_LAST = 0x4010F
Global Const $DRAGDROP_S_USEDEFAULTCURSORS = 0x40102
Global Const $DRAGDROP_E_NOTREGISTERED = 0x80040100
Global Const $DRAGDROP_E_INVALIDHWND = 0x80040102
Global Const $DRAGDROP_E_LAST = 0x8004010F
Global Const $DRAGDROP_E_FIRST = 0x80040100
Global Const $DRAGDROP_E_ALREADYREGISTERED = 0x80040101
Global Const $DRAGLISTMSGSTRING = "commctrl_DragListMsg"
;~ typedef enum tagDROPEFFECT
;~ {
Global Const $DROPEFFECT_NONE = 0
Global Const $DROPEFFECT_COPY = 1
Global Const $DROPEFFECT_MOVE = 2
Global Const $DROPEFFECT_LINK = 4
Global Const $DROPEFFECT_SCROLL = 0x80000000
;~ }

Global $IID_IDropTarget = _GUID("{00000122-0000-0000-C000-000000000046}")

; -- #Region IDropSource -------------------------------------------------------------
#Region IDropSource

Global Const $IDropSource_vTable = $IUnknown_vTable & "ptr QueryContinueDrag; ptr GiveFeedback;"
Global Const $tagIDropSource = "ptr vTable; dword dwRefCount;"

Global $IID_IDropSource = _GUID("{00000121-0000-0000-C000-000000000046}")



Global Const $__IDropSource_vTable = DllStructCreate($IDropSource_vTable)

Func _CreateIDropSource()
    Local $hMem = _MemGlobalAlloc(_DragDrop_SIZEOF($tagIDropSource),$GPTR)
    Local $IDropSource[3] = [$hMem, DllStructCreate($tagIDropSource,$hMem), $__IDropSource_vTable]
    DllStructSetData($IDropSource[1], 1, DllStructGetPtr($__IDropSource_vTable))
    __IDropSource_AddRef($hMem)
    Return $IDropSource
EndFunc

Func _ReleaseIDropSource(ByRef $IDropSource)
    Local $res = _ObjFuncCall("ulong",$IDropSource,"Release")
    If @error Then Return SetError(1,0,-1)
    If $res[0] = 0 Then
        $IDropSource = 0
    EndIf
    Return $res[0]
EndFunc

Global Const $__IDropSource_QueryInterface = DllCallbackRegister("__IDropSource_QueryInterface", $HRESULT, "ptr;ptr;ptr")
DllStructSetData($__IDropSource_vTable, "QueryInterface", DllCallbackGetPtr($__IDropSource_QueryInterface))

Global Const $__IDropSource_AddRef = DllCallbackRegister("__IDropSource_AddRef", $HRESULT, "ptr")
DllStructSetData($__IDropSource_vTable, "AddRef", DllCallbackGetPtr($__IDropSource_AddRef))

Global Const $__IDropSource_Release = DllCallbackRegister("__IDropSource_Release", $HRESULT, "ptr")
DllStructSetData($__IDropSource_vTable, "Release", DllCallbackGetPtr($__IDropSource_Release))

Global Const $__IDropSource_QueryContinueDrag = DllCallbackRegister("__IDropSource_QueryContinueDrag", $HRESULT, "ptr;int;dword")
DllStructSetData($__IDropSource_vTable, "QueryContinueDrag", DllCallbackGetPtr($__IDropSource_QueryContinueDrag))

Global Const $__IDropSource_GiveFeedback = DllCallbackRegister("__IDropSource_GiveFeedback", $HRESULT, "ptr;dword")
DllStructSetData($__IDropSource_vTable, "GiveFeedback", DllCallbackGetPtr($__IDropSource_GiveFeedback))


Func __IDropSource_QueryInterface($pObject, $iid, $ppvObject)
    If $ppvObject = 0 Or $iid = 0 Then Return $E_NOINTERFACE
    Local $stIID = DllStructCreate($tagIID, $iid), $pvObject = DllStructCreate("ptr", $ppvObject)
    If _GUID_Compare($stIID, $IID_IDropSource) Or _GUID_Compare($stIID, $IID_IUnknown) Then
        DllStructSetData($pvObject, 1, $pObject)
        __IDropSource_AddRef($pObject)
        Return $S_OK
    EndIf
    DllStructSetData($pvObject,1, 0)
    Return $E_NOINTERFACE
EndFunc   ;==>__IDropSource_QueryInterface

Func __IDropSource_AddRef($pObject)
    Local $st = DllStructCreate("ptr;dword", $pObject)
    Local $iCount = DllStructGetData($st, 2) + 1
    DllStructSetData($st, 2, $iCount)
    Return $iCount
EndFunc   ;==>__IDropSource_AddRef

Func __IDropSource_Release($pObject)
    Local $st = DllStructCreate("ptr;dword", $pObject)
    Local $iCount = DllStructGetData($st, 2) - 1
    If $iCount < 0 Then Return 0
    DllStructSetData($st,2,$iCount)
    Return $iCount
EndFunc   ;==>__IDropSource_Release

Func __IDropSource_QueryContinueDrag($pObject, $fEscapePressed, $grfKeyState)
    Select
        Case $fEscapePressed <> 0
            Return $DRAGDROP_S_CANCEL
        Case Not BitAND($grfKeyState, $MK_LBUTTON)
            Return $DRAGDROP_S_DROP
        Case Else
            Return $S_OK
    EndSelect
EndFunc   ;==>__IDropSource_QueryContinueDrag

Func __IDropSource_GiveFeedback($pObject, $dwEffect)
    Select
        Case $dwEffect = $DROPEFFECT_NONE

        Case BitAND($dwEffect, $DROPEFFECT_LINK) = $DROPEFFECT_LINK

        Case BitAND($dwEffect, $DROPEFFECT_MOVE) = $DROPEFFECT_MOVE

        Case BitAND($dwEffect, $DROPEFFECT_COPY) = $DROPEFFECT_COPY

        Case BitAND($dwEffect, $DROPEFFECT_SCROLL) = $DROPEFFECT_SCROLL

        Case Else
            Return $E_INVALIDARG
    EndSelect
    Return $DRAGDROP_S_USEDEFAULTCURSORS
EndFunc   ;==>__IDropSource_GiveFeedback

#EndRegion
; -- #EndRegion IDropSource -------------------------------------------------------------

; -- #Region IDataObject -------------------------------------------------------------
#Region IDataObject

Global Const $tagFORMATETC = "dword cfFormat; ptr ptd; DWORD  dwAspect; LONG lindex; DWORD tymed;"
Global Const $tagSTGMEDIUM = "DWORD tymed; ptr hGlobal; ptr pUnkForRelease;"
Global Const $sizeFORMATETC = _DragDrop_SIZEOF($tagFORMATETC)
Global Const $sizeSTGMEDIUM = _DragDrop_SIZEOF($tagSTGMEDIUM)

Global Const $tagDVTARGETDEVICE = "DWORD tdSize; USHORT  tdDriverNameOffset; USHORT  tdDeviceNameOffset; USHORT  tdPortNameOffset; USHORT  tdExtDevmodeOffset; BYTE  tdData[1];"


Global Const $tagIDataObject = "ptr vTable; dword dwRefCount; dword Count; ptr pFORMATETC; ptr pSTGMEDIUM;"
    Global Const $TYMED_HGLOBAL     = 1
    Global Const $TYMED_FILE        = 2
    Global Const $TYMED_ISTREAM     = 4
    Global Const $TYMED_ISTORAGE    = 8
    Global Const $TYMED_GDI         = 16
    Global Const $TYMED_MFPICT      = 32
    Global Const $TYMED_ENHMF       = 64
    Global Const $TYMED_NULL        = 0
    Global Const $DVASPECT_CONTENT    = 1
    Global Const $DVASPECT_THUMBNAIL  = 2
    Global Const $DVASPECT_ICON       = 4
    Global Const $DVASPECT_DOCPRINT   = 8
    Global Const $DATADIR_GET = 1
    Global Const $DATADIR_SET = 2



Global $IID_IDataObject = _GUID("{0000010E-0000-0000-C000-000000000046}")

Global Const $DV_E_FORMATETC = 0x80040064
Global Const $DATA_E_FORMATETC = $DV_E_FORMATETC
Global Const $DV_E_TYMED = 0x80040069
Global Const $OLE_S_USEREG = 0x00040000

Global Const $IDataObject_vTable = $IUnknown_vTable & _
                        "ptr GetData; ptr GetDataHere; ptr QueryGetData; ptr GetCanonicalFormatEtc; " & _
                        "ptr SetData; ptr EnumFormatEtc; ptr DAdvise; ptr DUnadvise; ptr EnumDAdvise; "

Global Const $__IDataObj_QueryInterface = DllCallbackRegister( "__IDataObj_QueryInterface", $HRESULT, "ptr;ptr;ptr")
Global Const $__IDataObj_AddRef = DllCallbackRegister( "__IDataObj_AddRef", "ULONG", "ptr")
Global Const $__IDataObj_Release = DllCallbackRegister( "__IDataObj_Release", "ULONG", "ptr")

Global Const $__IDataObj_GetData = DllCallbackRegister( "__IDataObj_GetData", $HRESULT, "ptr;ptr;ptr")
Global Const $__IDataObj_GetDataHere = DllCallbackRegister( "__IDataObj_GetDataHere", $HRESULT, "ptr;ptr;ptr")
Global Const $__IDataObj_QueryGetData = DllCallbackRegister( "__IDataObj_QueryGetData", $HRESULT, "ptr;ptr")
Global Const $__IDataObj_GetCanonicalFormatEtc = DllCallbackRegister( "__IDataObj_GetCanonicalFormatEtc", $HRESULT, "ptr;ptr;ptr")
Global Const $__IDataObj_SetData  = DllCallbackRegister( "__IDataObj_SetData", $HRESULT, "ptr;ptr;ptr;int")
Global Const $__IDataObj_EnumFormatEtc = DllCallbackRegister( "__IDataObj_EnumFormatEtc", $HRESULT, "ptr;dword;ptr")
Global Const $__IDataObj_DAdvise = DllCallbackRegister( "__IDataObj_DAdvise", $HRESULT, "ptr;ptr;DWORD;ptr;ptr")
Global Const $__IDataObj_DUnadvise = DllCallbackRegister( "__IDataObj_DUnadvise", $HRESULT, "ptr;dword")
Global Const $__IDataObj_EnumDAdvise = DllCallbackRegister( "__IDataObj_EnumDAdvise", $HRESULT, "ptr;ptr")

Global Const $__IDataObj_vTable = DllStructCreate($IDataObject_vTable)
DllStructSetData($__IDataObj_vTable, "QueryInterface", DllCallbackGetPtr($__IDataObj_QueryInterface))
DllStructSetData($__IDataObj_vTable, "AddRef", DllCallbackGetPtr($__IDataObj_AddRef))
DllStructSetData($__IDataObj_vTable, "Release", DllCallbackGetPtr($__IDataObj_Release))

DllStructSetData($__IDataObj_vTable, "GetData", DllCallbackGetPtr($__IDataObj_GetData))
DllStructSetData($__IDataObj_vTable, "GetDataHere", DllCallbackGetPtr($__IDataObj_GetDataHere))
DllStructSetData($__IDataObj_vTable, "QueryGetData", DllCallbackGetPtr($__IDataObj_QueryGetData))
DllStructSetData($__IDataObj_vTable, "GetCanonicalFormatEtc", DllCallbackGetPtr($__IDataObj_GetCanonicalFormatEtc))
DllStructSetData($__IDataObj_vTable, "SetData", DllCallbackGetPtr($__IDataObj_SetData))
DllStructSetData($__IDataObj_vTable, "EnumFormatEtc", DllCallbackGetPtr($__IDataObj_EnumFormatEtc))
DllStructSetData($__IDataObj_vTable, "DAdvise", DllCallbackGetPtr($__IDataObj_DAdvise))
DllStructSetData($__IDataObj_vTable, "DUnadvise", DllCallbackGetPtr($__IDataObj_DUnadvise))
DllStructSetData($__IDataObj_vTable, "EnumDAdvise", DllCallbackGetPtr($__IDataObj_EnumDAdvise))

; Author: Prog@ndy
Func __IDataObj_QueryInterface($pObject, $iid, $ppvObject)
    Local $stIID = DllStructCreate($tagIID, $iid), $pvObject = DllStructCreate("ptr", $ppvObject)
;~  ConsoleWrite(_WinAPI_StringFromGUID($iid) & @CRLF)
    If _GUID_Compare($stIID, $IID_IDataObject) Or _GUID_Compare($stIID, $IID_IUnknown) Then
        __IDataObj_AddRef($pObject)
        DllStructSetData($pvObject,1, $pObject)
        Return $S_OK
    EndIf
    DllStructSetData($pvObject,1, 0)
    Return $E_NOINTERFACE
EndFunc   ;==>__IDataObj_QueryInterface

; Author: Prog@ndy
Func __IDataObj_AddRef($pObject)
    Local $st = DllStructCreate($tagIDataObject, $pObject)
    Local $iCount = DllStructGetData($st, "dwRefCount") + 1
    DllStructSetData($st, "dwRefCount", $iCount)
    Return $iCount
EndFunc   ;==>__IDataObj_AddRef

; Author: Prog@ndy
Func __IDataObj_Release($pObject)
    Local $st = DllStructCreate($tagIDataObject, $pObject)
    Local $iCount = DllStructGetData($st, "dwRefCount") - 1
    DllStructSetData($st, "dwRefCount", $iCount)
    If $iCount = 0 Then
        ;[[[ Array
            Local $pFORMATETC = DllStructGetData($st, "pFORMATETC")
            Local $pSTGMEDIUM = DllStructGetData($st, "pSTGMEDIUM")
            Local $STGMED = DllStructCreate($tagSTGMEDIUM)
            Local $FMTETC = DllStructCreate($tagFORMATETC)
;~          Local $STGMED
            Local $pSTGMED = DllStructGetPtr($STGMED)
            Local $pFMTETC = DllStructGetPtr($FMTETC)
            For $i = 0 To DllStructGetData($st, "Count")-1
                _MemArrayGet($pFORMATETC, $i, $pFMTETC)
                If DllStructGetData($FMTETC, "ptd") Then _CoTaskMemFree(DllStructGetData($FMTETC, "ptd"))
                _MemArrayGet($pSTGMEDIUM, $i, $pSTGMED)
                _ReleaseStgMedium($STGMED)
            Next
            _MemArrayFree($pFORMATETC)
            _MemArrayFree($pSTGMEDIUM)
        ;]]] Array
        _MemGlobalFree($pObject)
    EndIf
    Return $iCount
EndFunc   ;==>__IDataObj_Release

; Author: Prog@ndy
Func __IDataObj_GetData($pObject, $pFormatEtc, $pMedium)
    If $pMedium = 0 Or $pFormatEtc = 0 Then Return $E_POINTER
    Local $st = DllStructCreate($tagIDataObject, $pObject)
    Local $dwCount = DllStructGetData($st, "Count")
    Local $pArrFormatEtc = DllStructGetData($st, "pFORMATETC")
    Local $idx = __DataObj_LookupFormatEtc($pFormatEtc, $pArrFormatEtc, $dwCount)
    If $idx == -1 Then Return $DV_E_FORMATETC
    Local $stFORMATETC = DllStructCreate($tagFORMATETC, $pFormatEtc)

;~  Local $tymed = DllStructGetData(DllStructCreate($tagFORMATETC,$pArrFormatEtc+ $idx*$sizeFORMATETC),"tymed")
    ;[[[ Array
        Local $tymed = DllStructGetData(_MemArrayGet($pArrFormatEtc, $idx, $tagFORMATETC),"tymed")
    ;]]] Array
    Local $Medium = DllStructCreate($tagSTGMEDIUM,$pMedium)
    DllStructSetData($Medium,"tymed", $tymed)
    DllStructSetData($Medium,"pUnkForRelease", 0)
    Switch $tymed
        Case $TYMED_ENHMF, $TYMED_GDI, $TYMED_HGLOBAL, $TYMED_MFPICT, $TYMED_NULL, $TYMED_ISTREAM, $TYMED_ISTORAGE
;~          Local $IntMedium = DllStructCreate($tagSTGMEDIUM,DllStructGetData($st,"pSTGMEDIUM") + $idx*$sizeSTGMEDIUM)
            ;[[[ Array
                Local $IntMedium = _MemArrayGet(DllStructGetData($st,"pSTGMEDIUM"),  $idx, $tagSTGMEDIUM)
            ;]]] Array
;~          DllStructSetData($Medium,"hGlobal", DupGlobalMemMem(DllStructGetData($IntMedium,"hGlobal")))
            If Not DeepCopyStgMedium($pMedium, DllStructGetPtr($IntMedium)) Then Return $DV_E_FORMATETC
        Case Else
            return $DV_E_FORMATETC;
    EndSwitch

    Return $S_OK
EndFunc   ;==>__IDataObj_GetData

; Author: Prog@ndy
Func __IDataObj_GetDataHere($pObject, $pFormatEtc, $pMedium)
    Return $DATA_E_FORMATETC;
EndFunc   ;==>__IDataObj_GetDataHere

; Author: Prog@ndy
Func __IDataObj_QueryGetData($pObject, $pFormatEtc)
    Local $st = DllStructCreate($tagIDataObject, $pObject)
    Return _Iif( __DataObj_LookupFormatEtc($pFormatEtc, DllStructGetData($st, "pFORMATETC"), DllStructGetData($st, "Count")) = -1, $DV_E_FORMATETC, $S_OK);
EndFunc   ;==>__IDataObj_QueryGetData

; Author: Prog@ndy
Func __IDataObj_GetCanonicalFormatEtc($pObject, $pFormatEtc, $pFormatEtcOut)
;~     // Apparently we have to set this field to NULL even though we don't do anything else
    Local $FormatEtcOut = DllStructCreate($tagFORMATETC, $pFormatEtcOut)
    DllStructSetData($FormatEtcOut, "ptd", 0);
    Return $E_NOTIMPL;
EndFunc   ;==>__IDataObj_GetCanonicalFormatEtc

; Author: Prog@ndy
Func __IDataObj_SetData($pObject, $pFormatEtc, $pMedium, $fRelease)
;~  Return $E_NOTIMPL;
    Local $STGMED = DllStructCreate($tagSTGMEDIUM,$pMedium)
    Switch DllStructGetData($STGMED,"tymed")
        Case $TYMED_ENHMF, $TYMED_GDI, $TYMED_HGLOBAL, $TYMED_MFPICT, $TYMED_NULL, $TYMED_ISTREAM, $TYMED_ISTORAGE
            ; they are accepted
        Case Else
            If Not $fRelease And DllStructGetData($STGMED,"tymed")=$TYMED_FILE Then Return $DV_E_FORMATETC
    EndSwitch
    If Not $fRelease Then
        $STGMED = DllStructCreate($tagSTGMEDIUM)
        Local $FormatEtc = DllStructCreate($tagFORMATETC)
        If Not DeepCopyStgMedium(DllStructGetPtr($STGMED) , $pMedium) Then Return $E_OUTOFMEMORY
        DeepCopyFormatEtc(DllStructGetPtr($FormatEtc) , $pFormatEtc)
        $pMedium = DllStructGetPtr($STGMED)
        $pFormatEtc = DllStructGetPtr($FormatEtc)
    EndIf

    Local $st = DllStructCreate($tagIDataObject, $pObject)
    Local $pArrFormatEtc = DllStructGetData($st, "pFORMATETC")
    Local $pArrStgMedium = DllStructGetData($st, "pSTGMEDIUM")
    Local $dwCount = DllStructGetData($st, "Count")
    Local $idx = __DataObj_LookupFormatEtc($pFormatEtc, $pArrFormatEtc, $dwCount)
    If $idx == -1 Then
        _MemArrayAdd($pArrFormatEtc, $pFormatEtc)
        _MemArrayAdd($pArrStgMedium, $pMedium)
        DllStructSetData($st, "Count", $dwCount+1)
    Else
        Local $ptd = DllStructGetData(_MemArrayGet($pArrFormatEtc, $idx, $tagFORMATETC),"ptd")
        If $ptd Then _CoTaskMemFree($ptd)
        _MemArraySet($pArrFormatEtc, $idx, $pFormatEtc)

        Local $Med = _MemArrayGet($pArrStgMedium, $idx, $tagSTGMEDIUM)
        _ReleaseStgMedium($Med)
        _MemArraySet($pArrStgMedium, $idx, $pMedium)
    EndIf
    If DllStructGetData($STGMED,"pUnkForRelease") = $pObject Then
        Local $IUnk = _ObjCreateFromPtr($pMedium,$IUnknown_vTable)
        _IUnknown_Release($IUnk)
    EndIf

    Return $S_OK
EndFunc   ;==>__IDataObj_SetData

; Author: Prog@ndy
Func __IDataObj_EnumFormatEtc($pObject, $dwDirection, $ppEnumFormatEtc)
    Switch $dwDirection
        Case $DATADIR_GET
            Local $st = DllStructCreate($tagIDataObject, $pObject)
;~          Local $result = DllCall("shell32.dll", $HRESULT, "SHCreateStdEnumFmtEtc", "uint", DllStructGetData($st, "Count"), "ptr", DllStructGetData($st, "pFORMATETC"), "ptr*", 0)
            ;[[[ Array
                Local $pFORMATETC = DllStructGetData($st, "pFORMATETC")
                Local $result = DllCall("shell32.dll", $HRESULT, "SHCreateStdEnumFmtEtc", "uint", DllStructGetData($st, "Count"), "ptr", __MemArrayLockedPtr($pFORMATETC), "ptr*", 0)
                __MemArrayUnLock($pFORMATETC)
            ;]]] Array
            Local $pEnumFormatEtc = DllStructCreate("ptr",$ppEnumFormatEtc)
            DllStructSetData($pEnumFormatEtc,1,$result[3])
            Return _Iif($result[3]=0, $E_OUTOFMEMORY, $S_OK)
        Case Else
;~          Return $E_NOTIMPL
            Return $OLE_S_USEREG ; No support for all formats, but this is easier :P
    EndSwitch
EndFunc   ;==>__IDataObj_EnumFormatEtc

; Author: Prog@ndy
Func __IDataObj_DAdvise($pObject, $pFormatEtc, $advf, $pAdvSink, $pdwConnection)
    Return $OLE_E_ADVISENOTSUPPORTED;
EndFunc   ;==>__IDataObj_DAdvise

; Author: Prog@ndy
Func __IDataObj_DUnadvise($pObject, $dwConnection)
    Return $OLE_E_ADVISENOTSUPPORTED;
EndFunc   ;==>__IDataObj_DUnadvise

; Author: Prog@ndy
Func __IDataObj_EnumDAdvise($pObject, $ppEnumAdvise)
    Return $OLE_E_ADVISENOTSUPPORTED;
EndFunc   ;==>__IDataObj_EnumDAdvise

; Author: Prog@ndy
Func _DragDrop_SIZEOF($tagStruct)
    Return DllStructGetSize(DllStructCreate($tagStruct, 1))
EndFunc   ;==>_DragDrop_SIZEOF

; Author: Prog@ndy
Func _CreateIDataObject(ByRef $fmtetc, ByRef $stgmed)
    If Not IsArray($fmtetc) Or UBound($fmtetc) <> UBound($stgmed) Then Return SetError(1, 0, 0)
    Local $iCount = UBound($fmtetc)

    Local $sizeIDataObj = _DragDrop_SIZEOF($tagIDataObject)

;~  Local $pObj = _MemGlobalAlloc($sizeIDataObj + ($iCount * $sizeFORMATETC) + ($iCount * $sizeSTGMEDIUM), $GPTR)
    ;[[[ Array
        Local $pObj = _MemGlobalAlloc($sizeIDataObj, $GPTR)
        Local $pFORMATETC = _MemArrayCreate($tagFORMATETC)
        Local $pSTGMEDIUM = _MemArrayCreate($tagSTGMEDIUM)
    ;]]] Array
    Local $stObj = DllStructCreate($tagIDataObject, $pObj)
    DllStructSetData($stObj, "vTable", DllStructGetPtr($__IDataObj_vTable))
    DllStructSetData($stObj, "dwRefCount", 1)


;~  Local $pPtr = $pObj + $sizeIDataObj

    DllStructSetData($stObj, "Count", $iCount)
;~  DllStructSetData($stObj, "pFORMATETC", $pPtr)
    DllStructSetData($stObj, "pFORMATETC", $pFORMATETC)
    For $i = 0 To $iCount - 1
;~      _MemMoveMemory(DllStructGetPtr($fmtetc[$i]), $pPtr, $sizeFORMATETC)
;~      _RtlCopyMemory(DllStructGetPtr($fmtetc[$i]), $pPtr, $sizeFORMATETC)
        _MemArrayAdd($pFORMATETC, $fmtetc[$i])
;~      $pPtr += $sizeFORMATETC
    Next
;~  DllStructSetData($stObj, "pSTGMEDIUM", $pPtr)
    DllStructSetData($stObj, "pSTGMEDIUM", $pSTGMEDIUM)
    For $i = 0 To $iCount - 1
;~      _MemMoveMemory(DllStructGetPtr($stgmed[$i]), $pPtr, $sizeSTGMEDIUM)
;~      _RtlCopyMemory(DllStructGetPtr($stgmed[$i]), $pPtr, $sizeSTGMEDIUM)
        _MemArrayAdd($pSTGMEDIUM, $stgmed[$i])
;~      $pPtr += $sizeSTGMEDIUM
    Next
    Local $result[3] = [$pObj, $stObj, $__IDataObj_vTable]
    Return $result
EndFunc   ;==>_CreateIDataObject

; Author: Prog@ndy
Func _ReleaseIDataObject(ByRef $IDataObj)
    Local $res = _ObjFuncCall("ulong",$IDataObj,"Release")
    If @error Then Return SetError(1,0,-1)
    If $res[0] = 0 Then
        $IDataObj = 0
    EndIf
    Return $res[0]
EndFunc

; Author: Prog@ndy
Func _RtlCopyMemory($pSource, $pDest, $iLength)
    DllCall("msvcrt.dll", "none:cdecl", "memcpy", "ptr", $pDest, "ptr", $pSource, "dword", $iLength)
EndFunc   ;==>_RtlCopyMemory

; Author: Prog@ndy
; translated from C++
Func DupGlobalMemMem($hMem)
    Local $len = _MemGlobalSize($hMem);
    Local $source = _MemGlobalLock($hMem);
    If $source = 0 Then $source = $hMem

;~  Local $dest = _MemGlobalAlloc($len, BitOR($GMEM_MOVEABLE,$GMEM_SHARE));
    Local $dest = _MemGlobalAlloc($len, BitOR($GMEM_FIXED,$GMEM_SHARE));

;~  _MemMoveMemory($source, _MemGlobalLock($dest), $len);
    _RtlCopyMemory($source, _MemGlobalLock($dest), $len);

    _MemGlobalUnlock($dest);
    _MemGlobalUnlock($hMem);
    Return $dest;
EndFunc   ;==>DupGlobalMemMem

Func DeepCopyStgMedium($pDest, $pSource)

    __MemCopyMemory($pSource,$pDest,$sizeSTGMEDIUM)
    Local $stSource = DllStructCreate($tagSTGMEDIUM,$pSource)
    Local $Souce_tymed = DllStructGetData($stSource,"tymed")
    Local $data = DllStructGetData($stSource,"hGlobal"), $newData
    Switch $Souce_tymed
        Case $TYMED_NULL
            Return True
        Case $TYMED_HGLOBAL
            $newData = _CloneHGLOBAL($data)
        Case $TYMED_GDI
            $newData = _CloneBitmap($data)
        Case $TYMED_ENHMF
            $newData = _CloneEnhMetaFile($data)
        Case $TYMED_MFPICT
            $newData = _CloneMetaFile($data)
        Case $TYMED_ISTREAM, $TYMED_ISTORAGE
            Local $IUnk = _ObjCreateFromPtr($data,$IUnknown_vTable)
            _IUnknown_AddRef($IUnk)
            Return True
        Case Else
            Return False
    EndSwitch
    If DllStructGetData($stSource,"pUnkForRelease") Then
        Local $IUnk = _ObjCreateFromPtr(DllStructGetData($stSource,"pUnkForRelease"),$IUnknown_vTable)
        _IUnknown_AddRef($IUnk)
    EndIf
    DllStructSetData(DllStructCreate($tagSTGMEDIUM,$pDest),"hGlobal",$newData)
    Return True
EndFunc


; Author: Prog@ndy
Func _CloneBitmap($hBmp)
    Local $result = DllCall("user32.dll", "ptr", "CopyImage", "ptr", $hBmp, "uint", 0, "int",0, "int",0, "uint", 0)
    Return $result[0]
EndFunc
; Author: Prog@ndy
Func _CloneEnhMetaFile($hemfSrc)
    Local $result = DllCall("Gdi32.dll", "ptr", "CopyEnhMetaFileW", "ptr", $hemfSrc, "ptr", 0)
    Return $result[0]
EndFunc
; Author: Prog@ndy
Func _CloneMetaFile($hemfSrc)
    Local $result = DllCall("Gdi32.dll", "ptr", "CopyMetaFileW", "ptr", $hemfSrc, "ptr", 0)
    Return $result[0]
EndFunc
; Author: Prog@ndy
Func _CloneHGLOBAL($hMem)
    Local $Size = _MemGlobalSize($hMem)
    Local $Flags = __MemGlobalFlags($hMem)
    If $Flags = $GMEM_INVALID_HANDLE Then Return SetError(1,0,0)
    Local $hNewMem = _MemGlobalAlloc($Size,$Flags)
    Local $pNewMem = _MemGlobalLock($hNewMem)
    Local $pMem = _MemGlobalLock($hMem)
    __MemCopyMemory($pMem, $pNewMem, $Size)
    _MemGlobalUnlock($hNewMem)
    _MemGlobalUnlock($hMem)
    Return $hNewMem
EndFunc

; Author: Prog@ndy
; translated from C++
Func DeepCopyFormatEtc($pDest, $pSource)
    ;// copy the source FORMATETC into dest

    __MemCopyMemory($pSource,$pDest,$sizeFORMATETC)

    Local $Souce_ptd = DllStructGetData(DllStructCreate($tagFORMATETC,$pSource),"ptd")
    if($Souce_ptd) Then
        ;// allocate memory for the DVTARGETDEVICE if necessary
        Local $dest_ptd = _CoTaskMemAlloc(_DragDrop_SIZEOF($tagDVTARGETDEVICE));

        ;// copy the contents of the source DVTARGETDEVICE into dest->ptd
        __MemCopyMemory($Souce_ptd, $dest_ptd, _DragDrop_SIZEOF($tagDVTARGETDEVICE))
        ;*(dest->ptd) = *(source->ptd);
        DllStructSetData(DllStructCreate($tagFORMATETC,$pDest),"ptd",$dest_ptd)
    EndIf
EndFunc


; Author: Prog@ndy
; translated from C++
Func __DataObj_LookupFormatEtc($pFormatEtc, $pAvailableFormats, $dwCount)

    Local $FormatEtc = DllStructCreate($tagFORMATETC, $pFormatEtc), $next

    ;// check each of our formats in turn to see if one matches
;~  Local $pPtr = $pAvailableFormats
    For $i = 0 To $dwCount - 1
;~      $next = DllStructCreate($tagFORMATETC, $pPtr)
        $next = _MemArrayGet($pAvailableFormats, $i, $tagFORMATETC)
        ;  "dword cfFormat; ptr ptd; DWORD  dwAspect; LONG lindex; DWORD tymed;"
        If ( ( DllStructGetData($next, 1) =  DllStructGetData($FormatEtc, 1) ) And _
             ( DllStructGetData($next, 3) = DllStructGetData($FormatEtc, 3) ) And _
             ( DllStructGetData($next, 4) = DllStructGetData($FormatEtc, 4) ) And _
             ( BitAND(DllStructGetData($next, 5), DllStructGetData($FormatEtc, 5)) <> 0 ) ) Then

            ;// return index of stored format
            Return $i;
;~          $pPtr += $sizeFORMATETC
        EndIf
    Next

    ;// error, format not found
    Return -1;
EndFunc   ;==>__DataObj_LookupFormatEtc

; Author: Prog@ndy
Func _ReleaseStgMedium(ByRef $stgmed)
    Local $ptr
    If IsDllStruct($stgmed) Then
        $ptr = DllStructGetPtr($stgmed)
    ElseIf IsPtr($stgmed) Then
        $ptr = $stgmed
    Else
        Return SetError(1)
    EndIf
    DllCall("ole32.dll","none", "ReleaseStgMedium", "ptr", $ptr)
EndFunc

#EndRegion IDataObject
; -- #EndRegion IDataObject -------------------------------------------------------------

; Author: Prog@ndy
Func _DoDragDrop(ByRef $objIDataSource, ByRef $objIDropSource, $dwDropEffects, ByRef $dwPerformedEffect)
    Local $result = DllCall($OLE32,$HRESULT,"DoDragDrop", "ptr", _ObjGetObjPtr($objIDataSource),"ptr", _ObjGetObjPtr($objIDropSource), "dword", BitOR($DROPEFFECT_MOVE,$DROPEFFECT_COPY,$DROPEFFECT_LINK), "dword*", 0)
    $dwPerformedEffect = $result[4]
    Return $result[0]
EndFunc

Func _Iif($FTEST, $VTRUEVAL, $VFALSEVAL)
    If $FTEST Then
        Return $VTRUEVAL
    Else
        Return $VFALSEVAL
    EndIf
EndFunc

 

objbase.au3

Global Const $OLE32 = DllOpen("ole32.dll")

; Prog@ndy
Func MAKE_HRESULT($sev,$fac,$code)
    Return BitOR(BitShift($sev,-31) , BitOR(BitShift($fac,-16),  $code))
EndFunc

Global Const $CLSCTX_INPROC_SERVER = 1
Global Const $CLSCTX_LOCAL_SERVER = 4
Global Const $CLSCTX_SERVER = BitOR($CLSCTX_INPROC_SERVER , $CLSCTX_LOCAL_SERVER)
Global Const $HRESULT = "lresult"
;~ Global Const $S_OK = 0
;~ Global Const $E_NOINTERFACE = 0x80004002
;~ Global Const $E_ABORT = 0x80004004
;~ Global Const $E_ACCESSDENIED = 0x80070005
;~ Global Const $E_FAIL = 0x80004005
;~ Global Const $E_INVALIDARG = 0x80070057
;~ Global Const $E_HANDLE = 0x80070006
;~ Global Const $E_NOTIMPL = 0x80004001
;~ Global Const $E_OUTOFMEMORY = 0x8007000E
;~ Global Const $E_PENDING = 0x8000000A
;~ Global Const $E_POINTER = 0x80004003
;~ Global Const $E_UNEXPECTED = 0x8000FFFF

Global Const $OLE_E_ADVF = 0x80040001
Global Const $OLE_E_ADVISENOTSUPPORTED = 0x80040003
Global Const $OLE_E_BLANK = 0x80040007
Global Const $OLE_E_CANT_BINDTOSOURCE = 0x8004000A
Global Const $OLE_E_CANT_GETMONIKER = 0x80040009
Global Const $OLE_E_CANTCONVERT = 0x80040011
Global Const $OLE_E_CLASSDIFF = 0x80040008
Global Const $OLE_E_ENUM_NOMORE = 0x80040002
Global Const $OLE_E_FIRST = 0x80040000
Global Const $OLE_E_INVALIDHWND = 0x8004000F
Global Const $OLE_E_INVALIDRECT = 0x8004000D
Global Const $OLE_E_LAST = 0x800400FF
Global Const $OLE_E_NOCACHE = 0x80040006
Global Const $OLE_E_NOCONNECTION = 0x80040004
Global Const $OLE_E_NOSTORAGE = 0x80040012
Global Const $OLE_E_NOT_INPLACEACTIVE = 0x80040010
Global Const $OLE_E_NOTRUNNING = 0x80040005
Global Const $OLE_E_OLEVERB = 0x80040000
Global Const $OLE_E_PROMPTSAVECANCELLED = 0x8004000C
Global Const $OLE_E_STATIC = 0x8004000B
Global Const $OLE_E_WRONGCOMPOBJ = 0x8004000E

Global $IID_IUnknown = _GUID("{00000000-0000-0000-C000-000000000046}")

Global Const $tagIID = "DWORD Data1;  ushort Data2;  ushort Data3;  BYTE Data4[8];"
; Prog@ndy
Func _GUID($IID)
    $IID = StringRegExpReplace($IID,"([}{])","")
    $IID = StringSplit($IID,"-")
    Local $_GUID =  "DWORD Data1;  ushort Data2;  ushort Data3;  BYTE Data4[8];"
    Local $GUID = DllStructCreate($_GUID)
    If $IID[0] = 5 Then $IID[4] &= $IID[5]
    If $IID[0] > 5 Or $IID[0] < 4 Then Return SetError(1,0,0)
    DllStructSetData($GUID,1,Dec($IID[1]))
    DllStructSetData($GUID,2,Dec($IID[2]))
    DllStructSetData($GUID,3,Dec($IID[3]))
    DllStructSetData($GUID,4,Binary("0x"&$IID[4]))
    Return $GUID
EndFunc

; Prog@ndy
; compares two GUID / IID DLLStructs
Func _GUID_Compare(ByRef $IID1, ByRef $IID2)
    Local $a,$b
    For $i = 1 To 4
        $a = DllStructGetData($IID1,$i)
        If @error Then Return SetError(1,0,0)
        $b = DllStructGetData($IID2,$i)
        If @error Then Return SetError(1,0,0)
        If $a <> $b Then Return 0
    Next
    Return 1
EndFunc

; The IUnknown-Interface
; description: http://www.reactos.org/generated/doxygen/d8/de9/interfaceIUnknown.html
Global Const $IUnknown = "ptr IUnknown;"
Global Const $IUnknown_vTable = "ptr QueryInterface; ptr AddRef; ptr Release;"
;~  /*** IUnknown methods ***/
;~  STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
; Prog@ndy
Func _IUnknown_QueryInterface(ByRef $ObjArr, ByRef $REFIID)
    Local $ret = _ObjFuncCall($HRESULT, $ObjArr, "QueryInterface", "ptr", DllStructGetPtr($REFIID), "ptr*", 0)
    If @error Then Return SetError(1,0,0)
    Return SetError($ret[0],0,$ret[3])
EndFunc

; Prog@ndy
Func _IUnknown_AddRef(ByRef $ObjArr)
    Local $ret = _ObjFuncCall("ULONG", $ObjArr, "AddRef")
    If @error Then Return SetError(1,0,0)
    Return SetError($ret[0]<1,0,$ret[0])
EndFunc

; Prog@ndy
Func _IUnknown_Release(ByRef $ObjArr)
    Local $ret = _ObjFuncCall("ULONG", $ObjArr, "Release")
    If @error Then Return SetError(1,0,0)
    Return SetError($ret[0],0,$ret[0]=0)
EndFunc

; -- #Region MemoryCalls -----------------------------------
#Region Call ObjectFuncs
; _ObjFunc.. are the MemoryFunc... functions from http://www.autoitscript.com/forum/index.php?showtopic=77463
;~ Global $__COMFN_HookPtr, $__COMFN_HookBak, $__COMFN_HookApi = "LocalFlags", $__COMFN_Kernel32Dll = DllOpen("kernel32.dll")
Global $__COMFN_HookPtr, $__COMFN_HookBak, $__COMFN_HookApi = "LocalCompact", $__COMFN_Kernel32Dll = DllOpen("kernel32.dll")
; by Ward
Func _ObjFuncInit()
    Local $KernelHandle = DllCall($__COMFN_Kernel32Dll, "ptr", "LoadLibrary", "str", "kernel32.dll")
    Local $HookPtr = DllCall($__COMFN_Kernel32Dll, "ptr", "GetProcAddress", "ptr", $KernelHandle[0], "str", $__COMFN_HookApi)
    $__COMFN_HookPtr = $HookPtr[0]

    $__COMFN_HookBak = DllStructCreate("ubyte[7]")
    DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", DllStructGetPtr($__COMFN_HookBak), "ptr", $__COMFN_HookPtr, "uint", 7, "uint*", 0)

    DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr, "byte*", 0xB8, "uint", 1, "uint*", 0)
    DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr + 5, "ushort*", 0xE0FF, "uint", 2, "uint*", 0)
EndFunc

; by Ward
; modified by Prog@ndy
; Return array: [0] - result
;               [1] - Object Pointer
;               [2] - first parameter
;               [n+1] - n-th Parameter
Func _ObjFuncCall($RetType, ByRef $ObjArr, $sFuncName,  $Type1 = "", $Param1 = 0, $Type2 = "", $Param2 = 0, $Type3 = "", $Param3 = 0, $Type4 = "", $Param4 = 0, $Type5 = "", $Param5 = 0, $Type6 = "", $Param6 = 0, $Type7 = "", $Param7 = 0, $Type8 = "", $Param8 = 0, $Type9 = "", $Param9 = 0, $Type10 = "", $Param10 = 0, $Type11 = "", $Param11 = 0, $Type12 = "", $Param12 = 0, $Type13 = "", $Param13 = 0, $Type14 = "", $Param14 = 0, $Type15 = "", $Param15 = 0, $Type16 = "", $Param16 = 0, $Type17 = "", $Param17 = 0, $Type18 = "", $Param18 = 0, $Type19 = "", $Param19 = 0, $Type20 = "", $Param20 = 0)
    If Not IsDllStruct($__COMFN_HookBak) Then _ObjFuncInit()

    Local $Address = _ObjGetFuncPtr($ObjArr,$sFuncName)
    If @error Then Return SetError(1,-1,0)
    If $Address = 0 Then Return SetError(3,-1,0)

    _ObjFuncSet($Address)
    Local $Ret
    Switch @NumParams
    Case 3
        $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0])
    Case 5
        $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1)
    Case 7
        $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2)
    Case 9
        $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2, $Type3, $Param3)
    Case 11
        $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4)
    Case 13
        $Ret = DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0], $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4, $Type5, $Param5)
    Case Else
        If Mod(@NumParams,2)=0 Then Return SetError(2,-1,0)
        Local $DllCallStr = 'DllCall($__COMFN_Kernel32Dll, $RetType, $__COMFN_HookApi, "ptr", $ObjArr[0]', $n, $i
        For $i = 5 To @NumParams Step 2
            $n = ($i - 3) / 2
            $DllCallStr &= ', $Type' & $n & ', $Param' & $n
        Next
        $DllCallStr &= ')'

        $Ret = Execute($DllCallStr)
    EndSwitch
    SetError(@error,@extended)
    Return $Ret
EndFunc
; by Ward
Func _ObjFuncSet($Address)
    DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr + 1, "uint*", $Address, "uint", 4, "uint*", 0)
EndFunc
; by Ward
Func _ObjFuncExit()
    DllCall($__COMFN_Kernel32Dll, "int", "WriteProcessMemory", "ptr", -1, "ptr", $__COMFN_HookPtr, "ptr", DllStructGetPtr($__COMFN_HookBak), "uint", 7, "uint*", 0)
    $__COMFN_HookBak = 0
EndFunc
#EndRegion
; -- #EndRedion MemoryCalls -----------------------------------

; Prog@ndy
Func _ObjCreateFromPtr($ObjPointer, $vTable)
    If Not $ObjPointer Then Return SetError(1,0,0)
    Local $object[3] = [$ObjPointer]
    $object[1] = DllStructCreate("ptr lpvTable",Ptr($object[0]))
    If @error Then Return SetError(2,0 ,0)
    $object[2] = DllStructCreate($vTable,DllStructGetData($object[1],1))
    If @error Then Return SetError(3,0,0)
    Return $object
EndFunc

; Prog@ndy
Func _ObjCoCreateInstance(ByRef $CLSID, ByRef $IID,$ObjvTable)

;~  Local $ret = DllCall($OLE32,"long_ptr","CoCreateInstance","ptr",DllStructGetPtr($CLSID),"ptr",0,"dword",$CLSCTX_SERVER, "ptr",DllStructGetPtr($IID),"ptr*",0)
    Local $ret = DllCall($OLE32,"long_ptr","CoCreateInstance","ptr",DllStructGetPtr($CLSID),"ptr",0,"dword",$CLSCTX_INPROC_SERVER, "ptr",DllStructGetPtr($IID),"ptr*",0)
    Local $object[3] = [$ret[5],0,0]
    ; get the interface
    $object[1] = DllStructCreate("ptr lpvTable",$object[0])
    $object[2] = DllStructCreate($ObjvTable,DllStructGetData($object[1],1))
    Return $object
EndFunc

; Prog@ndy
Func _ObjCoInitialize()
    Local $result = DllCall($OLE32,$HRESULT,"CoInitialize","ptr",0)
    Return $result[0]
EndFunc

; Prog@ndy
Func _ObjCoUninitialize()
    Local $result = DllCall($OLE32,$HRESULT,"CoUninitialize")
    Return $result[0]
EndFunc

; Prog@ndy
Func _ObjGetFuncPtr(ByRef $ObjArr, $FuncName)
    If UBound($ObjArr)<>3 Then Return SetError(1,0,0)
    Return DllStructGetData($ObjArr[2],$FuncName)
EndFunc
; Prog@ndy
Func _ObjGetObjPtr(ByRef $ObjArr)
    If UBound($ObjArr)<>3 Then Return SetError(1,0,0)
    If DllStructGetData($ObjArr[1],1)=0 Then Return SetError(2,0,0)
    Return $ObjArr[0]
EndFunc
; Prog@ndy
Func _OLEInitialize()
    Local $result = DllCall($OLE32,$HRESULT,"OleInitialize","ptr",0)
    Return $result[0]
EndFunc
; Prog@ndy
Func _OLEUnInitialize()
    Local $result = DllCall($OLE32,$HRESULT,"OleUninitialize")
    Return $result[0]
EndFunc

Func _CoTaskMemAlloc($iSize)
    Local $result = DllCall($OLE32, "ptr", "CoTaskMemAlloc", "ulong", $iSize)
    Return $result[0]
EndFunc

Func _CoTaskMemFree($pMem)
    DllCall($OLE32, "none", "CoTaskMemFree", "ptr", $pMem)
EndFunc
Func _CoTaskMemRealloc($pMem, $iSize)
    Local $result = DllCall($OLE32, "ptr", "CoTaskMemRealloc", "ptr", $pMem, "ulong", $iSize)
    Return $result[0]
EndFunc

 

MemArray.au3

#include<Memory.au3>
#include<Array.au3>

Global Const $__MemArray_HEAD = "dword iElSize;"
Global Const $__MemArray_HEADSIZE = __MemArray_SIZEOF($__MemArray_HEAD)
; Author: Prog@ndy
Func __MemArray_SIZEOF($tagStruct)
    Return DllStructGetSize(DllStructCreate($tagStruct, 1))
EndFunc   ;==>__MemArray_SIZEOF

 
Func __MemArrayLockedPtr($hMem)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1,0,0)
    Return _MemGlobalLock($hMem)+$__MemArray_HEADSIZE
EndFunc

Func __MemArrayUnLock($hMem)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1,0,0)
    _MemGlobalUnlock($hMem)
EndFunc


; Author: Prog@ndy
Func _MemArrayCreate($tagStruct)
    Local $iSize = __MemArray_SIZEOF($tagStruct)
    If $iSize = 0 Then Return SetError(1, 0, 0)
    Local $hMem = _MemGlobalAlloc($__MemArray_HEADSIZE, $GMEM_MOVEABLE)
    If $hMem = 0 Then Return SetError(2, 0, 0)
    DllStructSetData(DllStructCreate($__MemArray_HEAD, _MemGlobalLock($hMem)), 1, $iSize)
    _MemGlobalUnlock($hMem)
    Return $hMem
EndFunc   ;==>_MemArrayCreate
; Author: Prog@ndy
Func __MemArrayElementSize($hMem)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0)
    Local $iSize = DllStructGetData(DllStructCreate($__MemArray_HEAD, _MemGlobalLock($hMem)), 1)
    _MemGlobalUnlock($hMem)
    Return $iSize
EndFunc   ;==>__MemArrayElementSize
; Author: Prog@ndy
Func _MemArrayFree($hMem)
    Return _MemGlobalFree($hMem)
EndFunc   ;==>_MemArrayFree
; Author: Prog@ndy
Func _MemArrayAdd($hMem, ByRef $stEntry)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, -1)
    If Not (IsDllStruct($stEntry) Or IsPtr($stEntry)) Then Return SetError(2, 0, -1)
    Local $size = _MemGlobalSize($hMem)
    Local $iElSize = __MemArrayElementSize($hMem)
    Local $result = __MemGlobalReAlloc($hMem, $size + $iElSize, $GHND)
    If Not $result Then Return SetError(2, 0, 0)
    Local $indX = (($size - $__MemArray_HEADSIZE) / $iElSize)
    If IsPtr($stEntry) Then
        __MemCopyMemory($stEntry, _MemGlobalLock($hMem) + $size, $iElSize)
    Else
        __MemCopyMemory(DllStructGetPtr($stEntry), _MemGlobalLock($hMem) + $size, $iElSize)
    EndIf
    _MemGlobalUnlock($hMem)
    Return $indX
EndFunc   ;==>_MemArrayAdd
; Author: Prog@ndy
Func _MemArrayDelete($hMem, $indX)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0)
    Local $size = _MemGlobalSize($hMem)
    Local $iElSize = __MemArrayElementSize($hMem)

    Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize
    If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0)
    If $size > ($__MemArray_HEADSIZE + $iElSize) Then
        Local $hPtr = _MemGlobalLock($hMem)
        Local $deletedElementOffset = ($indX * $iElSize) + $__MemArray_HEADSIZE
        _MemMoveMemory($hPtr + $deletedElementOffset + $iElSize, $hPtr + $deletedElementOffset, $size - ($deletedElementOffset + $iElSize))
        _MemGlobalUnlock($hMem)
    EndIf
    __MemGlobalReAlloc($hMem, $size - $iElSize, $GMEM_MOVEABLE)
    Return 1
EndFunc   ;==>_MemArrayDelete
; Author: Prog@ndy
Func _MemArrayGet($hMem, $indX, $tagStruct)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0)
    Local $size = _MemGlobalSize($hMem)
    Local $iElSize = __MemArrayElementSize($hMem)

    Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize
    If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0)
    If IsPtr($tagStruct) Then 
        __MemCopyMemory(_MemGlobalLock($hMem) + $__MemArray_HEADSIZE + $indX * $iElSize, $tagStruct, $iElSize)
        Local $struct = $tagStruct
    Else
        Local $struct = DllStructCreate($tagStruct)
        If @error Then Return SetError(2,0,0)
        __MemCopyMemory(_MemGlobalLock($hMem) + $__MemArray_HEADSIZE + $indX * $iElSize, DllStructGetPtr($struct), $iElSize)
    EndIf
    _MemGlobalUnlock($hMem)
    Return $struct
EndFunc   ;==>_MemArrayGet

; Author: Prog@ndy
Func _MemArrayGetDelete($hMem, $indX, $tagStruct)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0)
    Local $size = _MemGlobalSize($hMem)
    Local $iElSize = __MemArrayElementSize($hMem)

    Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize
    If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0)
    Local $hPtr = _MemGlobalLock($hMem)
    If IsPtr($tagStruct) Then 
        __MemCopyMemory($hPtr + $__MemArray_HEADSIZE + $indX * $iElSize, $tagStruct, $iElSize)
    Else
        Local $struct = DllStructCreate($tagStruct)
        If @error Then Return SetError(2,_MemGlobalUnlock($hMem),0)
        __MemCopyMemory($hPtr + $__MemArray_HEADSIZE + $indX * $iElSize, DllStructGetPtr($struct), $iElSize)
    EndIf
    If $size > ($__MemArray_HEADSIZE + $iElSize) Then
        Local $deletedElementOffset = ($indX * $iElSize) + $__MemArray_HEADSIZE
        _MemMoveMemory($hPtr + $deletedElementOffset + $iElSize, $hPtr + $deletedElementOffset, $size - ($deletedElementOffset + $iElSize))
    EndIf
    _MemGlobalUnlock($hMem)
    __MemGlobalReAlloc($hMem, $size - $iElSize, $GMEM_MOVEABLE)
    Return $struct
EndFunc   ;==>_MemArrayGet

#cs
    Func _MemArrayGetToArray($hMem)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1,0,0)
    Local $size = _MemGlobalSize($hMem)
    Local $maxIndX = $size/$__MemArray_PTRSIZE
    If $maxIndX < 1 Then Return SetError(2,0,0)
    Local $struct = DllStructCreate("ptr[" & $maxIndX & "]", _MemGlobalLock($hMem) )
    Local $array[$maxIndX]
    For $i = 1 To $maxIndX
    $array[$i-1] = DllStructGetData($struct,1,$i)
    Next
    _MemGlobalUnlock($hMem)
    Return $array
    EndFunc
#ce
; Author: Prog@ndy
Func _MemArraySet($hMem, $indX, ByRef $stEntry)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0)
    Local $size = _MemGlobalSize($hMem)
    Local $iElSize = __MemArrayElementSize($hMem)

    Local $maxIndX = ($size - $__MemArray_HEADSIZE) / $iElSize
    If $indX < 0 Or $indX > $maxIndX Then Return SetError(2, 0, 0)
    Local $pEntry = _MemGlobalLock($hMem) + $__MemArray_HEADSIZE + $indX * $iElSize
    __MemZeroMemory($pEntry, $iElSize)
    If IsPtr($stEntry) Then
        __MemCopyMemory($stEntry, $pEntry, $iElSize)
    ElseIf IsDllStruct($stEntry) Then
        __MemCopyMemory(DllStructGetPtr($stEntry), $pEntry, $iElSize)
    Else
        Return SetError(2,0,0)
    EndIf
    _MemGlobalUnlock($hMem)
    Return 1
EndFunc   ;==>_MemArraySet
; Author: Prog@ndy
Func _MemArrayUBound($hMem)
    If Not IsPtr($hMem) Or $hMem = 0 Or Not __MemIsGlobal($hMem) Then Return SetError(1, 0, 0)
    Local $iElSize = __MemArrayElementSize($hMem)
    Return ((_MemGlobalSize($hMem) - $__MemArray_HEADSIZE) / $iElSize)
EndFunc   ;==>_MemArrayUBound

; Author: Prog@ndy
Func __MemIsGlobal($hMem)
    Local $result = __MemGlobalFlags($hMem)
    If @error Or $result == $GMEM_INVALID_HANDLE Then Return 0
    Return 1
EndFunc   ;==>__MemIsGlobal
; Author: Prog@ndy
Func __MemGlobalReAlloc($hMem, $iBytes, $iFlags)
    Local $aResult = DllCall("Kernel32.dll", "ptr", "GlobalReAlloc", "ptr", $hMem, "ulong", $iBytes, "uint", $iFlags)
    Return $aResult[0]
EndFunc   ;==>__MemGlobalReAlloc
; Author: Prog@ndy
Func __MemGlobalFlags($hMem)
    Local $aResult = DllCall("Kernel32.dll", "uint", "GlobalFlags", "ptr", $hMem)
    Return $aResult[0]
EndFunc   ;==>__MemGlobalFlags
; Author: Prog@ndy
Func __MemGlobalDiscard($hMem)
    Return __MemGlobalReAlloc($hMem, 0, $GMEM_MOVEABLE)
EndFunc   ;==>__MemGlobalDiscard
; Author: Prog@ndy
Func __MemCopyMemory($pSource, $pDest, $iLength)
    DllCall("msvcrt.dll", "none:cdecl", "memcpy", "ptr", $pDest, "ptr", $pSource, "dword", $iLength)
EndFunc   ;==>__MemCopyMemory
; Author: Prog@ndy
Func __MemFillMemory($pDest, $ubFill, $iLength)
    DllCall("kernel32.dll", "none", "RtlFillMemory", "ptr", $pDest, "dword", $iLength, "ubyte", $ubFill)
EndFunc   ;==>__MemFillMemory
; Author: Prog@ndy
Func __MemZeroMemory($pDest, $iLength)
    DllCall("kernel32.dll", "none", "RtlZeroMemory", "ptr", $pDest, "dword", $iLength)
EndFunc   ;==>__MemZeroMemory

😷

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...