Wait for text to send before continuing code? Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Wait for text to send before continuing code?

Post by kunkel321 » 13 May 2022, 15:39

I think this might be related to the problem I was having here: viewtopic.php?f=76&t=97888&p=434609#p434609

With the below code, I'm using SendMode Event, and -- while typing everything out -- the script works as expected. It types all of text1, then pastes text2, then text3. HOWEVER, if it is set to SendMode Input, then, by the time text1 has finished typing, the Clipboard has already been set to %text3%. ...At least I think that's what's happening, because it types text1, then pastes text3 twice.

I prefer using SendMode Input, but I'm thinking that if I wish to mix pasting via clipboard assignment, with typing things out, I might have to force the use of SendMode Event. Any ideas how do get this to work as desired?

Code: Select all

#NoEnv
#SingleInstance force
#Persistent

SendMode Event 	;Send is the same as SendEvent. It is more visual but prone to errors.
;SendMode Input	;SendInput is faster but you often can't see progress of typing.  

!^+p::
text1 = 
(
From Wikipedia, the free encyclopedia Jump to navigationJump to search For other uses, see Wiki (disambiguation). Editing display showing MediaWiki markup language Interview with Ward Cunningham, inventor of the wiki A wiki (/ˈwɪki/ (listen) WIK-ee) is a hypertext publication collaboratively edited and managed by its own audience directly. A typical wiki contains multiple pages for the subjects or scope of the project and could be either open to the public or limited to use within an organization for maintaining its internal knowledge base. Wikis are enabled by wiki software, otherwise known as wiki engines. A wiki engine, being a form of a content management system, differs from other web-based systems such as blog software, in that the content is created without any defined owner or leader, and wikis have little inherent structure, allowing blah.
)

text2 = 
(
THIS IS TEXT 2
)

text3 = 
(
THIS IS TEXT 3 
)

send %text1%

Clipboard =
Clipboard = %text2%
send ^v

Clipboard =
Clipboard = %text3%
send ^v

return
ste(phen|ve) kunkel


User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 13 May 2022, 16:49

Thanks for the reply Mike. Alas, it doesn't seem to make a difference. At least not the way I'm using it:
Spoiler
My actual app viewtopic.php?f=6&t=87791&p=435670#p435670 saves the original clipboard content, then restores it at the end of the script, after using the clipboard for these intermittent pastes. I'm finding the send ^v commands do get executed, but it just pastes the original clipboard content once fore each send ^v command. Again though, if I use the slower SendMode Event then it works correctly.
My assumption is that the AHK script is waiting for the text to finish playing before it proceeds to the next line of code, when SendMode Event is used.

I feel like there needs to be a "Wait For Text To Play" command that I can put before each Clipboard = %var%. That way, when I use SendMode Input it won't rush past those points in the code, erroneously reassigning the clipboard content too quickly.
ste(phen|ve) kunkel

User avatar
mikeyww
Posts: 26601
Joined: 09 Sep 2014, 18:38

Re: Wait for text to send before continuing code?

Post by mikeyww » 13 May 2022, 16:59

Yes, in some cases, paste is slow, too. I would see PasteWait, though in some cases, I find that it does not work well, and I just need to add a short sleep.

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 13 May 2022, 17:09

Thanks Mike, I'll check it out. It's funny, I was "googling around" and had found my way to the same forum thread :)

It's a shame the Windows doesn't allow you to detect when it is/isn't buffering text. I think waiting for that keyboard buffer to "empty" would probably do the trick...
ste(phen|ve) kunkel

User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: Wait for text to send before continuing code?

Post by boiler » 13 May 2022, 17:18

Add a Sleep, 500 after the first send ^v because you are clearing out the clipboard and loading it with text3 before Windows has had a chance to paste what you loaded as text2:

Code: Select all

#NoEnv
#SingleInstance force
#Persistent

SendMode Event 	;Send is the same as SendEvent. It is more visual but prone to errors.
;SendMode Input	;SendInput is faster but you often can't see progress of typing.  

!^+p::
text1 = 
(
From Wikipedia, the free encyclopedia Jump to navigationJump to search For other uses, see Wiki (disambiguation). Editing display showing MediaWiki markup language Interview with Ward Cunningham, inventor of the wiki A wiki (/ˈwɪki/ (listen) WIK-ee) is a hypertext publication collaboratively edited and managed by its own audience directly. A typical wiki contains multiple pages for the subjects or scope of the project and could be either open to the public or limited to use within an organization for maintaining its internal knowledge base. Wikis are enabled by wiki software, otherwise known as wiki engines. A wiki engine, being a form of a content management system, differs from other web-based systems such as blog software, in that the content is created without any defined owner or leader, and wikis have little inherent structure, allowing blah.
)

