Sign in to follow this  
Followers 0
iCode

help with DllStructCreate/DllStructGetData

7 posts in this topic

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)

Share this post


Link to post
Share on other sites



Hi,

Have you looked at the example in the help file?

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

$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)

Share this post


Link to post
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.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
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)

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

huh, then what's wrong with the function available in the forum? It does exactly what you're looking for...

Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
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)

Share this post


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
Sign in to follow this  
Followers 0