SEKOMD Posted yesterday at 09:12 AM Posted yesterday at 09:12 AM Hi everyone! Please tell me why the functions for getting/restoring the clipboard are unstable? Over time the error appears: !>12:03:17 AutoIt3.exe ended.rc:-1073740940 The error also appears when using functions from Nine. sorry for my english.. expandcollapse popup#include <WindowsConstants.au3> #include <WinApi.au3> #include <GDIPlus.au3> #include <ColorConstants.au3> #include <GUIConstantsEx.au3> #include <Misc.au3> #include <Array.au3> #include <WinAPISysWin.au3> #include <ColorConstants.au3> #include <GUIConstantsEx.au3> #include <Color.au3> #include <SCreencapture.au3> #include <GUIConstants.au3> #include <ScreenCapture.au3> #include <WindowsConstants.au3> #include <SendMessage.au3> #include <Clipboard.au3> OnAutoItExitRegister("__AutoItExit_ClipAll") Global $__bMemFree = False Global $avClip Global $aClip ;result - error For $x=1 to 1000 ConsoleWrite('Attemp ' & $x & @CRLF) ;_ScreenshotSendToClipBoard() Send('{PRINTSCREEN}') ;!important _ClipBoard_GetAll($avClip) ClipPut('test string..') _ClipBoard_PutAll($avClip) Next ;by wraithdu ;https://www.autoitscript.com/forum/topic/81267-_clipboard_getall-_clipboard_putall-_clipboard_wait/ Func _ClipBoard_GetAll(ByRef $avClip) Local $i = 0, $iFormat = 0, $hMem, $hMemNew, $pSource, $pDest, $iSize, $iErr = 0, $iErrEx = 0 If $__bMemFree = True Then __MemFree($avClip) Else Dim $avClip[1][2] EndIf If Not _ClipBoard_Open(0) Then Return SetError(1, 1, 0) Do $iFormat = _ClipBoard_EnumFormats($iFormat) If $iFormat = 0 Then ExitLoop $hMem = _ClipBoard_GetDataEx($iFormat) ; this can/will fail for some formats - don't know why yet, so let's continue without retutning an error If $hMem = 0 Then ContinueLoop ; copy the memory $pSource = _MemGlobalLock($hMem) If $pSource = 0 Then $iErr = 3 $iErrEx += 1 ExitLoop EndIf $iSize = _MemGlobalSize($hMem) $hMemNew = _MemGlobalAlloc($iSize, $GHND) If $hMemNew = 0 Then _MemGlobalUnlock($hMemNew) $iErr = 4 $iErrEx += 1 ExitLoop EndIf $pDest = _MemGlobalLock($hMemNew) If $pDest = 0 Then _MemGlobalFree($hMemNew) $iErr = 5 $iErrEx += 1 ExitLoop EndIf DllCall("msvcrt.dll", "int:cdecl", "memcpy_s", "ptr", $pDest, "ulong_ptr", $iSize, "ptr", $pSource, "ulong_ptr", $iSize) If @error Then $iErr = 6 $iErrEx += 1 EndIf _MemGlobalUnlock($hMem) _MemGlobalUnlock($hMemNew) $__bMemFree = True If $iErr = 6 Then __MemFree($avClip) ExitLoop EndIf ; add handle and format to array $i += 1 ReDim $avClip[$i + 1][2] $avClip[0][0] = $i $avClip[$i][0] = $hMemNew $avClip[$i][1] = $iFormat Until $iFormat = 0 If Not _ClipBoard_Close() Then $iErr = 5 If $iErr Then Return SetError($iErr, $iErrEx, 0) Return 1 EndFunc ;==>_ClipBoard_GetAll 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, $iErrEx = 0 ; , $bOpen, $iTime $__bMemFree = False If Not IsArray($avClip) Or UBound($avClip, 0) <> 2 Or $avClip[0][0] < 1 Then Dim $avClip[1][2] Return SetError(1, 1, 0) EndIf ; test if clipboard can be opened ; if _ClipBoard_Open failes, the clipboard is likely still being updated, so we keep trying until it succeeds ;Local $hTimer = TimerInit() ;Do ; $bOpen = _ClipBoard_Open(0) ; Sleep(50) ; $iTime = TimerDiff($hTimer) ;Until $bOpen = 1 Or $iTime >= 2000 ;If $bOpen = 0 Then ; Return SetError(2, 1, 0) ;EndIf ; empty clipboard If Not _ClipBoard_Open(0) Then Return SetError(2, 1, 0) ; comment out if using the code above If Not _ClipBoard_Empty() Then _ClipBoard_Close() Return SetError(3, 1, 0) EndIf If Not _ClipBoard_Close() Then Return SetError(4, 1, 0) ; re-open clipboard and put data If Not _ClipBoard_Open(0) Then Return SetError(5, 1, 0) For $i = 1 To $avClip[0][0] If Not _ClipBoard_SetDataEx($avClip[$i][0], $avClip[$i][1]) Then $iErr = 6 $iErrEx += 1 EndIf Next If Not _ClipBoard_Close() Then $iErr = 7 $iErrEx += 1 EndIf If $iErr Then Return SetError($iErr, $iErrEx, 0) Return 1 EndFunc ;==>_ClipBoard_PutAll Func __MemFree(ByRef $avClip) Local $iErr = 0, $iErrEx = 0 If $__bMemFree = False Then Return ElseIf Not IsArray($avClip) Or UBound($avClip, 0) <> 2 Or $avClip[0][0] < 1 Then Dim $avClip[1][2] $__bMemFree = False Return SetError(1, 1, 0) EndIf For $i = 1 To $avClip[0][0] If Not _MemGlobalFree($avClip[$i][1]) Then $iErr = 2 $iErrEx += 1 EndIf Next $__bMemFree = False Dim $avClip[1][2] If $iErr Then Return SetError($iErr, $iErrEx, 0) Return 1 EndFunc ;==>__MemFree Func __AutoItExit_ClipAll() #forcedef $avClip __MemFree($avClip) EndFunc ;==>__AutoItExit_ClipAll ;func by Nine Func _Clipboard_GetAll_byNine(ByRef $avClip) Local $iFormat = 0, $iNum If Not _ClipBoard_Open(0) Then Return SetError(-1, 0, 0) $iNum = _ClipBoard_CountFormats() Dim $avClip[$iNum + 1][2] $avClip[0][0] = $iNum For $i = 1 To $iNum $iFormat = _ClipBoard_EnumFormats($iFormat) $avClip[$i][0] = $iFormat Next _ClipBoard_Close() For $i = 1 To $iNum $avClip[$i][1] = _ClipBoard_GetData($avClip[$i][0]) Next EndFunc ;==>_Clipboard_GetAll_byNine Func _ClipBoard_PutAll_byNine(ByRef $avClip) Local $bEmpty, $iErr = 0 If Not _ClipBoard_Open(0) Then Return SetError(-2, 0, 0) $bEmpty = _ClipBoard_Empty() _ClipBoard_Close() If Not $bEmpty Then Return SetError(-3, 0, 0) For $i = 1 To $avClip[0][0] If _ClipBoard_SetData($avClip[$i][1], $avClip[$i][0]) = 0 Then $iErr += 1 Next If $iErr Then Return SetError(-4, $iErr, 0) Else Return 1 EndIf EndFunc ;==>_ClipBoard_PutAll_byNine Func _ScreenshotSendToClipBoard() _GDIPlus_Startup() Local $hBMP = _ScreenCapture_Capture() _ClipBoard_Open(0) Local $hBitmap = _WinAPI_CopyImage($hBMP, 0, 0, 0, BitOR($LR_COPYDELETEORG, $LR_COPYRETURNORG)) _ClipBoard_Empty() _ClipBoard_SetDataEx($hBitmap, $CF_BITMAP) _ClipBoard_Close() EndFunc ;==>_ScreenshotSendToClipBoard ;========================================================
Nine Posted yesterday at 11:37 AM Posted yesterday at 11:37 AM I do not get any error with both sets of functions. So I can only guess what could be the problem. My comp is recent and quite fast. Maybe the problem comes from the send. It might require some time to copy the screen to clipboard. Try put a sleep after, see if that helps. “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
SEKOMD Posted yesterday at 01:11 PM Author Posted yesterday at 01:11 PM (edited) 1 hour ago, Nine said: I do not get any error with both sets of functions. So I can only guess what could be the problem. My comp is recent and quite fast. Maybe the problem comes from the send. It might require some time to copy the screen to clipboard. Try put a sleep after, see if that helps. tried on a virtual machine VMware Workstation still an error.. clean Windows 11 LTSC installed.. Strange, what could this be connected with? The working machine is also Windows 11 LTSC 2024 Sorry the picture is big, I don't know how to make it smaller Edited yesterday at 01:12 PM by SEKOMD
Nine Posted yesterday at 02:44 PM Posted yesterday at 02:44 PM (edited) Sorry, I do not have Win11 nor a VM. Cannot test it. Got Win10 and working with no issue. You will need to debug and found the statement that creates the crash Edited yesterday at 02:46 PM by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
SEKOMD Posted 17 hours ago Author Posted 17 hours ago (edited) 11 hours ago, Nine said: You will need to debug and found the statement that creates the crash _ClipBoard_PutAll_byNine - supports restoring a screenshot in the clipboard (which was before), but does not support restoring the "file to insert" that was before in the clipboard _ClipBoard_PutAll - supports restoring the "file to insert" that was before in the clipboard, but does not support restoring a screenshot in the clipboard Please tell me, if it's not difficult, is it possible to somehow solve this? so that all the features work.. Edited 17 hours ago by SEKOMD
SEKOMD Posted 15 hours ago Author Posted 15 hours ago I managed to reproduce the problem, everything is clear from the code. There are no problems with reading/restoring text. Maybe someone can tell me how to solve this - I will be very grateful. expandcollapse popup#include <WindowsConstants.au3> #include <WinApi.au3> #include <GDIPlus.au3> #include <ColorConstants.au3> #include <GUIConstantsEx.au3> #include <Misc.au3> #include <Array.au3> #include <WinAPISysWin.au3> #include <ColorConstants.au3> #include <GUIConstantsEx.au3> #include <Color.au3> #include <SCreencapture.au3> #include <GUIConstants.au3> #include <ScreenCapture.au3> #include <WindowsConstants.au3> #include <SendMessage.au3> #include <Clipboard.au3> OnAutoItExitRegister("__AutoItExit_ClipAll") Global $__bMemFree = False Global $avClip Global $aClip MsgBox(64, '', 'copy something') ;==== Its works only if the script is compiled!! ==== _ScreenshotSendToClipBoard() Sleep(500) ;================================================ _ClipBoard_Open(0) $iFormat = 0 $iCount = 0 $iIsBitmapData=0 Do $iFormat = _ClipBoard_EnumFormats($iFormat) If $iFormat <> 0 Then $iCount += 1 if _ClipBoard_FormatStr($iFormat) = 'Bitmap' Then _ $iIsBitmapData=1 EndIf Until $iFormat = 0 _ClipBoard_Close() if $iIsBitmapData Then _Clipboard_GetAll_byNine($aClip) ClipPut('Test string for testing') MsgBox(64,'','New value clipboard: ' & ClipGet()) _ClipBoard_PutAll_byNine($aClip) MsgBox(64, '_ClipBoard_PutAll_byNine', 'check that the buffer has been restored') Exit EndIf _Clipboard_GetAll($avClip) ClipPut('Test string for testing') MsgBox(64,'','New value clipboard: ' & ClipGet()) _ClipBoard_PutAll($avClip) MsgBox(64, '_ClipBoard_PutAll', 'check that the buffer has been restored') ;by wraithdu ;https://www.autoitscript.com/forum/topic/81267-_clipboard_getall-_clipboard_putall-_clipboard_wait/ Func _ClipBoard_GetAll(ByRef $avClip) Local $i = 0, $iFormat = 0, $hMem, $hMemNew, $pSource, $pDest, $iSize, $iErr = 0, $iErrEx = 0 If $__bMemFree = True Then __MemFree($avClip) Else Dim $avClip[1][2] EndIf If Not _ClipBoard_Open(0) Then Return SetError(1, 1, 0) Do $iFormat = _ClipBoard_EnumFormats($iFormat) If $iFormat = 0 Then ExitLoop $hMem = _ClipBoard_GetDataEx($iFormat) ; this can/will fail for some formats - don't know why yet, so let's continue without retutning an error If $hMem = 0 Then ContinueLoop ; copy the memory $pSource = _MemGlobalLock($hMem) If $pSource = 0 Then $iErr = 3 $iErrEx += 1 ExitLoop EndIf $iSize = _MemGlobalSize($hMem) $hMemNew = _MemGlobalAlloc($iSize, $GHND) If $hMemNew = 0 Then _MemGlobalUnlock($hMemNew) $iErr = 4 $iErrEx += 1 ExitLoop EndIf $pDest = _MemGlobalLock($hMemNew) If $pDest = 0 Then _MemGlobalFree($hMemNew) $iErr = 5 $iErrEx += 1 ExitLoop EndIf DllCall("msvcrt.dll", "int:cdecl", "memcpy_s", "ptr", $pDest, "ulong_ptr", $iSize, "ptr", $pSource, "ulong_ptr", $iSize) If @error Then $iErr = 6 $iErrEx += 1 EndIf _MemGlobalUnlock($hMem) _MemGlobalUnlock($hMemNew) $__bMemFree = True If $iErr = 6 Then __MemFree($avClip) ExitLoop EndIf ; add handle and format to array $i += 1 ReDim $avClip[$i + 1][2] $avClip[0][0] = $i $avClip[$i][0] = $hMemNew $avClip[$i][1] = $iFormat Until $iFormat = 0 If Not _ClipBoard_Close() Then $iErr = 5 If $iErr Then Return SetError($iErr, $iErrEx, 0) Return 1 EndFunc ;==>_ClipBoard_GetAll 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, $iErrEx = 0 ; , $bOpen, $iTime $__bMemFree = False If Not IsArray($avClip) Or UBound($avClip, 0) <> 2 Or $avClip[0][0] < 1 Then Dim $avClip[1][2] Return SetError(1, 1, 0) EndIf ; test if clipboard can be opened ; if _ClipBoard_Open failes, the clipboard is likely still being updated, so we keep trying until it succeeds ;Local $hTimer = TimerInit() ;Do ; $bOpen = _ClipBoard_Open(0) ; Sleep(50) ; $iTime = TimerDiff($hTimer) ;Until $bOpen = 1 Or $iTime >= 2000 ;If $bOpen = 0 Then ; Return SetError(2, 1, 0) ;EndIf ; empty clipboard If Not _ClipBoard_Open(0) Then Return SetError(2, 1, 0) ; comment out if using the code above If Not _ClipBoard_Empty() Then _ClipBoard_Close() Return SetError(3, 1, 0) EndIf If Not _ClipBoard_Close() Then Return SetError(4, 1, 0) ; re-open clipboard and put data If Not _ClipBoard_Open(0) Then Return SetError(5, 1, 0) For $i = 1 To $avClip[0][0] If Not _ClipBoard_SetDataEx($avClip[$i][0], $avClip[$i][1]) Then $iErr = 6 $iErrEx += 1 EndIf Next If Not _ClipBoard_Close() Then $iErr = 7 $iErrEx += 1 EndIf If $iErr Then Return SetError($iErr, $iErrEx, 0) Return 1 EndFunc ;==>_ClipBoard_PutAll Func __MemFree(ByRef $avClip) Local $iErr = 0, $iErrEx = 0 If $__bMemFree = False Then Return ElseIf Not IsArray($avClip) Or UBound($avClip, 0) <> 2 Or $avClip[0][0] < 1 Then Dim $avClip[1][2] $__bMemFree = False Return SetError(1, 1, 0) EndIf For $i = 1 To $avClip[0][0] If Not _MemGlobalFree($avClip[$i][1]) Then $iErr = 2 $iErrEx += 1 EndIf Next $__bMemFree = False Dim $avClip[1][2] If $iErr Then Return SetError($iErr, $iErrEx, 0) Return 1 EndFunc ;==>__MemFree Func __AutoItExit_ClipAll() #forcedef $avClip __MemFree($avClip) EndFunc ;==>__AutoItExit_ClipAll ;func by Nine Func _Clipboard_GetAll_byNine(ByRef $aClip) Local $iFormat = 0, $iNum If Not _ClipBoard_Open(0) Then Return SetError(-1, 0, 0) $iNum = _ClipBoard_CountFormats() Dim $avClip[$iNum + 1][2] $avClip[0][0] = $iNum For $i = 1 To $iNum $iFormat = _ClipBoard_EnumFormats($iFormat) $avClip[$i][0] = $iFormat Next _ClipBoard_Close() For $i = 1 To $iNum $avClip[$i][1] = _ClipBoard_GetData($avClip[$i][0]) Next EndFunc ;==>_Clipboard_GetAll_byNine Func _ClipBoard_PutAll_byNine(ByRef $aClip) Local $bEmpty, $iErr = 0 If Not _ClipBoard_Open(0) Then Return SetError(-2, 0, 0) $bEmpty = _ClipBoard_Empty() _ClipBoard_Close() If Not $bEmpty Then Return SetError(-3, 0, 0) For $i = 1 To $avClip[0][0] If _ClipBoard_SetData($avClip[$i][1], $avClip[$i][0]) = 0 Then $iErr += 1 Next If $iErr Then Return SetError(-4, $iErr, 0) Else Return 1 EndIf EndFunc ;==>_ClipBoard_PutAll_byNine Func _ScreenshotSendToClipBoard() _GDIPlus_Startup() Local $hBMP = _ScreenCapture_Capture() _ClipBoard_Open(0) Local $hBitmap = _WinAPI_CopyImage($hBMP, 0, 0, 0, BitOR($LR_COPYDELETEORG, $LR_COPYRETURNORG)) _ClipBoard_Empty() _ClipBoard_SetDataEx($hBitmap, $CF_BITMAP) _ClipBoard_Close() EndFunc ;==>_ScreenshotSendToClipBoard ;========================================================
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now