Clear Posted December 5, 2018 Share Posted December 5, 2018 Hey, First, I am really sorry for this question. I have searched for the answer for several minutes, in Help File and via Google, but can't answer it by myself. I am new to AutoIt. Before I have used AutoHotkey for simple improvements of my work station. Unfortunately, IT decided to update OS to Windows 10, and with that, AutoHotkey was removed and instead AutoIt has been given. Unfortunately, I need to learn syntax, and as for me, it's more weird syntax for simple tasks (however I must admit, GUI is easier). What is my problem is that Send and ControlSend commands are not as effective as in case of SendInput. I want to create some templates with hotkeys and gui. Unfortunately, Send is too slow for bigger templates (text is pasted in SunAwtFrame class (program created in Java) with no ControlId. That's why I wanted to use Clipboard to make it work faster. In AutoHotkey it would be something like: ClipCopy := ClipboardAll Clipboard = Template to send Send, ^v Clipboard := ClipCopy ClipCopy = Unfortunately, something similar doesn't work in AutoIt: Local $ClipCopy = _Clipboard_GetData() ClipPut("Template to Send") Send("^v") _Clipboard_SetData($ClipCopy) It works only for text. I know that's because it need additional parameter for storing other type of content, but how am i supposed to know, what will be stored in clipboard? Is there any other way to achieve what I am trying to do? Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted December 5, 2018 Share Posted December 5, 2018 (edited) Hi @Clear, and welcome to the AutoIt forums If you look closely in the Help file about _Clipboard_GetData(), you'll see that you can specify the format of its content, so, if you want to get a previous copied bitmap, you can (and have to) specify the $iFormat parameter as $CF_BITMAP. And, the same is for _Clipboard_SetData() Edited December 5, 2018 by FrancescoDiMuro Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Clear Posted December 6, 2018 Author Share Posted December 6, 2018 (edited) Próbowałem, ale po wybraniu tej opcji, w ogóle nie działa, chyba że coś źle robię. Nie działa wtedy ani dla tekstu, ani obrazków, ani niczego innego. W przypadku obrazków, przy próbie wklejenia, pojawia się komunikat (do innych programów oczywiście tez nie działa) I tried, but after choosing this option, it doesn't work at all or I'm not doing it properly. It doesn't work for text, nor images, neither anything else. In case of images, when trying to paste, there is error: Quote --------------------------- Paint --------------------------- Clipboard cannot be pasted into Paint --------------------------- OK --------------------------- Kod: Func Text($Text) Local $Clip = _ClipBoard_GetData($CF_BITMAP) ClipPut($Text) Send("^v") _ClipBoard_SetData($Clip, $CF_BITMAP) EndFunc Edited December 6, 2018 by Clear Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted December 6, 2018 Share Posted December 6, 2018 @Clear Maybe this could be helpful pixelsearch 1 Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
Clear Posted December 6, 2018 Author Share Posted December 6, 2018 (edited) It seems like _Clipboard_GetData, _Clipboard_SetData and ...Ex functions are not working with $iFormat set to $CF_BITMAP in my workstation (Windows 10 64-bit) or I am doing it in wrong way. So something which I could acomplish with just few lines in AutoHotkey doesn't seem to work at all with AutoIt or I don't know how Once again, I will write what I am trying to do: Creating simple script that will bind hotkeys for quickly writing written templates (it's ok) #include <GUIConstantsEx.au3> #include <Clipboard.au3> HotKeySet("^{NUMPAD1}", TemplatesGreeting) HotKeySet("^{NUMPAD2}", TemplatesFarewell) HotkeySet("^{NUMPAD3}", TemplatesVerification) Opt("SendKeyDelay", 0) While 1 Sleep(100) WEnd While entering hotkey, GUI with templates' categories' buttons will appear. Clicking buttons should send templates. expandcollapse popupFunc TemplatesFarewell() Local $GUI1 = GUICreate("Farewell GUI", 275, 400) GUICtrlCreateLabel("Choose radio button", 10, 10) Local $FormRadio1 = GUICtrlCreateRadio("R1", 10, 40) Local $FormRadio2 = GUICtrlCreateRadio("R_2", 60, 40) GUICtrlCreateLabel("Choose Template to use:", 10, 100) Local $Button1 = GUICtrlCreateButton("Template #1", 10, 125, 250, 25) Local $Button2 = GUICtrlCreateButton("Template #2", 10, 160, 250, 25) Local $Button3 = GUICtrlCreateButton("Template #3", 10, 195, 250, 25) GUISetState(@SW_SHOW) ; HERE STARTS PROBLEM Local $FirstText = "Bye :)" While 1 Switch GUIGetMsg() Case $FormRadio1 $FirstText = "Bye :)" Case $FormRadio2 $FirstText = "Goodbye :)" Case $Button1 ; By using Send GUIDelete($GUI1) Send($FirstText & @CRLF & "Thanks for nothing! Here I will add some local chars like ąćęóńżź") ; Problem - it's slow. Otherwise, works fine Case $Button2 ; By using ControlSend GUIDelete($GUI1) ControlSend("Active Conversations", "", "", $FirstText & ". Thanks for anything - Some local chars like ąćęóńźż") ; It seems it works faster, but Polish chars are not displayed :( That's why I need to use something else ; The program to send is SunAwtFrame class (Jp2Launcher - Java) Case $Button3 ; By Using SendText (Clipboard) GUIDelete($GUI1) SendText($FirstText & ". This is some text. Blebleble." & @CRLF & "Have a nice day") Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($GUI1) EndFunc Func SendText($Text) ; User can have something in Clipboard - we store it to retrieve it later to make sure nothing is lost. Local $Clip = _ClipBoard_GetData($CF_BITMAP) ; Once we have saved clipboard content, we change clipboard to our template and send it ClipPut($Text) Send("^v") ; Now it's time to retrieve our clipboard from memory _ClipBoard_SetData($Clip, $CF_BITMAP) EndFunc EDIT: I am really sorry. I didn't notice till now, my previous post was written not in English. I edited it Edited December 6, 2018 by Clear Link to comment Share on other sites More sharing options...
pixelsearch Posted December 6, 2018 Share Posted December 6, 2018 Hi Clear, I just studied a bit UEZ's script to fill the Clipboard with an image, who knows, maybe it will help you one day, even if it seems simpler with AutoHotkey Translating your 2nd polish post with google shows that you also want to put images in clipboard and it didn't work, so this script could be helpful : expandcollapse popup; Based on UEZ's script #include <Clipboard.au3> #include <GDIPlus.au3> #include <MsgBoxConstants.au3> Local $sImageName = "G:\temp\cherry.jpg" ; Initialize GDI+ library _GDIPlus_Startup() ; Create a bitmap object from file $hClipboard_Bitmap = _GDIPlus_BitmapCreateFromFile($sImageName) ; Create a handle to a bitmap from a bitmap object $hClipboard_BitmapGDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hClipboard_Bitmap) ; Release a bitmap object (not needed anymore) _GDIPlus_BitmapDispose($hClipboard_Bitmap) ; Shut down GDI+ library _GDIPlus_Shutdown() ; Create a new image (bitmap) and copy the attributes of the specified image to the new one $hHBmp_Clipboard = _WinAPI_CopyImage($hClipboard_BitmapGDI, 0, 0, 0, _ BitOR($LR_COPYDELETEORG, $LR_COPYRETURNORG)) ; Open Clipboard, empty it, fill it with the image, close Clipboard $iReturn = _WinAPI_Bitmap2Clipboard($hHBmp_Clipboard) If $iReturn = 0 Then Msgbox($MB_TOPMOST, "Ok", "Clipboard contains the image") Else Msgbox($MB_TOPMOST, "Error", $iReturn) EndIf ; ========================================= Func _WinAPI_Bitmap2Clipboard($hHBitmap) If Not _ClipBoard_Open(0) Then Return 1 If Not _ClipBoard_Empty() Then Return 2 Local Const $hCP = _ClipBoard_SetDataEx($hHBitmap, $CF_BITMAP) If Not $hCP Or @error Then Return 3 If Not _ClipBoard_Close() Then Return 4 Return 0 EndFunc Concerning _WinAPI_CopyImage(), i didn't understand immediately why it was necessary here, because we already had a functional bitmap handle, so why is it necessary to copy the image again ? The answer is because in some cases, you will want to modify the image width/height (among other attributes). Also, have a look at the 2 flags (uncommented in help file) $LR_COPYDELETEORG, $LR_COPYRETURNORG : MSDN indicates this : * LR_COPYDELETEORG : "Deletes the original image after creating the copy" * LR_COPYRETURNORG : "Returns the original hImage if it satisfies the criteria for the copy—that is, correct dimensions and color depth—in which case the LR_COPYDELETEORG flag is ignored. If this flag is not specified, a new object is always created." Which means _WinAPI_CopyImage() will not always create a copy of the image, reusing the original if all criterias are correct, that's the answer to my question Thanks Francesco for UEZ's link, he always got great scripts ! A few weeks ago, I found another UEZ's link, very helpful, where he solved a tricky problem :https://www.autoitscript.com/forum/topic/165083-question-on-_guiimagelist-usage/?do=findComment&comment=1205157 Link to comment Share on other sites More sharing options...
Nine Posted December 6, 2018 Share Posted December 6, 2018 35 minutes ago, pixelsearch said: Concerning _WinAPI_CopyImage(), i didn't understand immediately why it was necessary here, because we already had a functional bitmap handle, so why is it necessary to copy the image again ? The answer is because in some cases, you will want to modify the image width/height (among other attributes). Also, have a look at the 2 flags (uncommented in help file) $LR_COPYDELETEORG, $LR_COPYRETURNORG : MSDN indicates this : * LR_COPYDELETEORG : "Deletes the original image after creating the copy" * LR_COPYRETURNORG : "Returns the original hImage if it satisfies the criteria for the copy—that is, correct dimensions and color depth—in which case the LR_COPYDELETEORG flag is ignored. If this flag is not specified, a new object is always created." Not quite, the answer comes from from @ProgAndy in "The problems of the other Scripts were the differencies between GDI32-HBITMAP and GDIPlus-HBITMAP." Image copy resolves that. If you don't do it, it will simply not work... Aether 1 “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) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
pixelsearch Posted December 7, 2018 Share Posted December 7, 2018 Hi Nine Thanks for your input, it allowed us to see what ProgAndy was able to do in 2008 and to get his UDF If I read him well, he was able, first, to copy a bmp image to clipboard, here :https://www.autoitscript.com/forum/topic/70184-screencapture-into-clipboard/?do=findComment&comment=514764 #include <ClipBoard.au3> #include <WinAPIRes.au3> $hBitmap = _WinAPI_LoadImage("","C:\windows\zapotec.bmp", $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE) _ClipBoard_Open(0) _ClipBoard_Empty() _ClipBoard_SetDataEx($hBitmap, $CF_BITMAP) _ClipBoard_Close() Reduced to its shortest size, his script works nicely on my computer for .bmp images only (not for tif or jpg) So without GDIPlus functions or _WinAPI_CopyImage() , he was able to copy a bmp to clipboard, great job ! After that, he created a UDF to allow other types of images to be copied to the clipboard, here : https://www.autoitscript.com/forum/topic/70237-images-and-the-clipboard/ In his UDF, the 9 important functions he used are nearly the same as UEZ's (only 1 function will differ) : _GDIPlus_Startup() _GDIPlus_ImageLoadFromFile() [UEZ uses _GDIPlus_BitmapCreateFromFile] _GDIPlus_BitmapCreateHBITMAPFromBitmap() _WinAPI_CopyImage() _GDIPlus_Shutdown() _ClipBoard_Open() _ClipBoard_Empty() _ClipBoard_SetDataEx() _ClipBoard_Close() I wish a function named _ClipPutImage() could be added in the next releases of AutoIt, to be able to copy the content of any image in the clipboard... with 1 line only, based on the script of these great guys Link to comment Share on other sites More sharing options...
pixelsearch Posted December 7, 2018 Share Posted December 7, 2018 (edited) Hi FrancescoDiMuro In the link you provided in your post, before UEZ's answer, Water indicated something that could interest Clear (lots of nicknames in that sentence lol) https://www.autoitscript.com/forum/topic/191946-how-to-copy-a-picture-to-the-clipboard【solved】/ OP wanted to copy an image into clipboard and Water answered him this : _ClipPutFile("<your filename goes here>") But this was not satisfying for OP because ctrl-v in his app pasted... the name of the file, not the image itself. Then Water suggested him to try this in Word and see the results. Then came UEZ... According to the help file , _ClipPutFile() "copy Files to Clipboard Like Explorer does" I just did this test : #include <Misc.au3> _ClipPutFile("G:\temp\cherry.jpg" & "|" & "C:\windows\zapotec.bmp") Don't expect the clipboard to contain the images themselves, it will contain 2 lines only (path & filename) : G:\temp\cherry.jpg C:\windows\zapotec.bmp Now is the important part : depending on the software where you are going to paste (ctrl-v), results will be totally different : * If you open Word and paste, then the 2 images will appear (as Water suggested) * If you open Worpad or Paint, nothing happens when you paste. So each software reacts differently when you paste in it a list of filenames, a point to remember. Hope it will be helpful Edited December 7, 2018 by pixelsearch Link to comment Share on other sites More sharing options...
Clear Posted December 7, 2018 Author Share Posted December 7, 2018 (edited) hey, guys, Thanks for your help. Unfortunately, I didn't want to copy image from file to clipboard, but rather to save and retrieve clipboard content - whichever it is - to retrieve it after template is send. User uses hotkey to activate gui User click button on gui to send corresponding template Program saves current clipboard content into memory (it can be anything - because, at the time, you don't know what user will be holding in clipboard) Program sets clipboard to template content (text) Program sends keystroke CTRL + V to send template Program retrieves clipboard content that was saved in 3. point I have found this thread with user created function _Clipboard_GetAll() and it seems kinda good for now. Sometimes, unfortunately the Clipboard is not retrieved during test, but it may be because I am testing it too fast. Will try to check it slower to check if it work properly. The current $Text function is: Func Text($Text) ; Remove saved Clip Content in case it was not removed by any chance before $Clip = "" Local $Timer = TimerInit() While TimerDiff($Timer) < 1000 _ClipBoard_Open(0) ; Copy current clipboard content by using wraithdu script _Clipboard_GetAll($Clip) _ClipBoard_Close() If $Clip Then ExitLoop Sleep(10) EndIf WEnd ; copying template content to clipboard ClipPut($Text) ; sending clipboard to other application Send("^v") ; releasing clipboard content _Clipboard_Open(0) _Clipboard_Empty() _Clipboard_Close() ; retrievieng clipboard content _ClipBoard_PutAll($Clip) $Clip = "" EndFunc EDIT: Unfortunately, it crashes or failing at random Edited December 7, 2018 by Clear Link to comment Share on other sites More sharing options...
Nine Posted December 7, 2018 Share Posted December 7, 2018 Could you try this simple script ? Seemed to be working fine with me... expandcollapse popup#include <Constants.au3> #include <GUIConstants.au3> #include <Clipboard.au3> Opt ("MustDeclareVars", 1) Global $aClip _Clipboard_GetAll($aClip) _ClipBoard_Empty() _ClipBoard_SetData ("Some text to set clipboard to",$CF_TEXT) MsgBox (0,"test","Check if clipboard is OK") _ClipBoard_PutAll($aClip) Beep () Func _Clipboard_GetAll(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 Func _ClipBoard_PutAll(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 Clear and pixelsearch 2 “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) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
Clear Posted December 7, 2018 Author Share Posted December 7, 2018 Thanks It works almost perfectly (formatted text is retrieved as plain, but it's still very good) Link to comment Share on other sites More sharing options...
Nine Posted December 7, 2018 Share Posted December 7, 2018 1 hour ago, Clear said: It works almost perfectly (formatted text is retrieved as plain, but it's still very good) I don't know how to solve this one, glad you like it “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) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
pixelsearch Posted December 7, 2018 Share Posted December 7, 2018 (edited) @Nine : that's a great function, it works fine, nicely written and fully understandable. I like how you used the 2D array and the [$iNum+1] so you could store in [0][0] the total of different formats actually in clipboard, and all your future loops will start at 1, that's how I like loops, starting at 1 and not at 0 ! Then all formats/data you stored them in rows 1+ (col 0 for formats, col 1 for data) Btw, there's still room in [0][1] in case you wanna add something in it (joke) I guess I'm gonna have a look at your other functions, in case they are as nicely written as this one Edited December 7, 2018 by pixelsearch Link to comment Share on other sites More sharing options...
Nine Posted December 7, 2018 Share Posted December 7, 2018 @pixelsearch thank you for response. Especially from you, I trust you truly are a great programmer. “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) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
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