Jump to content

Recommended Posts

Posted

first of all i'm sorry for posting a support request into the dev forum.

but everytime i posted something like this into the support forum, i never got helped.

so i'll try my luck here today :(

I'm trying to copy a file into the clipboard that explorer can paste.

here is how far i got:

CODE
;~ ' format of CF_HDROP and CF_PRINTERS, in the HDROP case the data that follows

;~ ' is a double null terminated list of file names, for printers they are printer

;~ ' friendly names

;~ '

;~ TYPE DROPFILES

;~ pFiles AS DWORD ' offset of file list

;~ pt AS POINTAPI ' drop point (client coords)

;~ fNC AS LONG ' is it on NonClient area and pt is in screen coords

;~ fWide AS LONG ' WIDE character switch

;~ END TYPE

;~ TYPE POINTAPI

;~ x AS LONG

;~ y AS LONG

;~ END TYPE

$sFile = @ScriptFullPath

$nBuffSize = StringLen($sFile) + 2

$POINTAPI = DllStructCreate("int;int")

$DROPFILES = DllStructCreate("dword;ptr;int;int;char["&$nBuffSize&"]")

DllStructSetData($DROPFILES,2,DllStructGetPtr($POINTAPI))

DllStructSetData($DROPFILES,1,DllStructGetSize($DROPFILES) - $nBuffSize)

; uncomment the next line and comment out the last one to crash you explorer :D

;DllStructSetData($DROPFILES,1,DllStructGetPtr($DROPFILES,5))

DllStructSetData($DROPFILES,5,$sFile & "||")

For $i = 1 To $nBuffSize

; Replacing '|' with chr(0)

If DllStructGetData($DROPFILES,5,$i) = 124 Then DllStructSetData($DROPFILES,5,0,$i)

Next

$r = DllCall("user32.dll","int","OpenClipboard","hwnd",0)

If @error Or $r[0] = 0 Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

$r = DllCall("user32.dll","int","EmptyClipboard")

If @error Or $r[0] = 0 Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

;~ HGLOBAL GlobalAlloc(

;~ UINT uFlags,

;~ SIZE_T dwBytes

;~ );

$GMEM_MOVEABLE = 0x0002

$r = DllCall("kernel32.dll","long","GlobalAlloc","int",$GMEM_MOVEABLE,"int",DllStructGetSize($DROPFILES)+1)

If @error Or $r[0] < 1 Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

$hGlobal = $r[0]

;~ LPVOID GlobalLock(

;~ HGLOBAL hMem

;~ );

$r = DllCall("kernel32.dll","long","GlobalLock","long",$hGlobal)

If @error Or $r[0] < 1 Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

$hLock = $r[0]

; DECLARE SUB MoveMemory LIB "KERNEL32.DLL" ALIAS "RtlMoveMemory" (pDestination AS ANY, pSource AS ANY, BYVAL cbLength AS LONG)

$r = DllCall("kernel32.dll","none","RtlMoveMemory","long",$hLock,"long",DllStructGetPtr($DROPFILES),"int",DllStructGetSize($DROPFILES))

If @error Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

;~ HANDLE SetClipboardData(

;~ UINT uFormat,

;~ HANDLE hMem

;~ );

$CF_HDROP = 15

$r = DllCall("user32.dll","long","SetClipboardData","int",$CF_HDROP,"long",$hGlobal)

If @error Or $r[0] < 1 Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

$r = DllCall("user32.dll","int","CloseClipboard")

If @error Or $r[0] = 0 Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

;~ BOOL GlobalUnlock(

;~ HGLOBAL hMem

;~ );

$r = DllCall("kernel32.dll","int","GlobalUnlock","long",$hGlobal)

If @error Or _LastError() > 0 Then ConsoleWrite("Error: " & FileReadLine(@ScriptFullPath,@ScriptLineNumber-1))

Func _LastError()

Local $r = DllCall("kernel32.dll","int","GetLastError")

Return $r[0]

EndFunc

the only example for DROPFILES i found is here, but i dont get it :)
CODE
#include "stdafx.h"

#include "DropFiles.h"

CDropFiles::CDropFiles()

{

m_pBuff = NULL;

m_nBuffSize = 0;

}

CDropFiles::~CDropFiles()

{

delete m_pBuff;

}

void CDropFiles::AddFile(const CString &sFile)

{

m_aFiles.Add(sFile);

}

void CDropFiles::CreateBuffer()

{

// CreateBuffer must be called once, when all Files are added!!!

ASSERT(m_pBuff == NULL);

ASSERT(m_nBuffSize == 0);

for(int i=0;i<m_aFiles.GetSize();i++){

m_nBuffSize += m_aFiles.GetLength()+1;

}

m_nBuffSize += sizeof(DROPFILES)+2;

m_nBuffSize = (m_nBuffSize/32 + 1)*32;

int nBuffSize = 0;

m_pBuff = new char[m_nBuffSize];

ZeroMemory(m_pBuff, m_nBuffSize);

((DROPFILES*)m_pBuff)->pFiles = sizeof(DROPFILES);

char* pCurrent = m_pBuff + sizeof(DROPFILES);

for(i=0;i<m_aFiles.GetSize();i++){

strcpy(pCurrent,(LPCTSTR)m_aFiles);

pCurrent += m_aFiles.GetLength();

*pCurrent = 0;

pCurrent++;

}

//check buffer bound

ASSERT(pCurrent - m_nBuffSize - 1 <= m_pBuff);

}