text2 = 
(
THIS IS TEXT 2
)

text3 = 
(
THIS IS TEXT 3 
)

send %text1%

Clipboard =
Clipboard = %text2%
send ^v
Sleep, 500

Clipboard =
Clipboard = %text3%
send ^v

return

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 13 May 2022, 17:34

Thanks Boiler. Yeah, a long enough Sleep would work. The length of the string can vary greatly though. I was actually thinking of maybe assessing the length of the string, then having the length of the Sleep change accordingly.
ste(phen|ve) kunkel

User avatar
boiler
Posts: 16771
Joined: 21 Dec 2014, 02:44

Re: Wait for text to send before continuing code?

Post by boiler » 13 May 2022, 17:46

You shouldn't have to vary it much. It's not like you have to wait for the Send line to complete. This is just a sleep after the first paste, which is independent of how long it takes for the Send line to complete sending its text.

User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: Wait for text to send before continuing code?

Post by rommmcek » 13 May 2022, 22:52

This is what I think the proper approach:
Spoiler
Last edited by rommmcek on 14 May 2022, 12:38, edited 1 time in total.

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 14 May 2022, 09:40

Thanks for the replies, Guys.
Boiler I don't want to hijack the other thread, so quoting you here..
boiler wrote:
14 May 2022, 04:14
As I mentioned in the other thread [this], the reason it sends the third variable’s text twice has only to do with you immediately assigning new text to the clipboard after the first paste. It is not because of how long the Send command takes to send your first piece of text.

The issue as you described it makes that clear. The first piece of text finishes being sent without interruption, then the third piece of text is sent twice. That is exactly what is expected to happen because of the lack of the delay after the paste of your second piece of text regardless of what happened before it. You are wasting your time trying to figure out how to delay varying amounts of time based on of the length of text sent by the Send command.
Anyway, Experimentation is suggesting to me that a varied delay might work. Notice with the code you posted above (my code but with the Sleep, 500 added) it does run as posted, but if you change the commenting-out so that the faster SendMode Input is used, then it breaks the code again.
Arguably, 500 ms is a fairly substantial delay. Even with 2000 it doesn't work (it does with 3000 though). It seems like (when using SendMode Input), one thread of AHK swaps the variables in the clipboard, while another thread sends to the Windows clipboard buffer "big string of text^v^v." I'm not sure about the terminology, but you see what I mean...

Here is an experiment with a dynamic delay
Spoiler
Try it, then quadruple the size of the string and try it. It seems to work for me.

Other thoughts: I tried changing the send mode in the middle of the code -- that doesn't seem to work.
ste(phen|ve) kunkel

User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: Wait for text to send before continuing code?

Post by rommmcek » 14 May 2022, 12:55

Edited my previous bad posting.
Some target applications can't cope with flood rate of Send input (we have to use Send Event and SetKeyDelay) and some give no feedback (dynamic sleep you proposed should work placed immediately after Send command).
What is target app of yours?

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 16 May 2022, 11:45

Thanks for the script Rommmcek. It's seriously tripping me out.

During my testing, I'm typically using Notepad. The testing is for my above-mentioned app though, and that gets used mostly in webforms (Chrome browser) and in Outlook emails.

I tweaked your script a tiny bit:
Spoiler

When I run it, it types all of text1, then stops (actually, waits?). No matter how long, it waits until I select the text and delete it. THEN it pastes text2 and waits again. Then, when I delete text2, it pastes text3. Is that the intent??

EDIT: Also I'm not sure what the dll call is doing... (no doubt that is related to the above question.) I found this:
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getopenclipboardwindow
Bill Gates says that the dll "Retrieves the handle to the window that currently has the clipboard open." But what is the purpose of doing so?

EDIT 2: Just an interesting observation: When using very long strings, the keys get scrambled toward the end.
With this random text I found on the internet:
Spoiler
If I play it 8 times, using SendMode Input, I get this:
Spoiler
It's okay at the beginning, then gets all messed up.

EDIT 2.2: Also, the Ctrl and/or Shift keys often get left in the down position.
ste(phen|ve) kunkel

User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: Wait for text to send before continuing code?

Post by rommmcek » 16 May 2022, 15:33

Try:
Spoiler
[Edit] Added attempt to prevent modifiers remain stuck.

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 17 May 2022, 08:40

