Jump to content

help with DllStructCreate/DllStructGetData


 Share

Go to solution Solved by FireFox,

Recommended Posts

made a post about this yesterday but got no replies and i think i didn't ask my question very well...

i'm using _ClipBoard_GetDataEx in a loop to grab all available formats in the clipboard and i want to store the data in an array

i think i need to use DllStructCreate and DllStructGetData to get the data from the handle returned by _ClipBoard_GetDataEx, and therein lies my problem; i don't know what the hell i'm doing when it comes to dll stuff :

here's the [non-working] code i have...

Global $avClip

_ClipBoard_Open(0)

Do
    $iFormat = _ClipBoard_EnumFormats($iFormat)
    If $iFormat = 0 Then ContinueLoop
    $hMem = _ClipBoard_GetDataEx($iFormat)
    If $hMem = 0 Then ContinueLoop

    $tStruct  = DllStructCreate("PTR", $hMem) ; <<< obviously very wrong, but it's the best i could come up with
    $vData = DllStructGetData($tStruct, 1) ; <<< probably very wrong also

    ReDim $avClip[UBound($avClip) + 1][2]
    $avClip[0][0] += 1
    $avClip[UBound($avClip) - 1][0] = $vData
    $avClip[UBound($avClip) - 1][1] = $iFormat

Until $iFormat = 0

_ClipBoard_Close()

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Link to comment
Share on other sites

$hMemory = _ClipBoard_GetDataEx($CF_TEXT)
If $hMemory = 0 Then _WinAPI_ShowError("_ClipBoard_GetDataEx failed")
$tData = DllStructCreate("char Text[8192]", $hMemory)
 MemoWrite(DllStructGetData($tData, "Text"))

i have - the problem is that i'm wanting to run _ClipBoard_GetDataEx in a loop and i have no idea what the formats may be  -  i'm not trying to retrieve a known format, but rather everything on the clipboard, so i don't know how to write "DllStructCreate("char Text[8192]", $hMemory)" when i don't know the format

i want to do basically the same thing as _ClipBoard_GetAll in the examples forum, but i would like to eliminate the memory/mem copy stuff and just store the actual clipboard data, in all formats, in an array

so basically my question is how to get the data from the handle that _ClipBoard_GetDataEx returns?

Edited by iCode

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Link to comment
Share on other sites

Try this :

#include <ClipBoard.au3>
#include <Array.au3>

Example()

Func Example()
    ; Open the ClipBoard
    _ClipBoard_Open(0)

    ; Enumerate clipboard formats
    Local $iCount = _ClipBoard_CountFormats()
    If $iCount = 0 Then Return False

    Local $aFormats[$iCount]
    Local $iFormat = 0

    For $i = 0 To $iCount - 1
        $iFormat = _ClipBoard_EnumFormats($iFormat)
        $aFormats[$i] = $iFormat
    Next

    Local $aData[$iCount]
    Local $hMemory = 0, $pMemoryBlock = 0, $tData = 0

    For $i = 0 To $iCount - 1
        $hMemory = _ClipBoard_GetDataEx($aFormats[$i])

        $pMemoryBlock = _MemGlobalLock($hMemory)

        If $pMemoryBlock = 0 Then
            _ClipBoard_Close()
            Return False
        EndIf

        ; Get the actual memory size of the ClipBoard memory object (in bytes)
        Local $iDataSize = _MemGlobalSize($hMemory)

        If $iDataSize = 0 Then
            _MemGlobalUnlock($hMemory)
            _ClipBoard_Close()
            Return False
        EndIf

        ; Binary data return for all formats
        $tData = DllStructCreate("byte[" & $iDataSize & "]", $pMemoryBlock)

        ; Grab the data from the Structure so the Memory can be unlocked
        $aData[$i] = DllStructGetData($tData, 1)

        ; Unlock the memory
        _MemGlobalUnlock($hMemory)
    Next

    ; Close the ClipBoard
    _ClipBoard_Close()

    _ArrayDisplay($aData)
EndFunc   ;==>Example

Br, FireFox.

Link to comment
Share on other sites

i do appreciate the help :)

