Clipboard operation without need of artifical delays using Sleep statements - clipboard

I created simple macro to swap clipboard content with current selection. But it stops working properly when I remove Sleep commands: It does not complete clipboard operation. Just try without these commands to see what I mean.
But Sleep commands are more a hack than a proper solution. What if 500 milliseconds is too long – or in some cases – too short time to wait?
Please what is the proper AutoHotKey way to get it working without Sleep commends?
^CapsLock::
ClipboardOld=%ClipboardAll%
Send ^c
Sleep 500
ClipWait
ClipboardNew=%ClipboardAll%
Sleep 500
Clipboard=%ClipboardOld%
Sleep 500
ClipboardOld= ;clear global variable to conserve memory
Send ^v
Sleep 500
Clipboard=%ClipboardNew%
Sleep 500
ClipboardNew= ;clear global variable to conserve memory
Return

I removed the sleep statements from your code, but could only reproduce a problem when the selection and clipboard data were relatively large, like picture data.
I made two changes to your code:
This swaps clipboard and selection
^CapsLock::
tooltip loading clipboard
ClipboardOld := ClipboardAll
clipboard= ; makes ClipWait wait for NEW clipboard
Send ^c
ClipWait 30,1 ; "1" watches for both text and binary data
tooltip swapping clipboard
ClipboardNew := ClipboardAll
Clipboard := ClipboardOld
ClipboardOld=
Send ^v
Clipboard := ClipboardNew
ClipboardNew=
tooltip
return
If this code is still not working, I suggest trying to identify which sleep statements are necessary to make the code work correctly. Use a divide and conquer approach and a process of elimination by deleting half the sleep statements and testing until you find the statement(s) that are needed.
Update: This attempts to address the problem described in the comment section:
^CapsLock::
tooltip loading clipboard
ClipboardOld := ClipboardAll
clipboard=
Send ^c
ClipWait 30,1
tooltip swapping clipboard
ClipboardNew := ClipboardAll
Clipboard= ; reset clipboard to enable ClipWait
Clipboard := ClipboardOld
ClipWait 30,1
ClipboardOld=
Send ^v
Clipboard= ; reset clipboard to enable ClipWait
Clipboard := ClipboardNew
ClipWait 30,1 ; Wait for clipboard to restore
ClipboardNew=
tooltip
return

Related

Testing if a window is responsive

I have this script to run a online game, click trough the startup screens and input my password for me.
Ever since the latest patch however, the %MWOStartupTime% has become rather unpredictable and this doesn't work reliably anymore. I'm suspecting the game is firing some early web requests. Or something.
So here's the question: Instead of waiting for a fixed time, can I somehow test if a given window not only exists but is responsive? That way I could loop, wait for a responsive window and start "clicking" then.
I'm also happy about alternative ideas/solutions. If it turns out I need to use the WinAPI I can rewrite it in a real programming language too.
Run, MWOClient.exe, %MWODirectory%
; Wait for the Client to launch
WinWait, MechWarrior Online,, 20
WinActivate, MechWarrior Online
; Wait until the window is responsive
Sleep, %MWOStartupTime%
; Press Escape a few times to skip the loading screens
Loop %MWOScreenLoops% {
WinActivate, MechWarrior Online
Sleep, %MWOScreenTime%
SendInput {Esc}
}
; Click the password textbox
WinActivate, MechWarrior Online
Click %MWOPasswordBoxXCoord%, %MWOPasswordBoxYCoord%
Sleep 500
; Type the password
WinActivate, MechWarrior Online
SendInput %MWOPassword%
Sleep 500
; Copy the password to the clipboard in case the
; password input fails
clipboard = %MWOPassword%
; Click login
Click %MWOPlayButtonXCoord%, %MWOPlayButtonYCoord%
Have you tried following WinActivate with WinWaitActive? You should be able to drop the Sleep command.
WinActivate, MechWarrior Online
WinWaitActive, MechWarrior Online
https://www.autohotkey.com/docs/commands/WinWaitActive.htm

Is it possible to detect a clipboard paste?

I want to be able to copypaste passwords from my password manager to arbitrary programs. I would like to clear the password from the clipboard as soon as I have pasted it into another program. Is it possible to detect in Windows/Linux when the clipboard is being read?
I believe you can do this with delayed rendering. Instead of providing the data, you would give a null handle, then Windows will call you back with a RenderFormat message. Then you would render the data (provide the actual text to the clipboard), and set a 1000ms sleep timer (or better yet, another thread). After 1000ms, you clear the clipboard.

Lazarus: The effect of Application.ProcessMessages