Re the top one: It does that same as the previous one. It waits until the there is an empty edit field, then pastes in the next chunk. Interestingly, it occurs to me that this might be used to solve the problem of ensuring that there is an editable text field, to receive the sent text... I'll explore that too. EDIT: Interestingly, the thing with waiting for the text field to be empty before pasting the next chunk does not occur if I run the script in an edit field in a web form on Chrome. In Chrome, it just types the whole thing out as you might expect.

Re the bottom one: Yeah, it occurred to me to force everything to get typed-out (rather than pasting). My whole trip is to allow sequential typing and pasting though...

If anyone is curious, I ended up with this as the delay:

Code: Select all

...
len := StrLen(item.value)  ; Added dynamic sleep on 5-16-2022 so the paste won't happen until typing is complete. 
len := 200 + (len * 1.6)
send % item.value
Sleep, %len%
...
It's not a perfect system. Typing speed seems to be different in different apps. These numbers seem to work in Notepad, Adventure, EditPadPro, Word, and Outlook.
ste(phen|ve) kunkel

User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: Wait for text to send before continuing code?

Post by rommmcek » 17 May 2022, 17:54

Try:
Spoiler

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 18 May 2022, 09:03

Clever approach!! I hadn't thought of that. If I'm understanding the code correctly, the loop sends the text one letter at a time. Alas, it still has the same effect of AHK updating the clipboard before Windows is done typing. I even tried including a Sleep, 20 inside the loop. That did slow it down. Interestingly, 20 ms and 1 ms had no noticeable difference in the entire playback speed of the script.

Another note: One of the advantages of SendInput vs SendEvent is that SendInput blocks mouse and keyboard input (helping to prevent typing errors). The loop you posed also sends text with the input blocked. If there is even a 1 ms delay in the loop though, it does not block input. It's almost like we turn SendInput into SendEvent.

I'm wondering if my method to "wait for text to send before continuing code" should simply be to enforce the use of SendEvent for that particular text variable. ....will experiment more.
ste(phen|ve) kunkel

User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: Wait for text to send before continuing code?

Post by rommmcek » 18 May 2022, 14:11

You can work around OS sleep resolution like:

Code: Select all

    txt1:= StrSplit(text1)
    loop, % txt1.Length() {
        send % txt1[A_Index]
        if !Mod(A_Index, 5) ; 2 - slow, 3 - quicker, 5 - fast, 10 - very fast
            Sleep, 10
    }
Try also:

Code: Select all

    txt1:= StrSplit(text1)
    loop, % txt1.Length() {
        send % txt1[A_Index]
        Sleep, -1
    }

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 18 May 2022, 17:43

Cool use of mod. I always enjoy seeing the clever ways that people use mod values for different things.

Side Track: The main reason I prefer SendInput over SendEvent is because it blocks user input. So it occurred to me to use SendEvent, but to also BlockInput On/Off before/after the send command. I'm not sure how to use it though....

Given the below code, I expected the first MsgBox to appear, then I wouldn't be able to click it because input would be locked. It doesn't block input though. I'm also able to type into notepad while the first MsgBox is still showing. Thoughts?

Code: Select all

!^z::
BlockInput On ; ### WARNING ### See Rommmcek's comment below.  This code is potentially dangerous.
MsgBox block On
BlockInput Off
MsgBox block off
Last edited by kunkel321 on 19 May 2022, 11:55, edited 1 time in total.
ste(phen|ve) kunkel

User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: Wait for text to send before continuing code?

Post by rommmcek » 19 May 2022, 00:25

Your last scriptlet: Always be careful when posting such code! While Ctrl+Alt+Del as well as Win+L should still work, better use MsgBox,,, block On for 10 sec, 10 to auto unblock!
Btw.: Run it as admin or use at the start of the script:

Code: Select all

if !A_IsAdmin
{
   Run *RunAs "%A_ScriptFullPath%"  ; Requires v1.0.92.01+
   ExitApp
}
Maybe this will solve your other problem too, since sending chars one of the time works for me flawlessly.

To prevent Sleep disrupting SendInput properties try to replace it with DllCall("Sleep", "UInt",10). Don't worry about TimeBeginPeriod and TimeEndPeriod, the granulation will remain on the Sleep level though.

User avatar
kunkel321
Posts: 976
Joined: 30 Nov 2015, 21:19

Re: Wait for text to send before continuing code?

Post by kunkel321 » 19 May 2022, 17:15

Good point about the potentially hazardous script. I put a warning on it. Thanks for all your help on this script Rommmcek. I'm still working on this topic too, but I have to ask a regex question too. Will use a different thread.
ste(phen|ve) kunkel

Post Reply

Return to “Ask for Help (v1)”