now i'll add what i should have said in the beginning; after backing up the clipboard, i then need to restore it from the array

i added an element to your array to store the format, but _ClipBoard_SetDataEx fails in the 2nd function because, i assume, the array is holding only binary and i'm feeding _ClipBoard_SetDataEx binary data instead of a handle and an incorrect format type for that data

here's what i have...

#include <ClipBoard.au3>
#include <Array.au3>

Global $avClip

ConsoleWrite("----- GET -----" & @LF)
_Clipboard_GetAll()
ConsoleWrite("_Clipboard_GetAll error = " & @error & @LF)
If @error Then Exit
_ArrayDisplay($avClip)
ConsoleWrite("----- PUT -----" & @LF)
_ClipBoard_PutAll($avClip)
ConsoleWrite("_ClipBoard_PutAll error = " & @error & @LF)

Func _Clipboard_GetAll()

    Local $iErr = 0, $iFormat = 0, $hMem = 0, $pMemBlk = 0, $iSize = 0, $tData, $bData

    If _ClipBoard_Open(0) = False Then Return SetError(1, 0, 0)

    Dim $avClip[1][2]

    While 1

        $iFormat = _ClipBoard_EnumFormats($iFormat)
        If $iFormat = 0 Then ExitLoop

        $hMem = _ClipBoard_GetDataEx($iFormat)
        If $hMem = 0 Then
            ConsoleWrite("$hMem=0" & @LF)
            ContinueLoop
        EndIf

        $pMemBlk = _MemGlobalLock($hMem)
        If $pMemBlk = 0 Then
            $iErr = 2
            ExitLoop
        EndIf

        ; Get the actual memory size of the ClipBoard memory object (in bytes)
        $iSize = _MemGlobalSize($hMem)
        If $iSize = 0 Then
            _MemGlobalUnlock($hMem)
            $iErr = 3
            ExitLoop
        EndIf

        ; Binary data return for all formats
        $tData = DllStructCreate("byte[" & $iSize & "]", $pMemBlk)
        ; Grab the data from the Structure so the Memory can be unlocked
        $bData = DllStructGetData($tData, 1)

        ; Unlock the memory
        _MemGlobalUnlock($hMem)

        ReDim $avClip[UBound($avClip) + 1][2]
        $avClip[0][0] += 1
        $avClip[UBound($avClip) - 1][0] = $bData
        $avClip[UBound($avClip) - 1][1] = $iFormat

    WEnd

    _ClipBoard_Close()

    If $iErr Then Return SetError($iErr, 0, 0)
    Return 1

EndFunc   ;==>Example

Func _ClipBoard_PutAll(ByRef $avClip)

    Local $iErr = 0

    If Not IsArray($avClip) Or UBound($avClip, 0) <> 2 Or $avClip[0][0] < 1 Then Return SetError(1, 0, 0)

    If Not _ClipBoard_Open(0) Then Return SetError(2, 0, 0)
    If Not _ClipBoard_Empty() Then
        _ClipBoard_Close()
        Return SetError(3, 0, 0)
    EndIf
    If Not _ClipBoard_Close() Then Return SetError(4, 0, 0)
    If Not _ClipBoard_Open(0) Then Return SetError(5, 0, 0)

    For $i = 1 To $avClip[0][0]
        If _ClipBoard_SetDataEx($avClip[$i][0], $avClip[$i][1]) = 0 Then ; <<< here's where it explodes
            $iErr = 6
            ExitLoop
        EndIf
    Next

    _ClipBoard_Close()

    If $iErr Then Return SetError($iErr, 0, 0)
    Return 1

EndFunc

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Link to comment
Share on other sites

that's what i'm going to use i think

i was trying to do basically the same thing without having to free the memory if the data wasn't put back, hence storing it in an array

sorry for the bother :)

FUNCTIONS: WinDock (dock window to screen edge) | EditCtrl_ToggleLineWrap (line/word wrap for AU3 edit control) | SendEX (yet another alternative to Send( ) ) | Spell Checker (Hunspell wrapper) | SentenceCase (capitalize first letter of sentences)

CODE SNIPPITS: Dynamic tab width (set tab control width according to window width)

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...