I have the following code and it correctly shows the InvoicingUnit on the message box. It also shows the value in the caption correctly.
ADItemRecord := GetInvItemRecord(txtItemCode.Text);
ShowMessage(ADItemRecord.InvoicingUnit );
lblUnit.Caption := ADItemRecord.InvoicingUni;
But the following change (i.e., removing the Message box), shows no caption. The caption is blank.
ADItemRecord := GetInvItemRecord(txtItemCode.Text);
lblUnit.Caption := ADItemRecord.InvoicingUni;
I believe this is to do with the program moving on to the next line before the data is ready in the record. So I did the following change hoping that the program will correctly complete the fetch and then move on.
ADItemRecord := GetInvItemRecord(txtItemCode.Text); //Fetch data from DB
Application.ProcessMessages; //Wait for it to complete (I think)
lblUnit.Caption := ADItemRecord.InvoicingUnit;
Application.ProcessMessages;
But the above change has no effect.
Am I correct to assume that calling Application.ProcessMessages will wait till the previous line correctly completes?
The function GetInvItemRecord is meant to fetch the record from the DB.
The program is built on Ubuntu with Postgres.
Application.ProcessMessages signals that the app can execute events from its event queue. Let's say that you have 2 buttons on a form with to onclick procedures assigned. The first procedure is a lengthly process (eg. repeat ... until true). The second button has only ShowMessage('haha').
Now, without appllication.processmessages inserted in the first procedure in the repeat statement, if you press the first button then you will not be able to press the seccond button (or anything else) until the repeat statement finishes. So the user interface is frozen.
With the application.processmessages inserted like
repeat
Application.ProcessMessages;
...
until true;
if you press the first button and then the second button the showmessage will happen! So, it is a way to fake a multithread app :-))
I hope that i was clear.
This was one of the difficult ones since I did not know what to look for. I've included my answer here so that someone else may also benefit from this.
I thought perhaps it was not the problem (delay) in calling the function to fetch data, but an issue with delayed screen painting or refreshing. Then I found these two links:
What's the difference between Refresh, Update and Repaint?
and this:
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Controls_TControl_Update.html
So I decided to call the Update procedure after assigning the value to the caption. That was the solution to my problem.
I still am not sure how Application.ProcessMessages works - smiles.

Autohotkey: multiple / contingent uses for one command

I'm working on a game design / UI project to redesign an existing game's control scheme (in this case, Trine) to use minimalistic input. I am trying to map lateral movement and the jump function to a Win8 tablet's volume buttons. Here is the basic code I am using:
Volume_Up::
Loop 5
{
Send {right down}
Sleep 50
}
Send {right up}
Return
Volume_Down::
Loop 5
{
Send {left down}
Sleep 50
}
Send {left up}
Return
This is working fairly well and is pretty responsive for moving left and right. However, the desired behavior that I want is to trigger jump (i.e. up) when BOTH buttons are depressed. For instance:
Player holds VolumeUp to move right.
Player comes to an obstacle.
Player continues to hold VolumeUp to queue right-bound movement and;
Player taps VolumeDown momentarily
Player jumps, movement continues up-and-over obstacle toward the right.
I have tried various permutations on using another script with the (Volume_Up & Volume_Down::) syntax to trigger this interaction, but that always seems to interfere with the movement commands. I think this may call for a nested If statement inside the move-left / move-right commands, to check if both buttons are depressed, but the Autohotkey documentation is not very clear and I'm unsure how to code that (I'm more of a game designer than I am a programmer). Any help would be really appreciated!
First of all, give attention to the comment from MCL. Pressing a button down 5 times and never releasing it in between does not seem to do much.
I think that you want multiple threads to be able to run at the same time.
Look up threads, but be aware about the following:
"Although AutoHotkey doesn't actually use multiple threads, it simulates some of that behavior: If a second thread is started -- such as by pressing another hotkey while the previous is still running -- the current thread will be interrupted (temporarily halted) to allow the new thread to become current. If a third thread is started while the second is still running, both the second and first will be in a dormant state, and so on."

Preventing screen dim and display sleep on OS X

I'm making an app for OS X 10.7 and later that plays video. Any document can be taken full-screen using the standard full-screen commands.
I'd like to forestall the automatic screen dim and display sleep as long as any document in my app is playing.
Ideally, the end (or pausing) of all playing videos should commence the full display sleep timer—a 3-minute display sleep delay shouldn't run out 1 minute and 37 seconds after the last video ends simply because something was checking or disrupting the timer every 3 minutes.
I also don't want to disable display sleep outright. If my program crashes or is force quit or the power goes out, the user's display sleep settings should remain untouched.
What's the best way to ensure that playback is not considered “idle”, but that once playback finishes, display sleep after idle works correctly?
Take a power assertion during playback with IOPMAssertionCreateWithName(), and release it when done. Power assertions handle unexpected process termination correctly:
Assertions should be released with IOPMAssertionRelease. However, even if not properly released, assertions will be automatically released when the process exits, dies, or crashes. A crashed process will not prevent idle sleep indefinitely.

Resources