BigDaddyO Posted September 4, 2019 Posted September 4, 2019 I have a script that puts amounts into another application, about 1000+ one after the other. While reviewing, it appears there are some rare occasions where the $ is actually entered as a 4. ControlSend($hReceiptHwnd, "Check Amount", "Edit1", Stringreplace($iAmt, ",", "")) I also filewriteline that $iAmt into a runtime log and the $ shows fine in there, so it must be the ControlSend So I'm wondering how ControlSend actually sends the dollar sign? Does it send Shift+4 or does it send the actual Ascii character 36? Perhaps I should also do a StringReplace($iAmt, "$", Chr(36)) or would it even matter? Thanks, Mike
Danp2 Posted September 4, 2019 Posted September 4, 2019 Have you checked to see if using the $SEND_RAW flag makes any difference? Latest Webdriver UDF Release Webdriver Wiki FAQs
BigDaddyO Posted September 4, 2019 Author Posted September 4, 2019 I have not tried that, good idea! It takes over an hour to run the full script and the last run had 3 of 1032 records that had the issue, so I won't know for a while.
Nine Posted September 4, 2019 Posted September 4, 2019 I have made a little test that I am pretty sure you will appreciate : Opt ("MustDeclareVars", 1) run ("notepad.exe") Global $h = WinWaitActive("[CLASS:Notepad]") For $i = 1 to 1000 ControlSend ($h, "", "Edit1", "$?*({ENTER}") Next Now if I don't do anything on my comp while the script is running, I have no error. BUT if I press shift , or if I click on tray, on rare occasion, the character sent is a number, like you are experiencing. And if I add $SEND_RAW, well.......doesn't matter, it will still send a number. So the question, is what is happening on your comp while script is running ? “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
jaberwacky Posted September 5, 2019 Posted September 5, 2019 So what you want to do is to take the value $10,583 and send it to the window as $10583 but sometimes it sends it as 410583? Do I understand correctly? Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
BigDaddyO Posted September 5, 2019 Author Posted September 5, 2019 (edited) Thank you for that demo Nine, keeps me from having to verify with a run this morning. "our test db refreshes nightly" The script is actually running inside a Citrix desktop window on my one screen while I continue my normal job on my other screen. Often I have another application open over the Citrix window as well. I wonder if there's a way to use BlockInput only for keyboard? edit: Yes there is a BlockInputEx: https://www.autoitscript.com/forum/topic/87735-blockinputex-udf Jaberwacky, yes your understanding of the issue is correct. Edited September 5, 2019 by BigDaddyO
BigDaddyO Posted September 5, 2019 Author Posted September 5, 2019 (edited) I tried the BlockInputEx and just blocking the keyboard doesn't help either. so weird. #include <BlockInputEx.au3> ;================== hWindows usage Example ================== run ("notepad.exe") Global $h = WinWaitActive("[CLASS:Notepad]") ;Here we block *All* keyboard keys for specific window (in this case the Notepads window). ;~ _BlockInputEx(3, "", "", $h) ;blocking keyboard input for the window doesnt help either. ;Here we block only *Keyboard* input (without mouse). _BlockInputEx(3) ;This doesn't help either For $i = 1 to 400 ControlSend ($h, "", "Edit1", "$?*({ENTER}") Next While testing (rapid-tap shift), I'd get the Sticky Keys popup prompt, and then I'd see a bunch of mistypes displayed. edit: I also confirmed that using Chr() doesn't help: ControlSend ($h, "", "Edit1", Chr(36) & Chr(63) & Chr(42) & Chr(40) & "{ENTER}") Edited September 5, 2019 by BigDaddyO
jaberwacky Posted September 5, 2019 Posted September 5, 2019 Try this as just a test please: #include "AutoItConstants.au3" Run("Notepad.exe") Const $hNotepad = WinWaitActive("[CLASS:Notepad]") For $i = 1 To 1000 ControlSend($hNotepad, "Untitled", "Edit1", "$?*({ENTER}" & @CRLF, $SEND_RAW) Next Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
jaberwacky Posted September 5, 2019 Posted September 5, 2019 Better yet! Run("Notepad.exe") Const $hNotepad = WinWaitActive("[CLASS:Notepad]") For $i = 1 To 1000 ControlFocus($hNotepad, "Untitled", "Edit1") ControlSend($hNotepad, "Untitled", "Edit1", "$?*({ENTER}") Next Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum?
Zedna Posted September 5, 2019 Posted September 5, 2019 Look here Resources UDF ResourcesEx UDF AutoIt Forum Search
BigDaddyO Posted September 6, 2019 Author Posted September 6, 2019 @jaberwacky Neither of those get around the issue, tapping the Shift key manually while running still messes them up. I even tried this: and it doesn't help. Run("Notepad.exe") Const $hNotepad = WinWaitActive("[CLASS:Notepad]") For $i = 1 To 400 ControlSend($hNotepad, "Untitled", "Edit1", "+4+/+8+9{ENTER}") Next @Zedna the issue i'm encountering isn't so much that ControlSend doesn't work, its that it's sometimes interrupted by external factors. "Shift key manually tapped", "Selecting the System Tray or another Application while it's running" The only thing that has worked 100% of the time is to do the BlockInput(1) but that needs the #RequireAdmin to work which really sucks.
Nine Posted September 16, 2019 Posted September 16, 2019 Try using my UDF : “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
mistersquirrle Posted September 16, 2019 Posted September 16, 2019 (edited) Hello @BigDaddyO, Check out my take on the issue from @jaberwacky's example: expandcollapse popup;https://www.autoitscript.com/forum/topic/200176-controlsend-shows-4-sometimes/ #include <GuiRichEdit.au3> HotKeySet('{END}', '_Exit') ; Just in case you want to end it early ;~ AutoItSetOption('SendKeyDelay', 0) ; Used when testing sending the keys, and sending ^v ;~ AutoItSetOption('SendKeyDownDelay', 0) ; Used when testing sending the keys, and sending ^v OnAutoItExitRegister('_Exit') ; Just so that we can restore our previous Clipboard Run("Notepad.exe") Const $hNotepad = WinWaitActive("[CLASS:Notepad]") Const $sClip = ClipGet() ; Store the current Clip, to be nice :) ClipPut("$?*(" & @CRLF) ; Put the text that you want into the Clipboard, so that we don't have to 'send' the characters ;~ ClipPut(Chr(36) & Chr(63) & Chr(42) & Chr(40) & @CRLF) $hNotepadEdit = ControlGetHandle($hNotepad, "Untitled", "Edit1") WinSetState($hNotepad, '', @SW_MINIMIZE) ; Using _GUICtrlRichEdit_Paste, we don't need the window to have any focus, and it actually returns MUCH faster if the window DOESN'T have focus. Like ~35s vs ~2.6s For $i = 1 To 1000 ;~ ControlFocus($hNotepad, "Untitled", "Edit1") ; This isn't needed with _GUICtrlRichEdit_Paste ;~ ControlSend($hNotepad, "Untitled", "Edit1", "$?*({ENTER}") ;~ ControlSend($hNotepad, "Untitled", "Edit1", "^v") ; This caused issues if I held Right 'Ctrl' down, occasionally I would just get "v", though the failure rate was much less than holding Right 'Shift' with the above ControlSend _GUICtrlRichEdit_Paste($hNotepadEdit) ; Specifically, WM_PASTE. I have no idea how to use this outside of this UDF, though you could easily look at the UDF function and see, here would be the "direct" call without the UDF's other layers: ; DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hNotepadEdit, "uint", 0x00000302, "wparam", 0, "lparam", 0) ; There doesn't seem to be any real benefit to using the call directly, however, takes about the same amount of time. There's not a lot of extra things or error checking happening If Mod($i, 10) = 0 Then ConsoleWrite(($i / 1000) * 100 & '% done' & @CRLF) ; Just a little logging Next WinSetState($hNotepad, '', @SW_RESTORE) ; All 1000 lines are there, I promise :) Func _Exit() ClipPut($sClip) ; Restore the previous Clip, to be nice :) Exit EndFunc ;==>_Exit Using that example, I was able to get this to complete with (as far as I can tell) 100% success, though the actual keys aren't "sent", if that's a requirement of yours. Let me know if this works for you, as it looks like that it should be *much* faster than ControlSend (though the fastest would probably be to just build your Clipboard with the final output, and send it once, or set the text directly). Edited September 16, 2019 by mistersquirrle Fix script We ought not to misbehave, but we should look as though we could.
BigDaddyO Posted September 16, 2019 Author Posted September 16, 2019 (edited) @Nine You solution seems to work great! It only takes 7ms to block and re-enable access so I can stick it just before and after my ControlSend and from my testing it works great! #include "BlockInputEX.au3" Run("Notepad.exe") Const $hNotepad = WinWaitActive("[CLASS:Notepad]") For $i = 1 To 400 _BlockInput(1) ;Disable input ControlSend($hNotepad, "Untitled", "Edit1", "$?({ENTER}") _BlockInput(0) ;Enable input Next @mistersquirrle Yes, send was a requirement, otherwise I would just use ControlSetText. Edited September 16, 2019 by BigDaddyO
Nine Posted September 16, 2019 Posted September 16, 2019 “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
mistersquirrle Posted September 16, 2019 Posted September 16, 2019 11 minutes ago, BigDaddyO said: @mistersquirrle Yes, send was a requirement, otherwise I would just use ControlSetText. Oh well, at least I can say that I tried. Question about it though, is each keystroke required? Or is just the 'ENTER' required? Because you can still (in the Notepad example) use my solution of the paste for the actual data, and then ControlSend the ENTER no problem. I didn't have any issues with holding/ pressing Ctrl or Shift this way, was still able to do things, and it could still be done while minimized. I obviously don't know how your "Check Amount" window works, but I would personally prefer not blocking input. When I tried it and tried to disrupt it by holding 'Shift' or 'Ctrl', it actually ended up getting my 'Shift' key stuck down for a while, and it's impossible to do anything else (obviously) while input is blocked, or constantly being blocked. But, if it works for you, go for it, don't let me try to stop you. Here's my code with the 'ENTER' key actually 'sent', but pasting the other data. ;https://www.autoitscript.com/forum/topic/200176-controlsend-shows-4-sometimes/ #include <GuiRichEdit.au3> #include "BlockInputEX.au3" HotKeySet('{END}', '_Exit') ; Just in case you want to end it early OnAutoItExitRegister('_Exit') ; Just so that we can restore our previous Clipboard Run("Notepad.exe") Const $hNotepad = WinWaitActive("[CLASS:Notepad]") Const $sClip = ClipGet() ; Store the current Clip, to be nice :) ClipPut("$?*(") ; Put the text that you want into the Clipboard, so that we don't have to 'send' the characters $hNotepadEdit = ControlGetHandle($hNotepad, "Untitled", "Edit1") ;~ WinSetState($hNotepad, '', @SW_MINIMIZE) ; Using _GUICtrlRichEdit_Paste, we don't need the window to have any focus, and it actually returns MUCH faster if the window DOESN'T have focus. Like ~35s vs ~2.6s For $i = 1 To 1000 _GUICtrlRichEdit_Paste($hNotepadEdit) ControlSend($hNotepad, '', "Edit1", "{ENTER}") ;~ ControlSend($hNotepadEdit, '', $hNotepadEdit, "{ENTER}") ; This also works ;~ _BlockInput(1) ;Disable input ;~ ControlSend($hNotepad, "Untitled", "Edit1", "$?({ENTER}") ;~ _BlockInput(0) ;Enable input If Mod($i, 10) = 0 Then ConsoleWrite(($i / 1000) * 100 & '% done' & @CRLF) ; Just a little logging Next ;~ WinSetState($hNotepad, '', @SW_RESTORE) ; All 1000 lines are there, I promise :) Func _Exit() ClipPut($sClip) ; Restore the previous Clip, to be nice :) Exit EndFunc ;==>_Exit We ought not to misbehave, but we should look as though we could.
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