#include-once #include Func _Clipboard_GetAll(ByRef $avClip) Local $iFormat = 0, $hMem, $hMem_new, $pSource, $pDest, $iSize, $iErr = 0, $iErr2 = 0 Dim $avClip[1][2] If Not _ClipBoard_Open(0) Then Return SetError(-1, 0, 0) Do $iFormat = _ClipBoard_EnumFormats($iFormat) If $iFormat <> 0 Then ReDim $avClip[UBound($avClip) + 1][2] $avClip[0][0] += 1 ; aClip[n][0] = iFormat, aClip[n][1] = hMem $avClip[UBound($avClip) - 1][0] = $iFormat $hMem = _ClipBoard_GetDataEx($iFormat) If $hMem = 0 Then $iErr += 1 ContinueLoop EndIf $pSource = _MemGlobalLock($hMem) $iSize = _MemGlobalSize($hMem) $hMem_new = _MemGlobalAlloc($iSize, $GHND) $pDest = _MemGlobalLock($hMem_new) _MemCopyMemory($pSource, $pDest, $iSize) If @error Then $iErr2 += 1 _MemGlobalUnlock($hMem) _MemGlobalUnlock($hMem_new) $avClip[UBound($avClip) - 1][1] = $hMem_new EndIf Until $iFormat = 0 _ClipBoard_Close() ; Return: ; | 0 - no errors ; |-2 - _MemGlobalAlloc errors ; |-4 - _MemCopyMemory errors ; |-6 - both errors ; @extended: ; - total number of errors Local $ErrRet = 0 If $iErr Then $ErrRet -= 2 If $iErr2 Then $ErrRet -= 4 If $ErrRet Then Return SetError($ErrRet, $iErr + $iErr2, 0) Else Return 1 EndIf EndFunc Func _ClipBoard_PutAll(ByRef $avClip) ; DO NOT free the memory handles after a call to this function ; the system now owns the memory Local $iErr = 0 If Not IsArray($avClip) Or UBound($avClip, 0) <> 2 Or $avClip[0][0] <= 0 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 ; seems to work without closing / reopening the clipboard, but MSDN implies we should do this ; since a call to EmptyClipboard after opening with a NULL handle sets the owner to NULL, ; and SetClipboardData is supposed to fail, so we close and reopen it to be safe _ClipBoard_Close() If Not _ClipBoard_Open(0) Then Return SetError(-3, 0, 0) For $i = 1 To $avClip[0][0] If _ClipBoard_SetDataEx($avClip[$i][1], $avClip[$i][0]) = 0 Then $iErr += 1 Next _ClipBoard_Close() If $iErr Then Return SetError(-4, $iErr, 0) Else Return 1 EndIf EndFunc Func _Clipboard_MemFree(ByRef $avClip) Local $iErr = 0 If Not IsArray($avClip) Or UBound($avClip, 0) <> 2 Or $avClip[0][0] <= 0 Then Dim $avClip[1][2] Return SetError(-1, 0, 0) EndIf For $i = 1 To $avClip[0][0] If Not _MemGlobalFree($avClip[$i][1]) Then $iErr += 1 Next Dim $avClip[1][2] If $iErr Then Return SetError(-2, $iErr, 0) Else Return 1 EndIf EndFunc Func _MemCopyMemory($pSource, $pDest, $iLength) Local $aResult = DllCall("msvcrt.dll", "int:cdecl", "memcpy_s", "ptr", $pDest, "ulong_ptr", $iLength, "ptr", $pSource, "ulong_ptr", $iLength) If @error Then Return SetError(@error, 0, -1) Return SetError(Number($aResult[0] <> 0), 0, $aResult[0]) EndFunc