void* CDropFiles::GetBuffer() const

{

ASSERT(m_pBuff);

return (void *)m_pBuff;

}

int CDropFiles::GetBuffSize() const

{

ASSERT(m_nBuffSize);

return m_nBuffSize;

}

CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map
Posted

finaly, success :)

Opt('MustDeclareVars',1)

; Tests
Local $fTest
If @Compiled Then
    ConsoleWrite("Tests dont work with compiled script" & @CR)
    Exit
EndIf
; Single File
$fTest = _ClipPutFile(@ScriptFullPath)
If Not $fTest Then
    ConsoleWrite("Test 1 Failed -> " & @error & @CR)
Else
    ConsoleWrite("Test 1 Result:" & @CR & ClipGet() & @CR)
EndIf

; Multiple files
$fTest = _ClipPutFile(@ScriptFullPath & "|" & @AutoItExe)
If Not $fTest Then
    ConsoleWrite("Test 2 Failed -> " & @error & @CR)
Else
    ConsoleWrite("Test 2 Result:" & @CR & ClipGet() & @CR)
EndIf

; Seperator
$fTest = _ClipPutFile(@ScriptFullPath & "$" & @AutoItExe,"$")
If Not $fTest Then
    ConsoleWrite("Test 3 Failed -> " & @error & @CR)
Else
    ConsoleWrite("Test 3 Result:" & @CR & ClipGet() & @CR)
EndIf

Func _ClipPutFile($sFile, $sSeperator = "|")
    Local $vDllCallTmp, $nGlobMemSize, $hGlobal, $DROPFILES, $i, $hLock
    Local $GMEM_MOVEABLE = 0x0002, $CF_HDROP = 15
    $sFile = $sFile & $sSeperator & $sSeperator
    $nGlobMemSize = StringLen($sFile) + 20; 20 = size of DROPFILES whitout buffer
    $vDllCallTmp = DllCall("user32.dll", "int", "OpenClipboard", "hwnd", 0)
    If @error Or $vDllCallTmp[0] = 0 Then
        SetError(1)
        Return False
    EndIf
    $vDllCallTmp = DllCall("user32.dll", "int", "EmptyClipboard")
    If @error Or $vDllCallTmp[0] = 0 Then
        SetError(2)
        Return False
    EndIf
    $vDllCallTmp = DllCall("kernel32.dll", "long", "GlobalAlloc", "int", $GMEM_MOVEABLE, "int", $nGlobMemSize)
    If @error Or $vDllCallTmp[0] < 1 Then
        SetError(3)
        Return False
    EndIf
    $hGlobal = $vDllCallTmp[0]
    $vDllCallTmp = DllCall("kernel32.dll", "long", "GlobalLock", "long", $hGlobal)
    If @error Or $vDllCallTmp[0] < 1 Then
        SetError(4)
        Return False
    EndIf
    $hLock = $vDllCallTmp[0]
    
    $DROPFILES = DllStructCreate("dword;ptr;int;int;int;char[" & StringLen($sFile) & "]", $hLock)
    If @error Then
        SetError(5)
        Return False
    EndIf
    DllStructSetData($DROPFILES, 1, DllStructGetSize($DROPFILES) - StringLen($sFile))
    DllStructSetData($DROPFILES, 2, 0)
    DllStructSetData($DROPFILES, 3, 0)
    DllStructSetData($DROPFILES, 4, 0)
    DllStructSetData($DROPFILES, 5, 0)
    DllStructSetData($DROPFILES, 6, $sFile)
    For $i = 1 To StringLen($sFile)
        If DllStructGetData($DROPFILES, 6, $i) = Asc($sSeperator) Then DllStructSetData($DROPFILES, 6, 0, $i)
    Next
    $vDllCallTmp = DllCall("user32.dll", "long", "SetClipboardData", "int", $CF_HDROP, "long", $hGlobal)
    If @error Or $vDllCallTmp[0] < 1 Then
        SetError(6)
        $DROPFILES = 0
        Return False
    EndIf
    $vDllCallTmp = DllCall("user32.dll", "int", "CloseClipboard")
    If @error Or $vDllCallTmp[0] = 0 Then
        SetError(7)
        $DROPFILES = 0
        Return False
    EndIf
    $vDllCallTmp = DllCall("kernel32.dll", "int", "GlobalUnlock", "long", $hGlobal)
    If @error Then
        SetError(8)
        $DROPFILES = 0
        Return False
    EndIf
    $vDllCallTmp = DllCall("kernel32.dll", "int", "GetLastError")
    If $vDllCallTmp = 0 Then 
        $DROPFILES = 0
        Return False
    Else
        SetError(8)
        $DROPFILES = 0
        Return True
    EndIf
EndFunc  ;==>_ClipPutFile
CoProc Multi Process Helper libraryTrashBin.nfshost.com store your AutoIt related files here!AutoIt User Map

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...