autohotkey: Cancel RButton user input after LButton pressed - scripting

In an fps I am trying to setup a hotkey such that when I am holding Lbutton (leftmouse), primary fire of a gun, and then tap RButton the LButton ceases and RButton commences. Ingame with no script, for other weapons, I get the desired result automatically. That is: I'm holding LButton, but if I also hold RButton 'after', the LButton ceases and the RButton's burst fire does its thing. However a different scoped weapon, with no script, freezes up when the above is done.
So I'm looking to, as soon as RButton is pressed, cease all user input of LButton until RButton's hotkey finishes.
~RButton
;Blockinput Mouse ;Send/Sendmouse
Send, {Click Left}{Click Right}{Click Left}
;BlockInput off
return
You can think of the Rbutton script as for a scoped rifle. Click Left activates scope, Click right fires it. Currently the desired behaviour only works when I completely remove my hand from LButton and then press RButton....I am also able to get ~LButton & ~RButton:: to work but that only covers the case when they r both first pressed at the exact same time, I want to cover the instance where LButton is pressed and held before RButton.
Ive tried applying blockinput, like seen above, had the UAC workaround to get it working, blocks certain things but doesnt seem to block any heldkeys when it is proc'd like the lbutton unless I'm missing something. If there was a "Freeze user input of LButton as soon as RButton procs, until RButton's script finishes" that would solve the problem I would think. I tried adding sleep delays, but they dont seem to help. The issue seems to be that LButton, when held, continues to proc when RButton first activates.
I used the below while holding LButton, and the sound DOES proc, so this must be possible to script.
*RButton::
Soundbeep
return
EDIT:
;code here works but only with that 100 sleep where i have to remove my hand from pressing the lbutton within 100ms of pressing rbutton.
*RButton::
GetKeyState, state, lbutton, p
if (state = "D")
{
soundbeep
send {Click Left Up}
sleep 100
;i need to actually disable the previous keypresses from it
}
Send, {Click Right}{Click Left}{Click Right}
return

From what I understood from your question, you don't really need to block user mouse input so much as Sending a Left MouseUp command if the Left mouse button was held down. I was having difficulty understanding what the end goal you were looking for was, but I wrote this based on what I was able to understand:
#SingleInstance Force
*RButton::
Soundbeep
If (getKeyState( "lbutton", "p" )){
Click, Left, Up
Send, {Click Left}{Click Right}{Click Left}
} else {
Send, {Click Left}{Click Right}{Click Left}
}
return
esc::ExitApp
UPDATE:
Based on the clarification from the comments of the question, this should work. Understood functionality: If the right mouse button is clicked while the left mouse button is held down, release the LMB, but do not suppress the RMB input.
*~RButton::
If (getKeyState( "lbutton", "p" ))
Click, Left, Up
return
UPDATE 2:
Now releasing the LMB before the RMB is pressed. I have a feeling that whatever game that you are playing will not be able to detect zero-tick switches between keystates, so I included a Sleep function that you can fine-tune/ remove as needed.
*RButton::
If (getKeyState( "lbutton", "p" )){
Click, Left, Up
Sleep 100
}
Click, Right, Down
KeyWait RButton
Click, Right, Up
return

Related

Buttons Back, Leave and Cancel are inoperative in Hierarchical ALV

I display a hierarchical ALV. When I click the BACK or LEAVE or CANCEL buttons (in the toolbar), I'm supposed to go back or leave the program or cancel .
But when I click one of those buttons an additional row appends in the ALV hierarchy.
Any help ?
Check yor PBO/PAI moduls.
EXAMPLE:
IN PBO i said
module status_0100 output.
set pf-status 'GUI_STATUS_0100'.
" and some other code
" and some other code
endmodule.
IN PAI i said
module user_command_0100 input.
case sy-ucomm.
when 'CANCEL' or 'BACK'.
set screen 0.
when 'EXIT'.
leave program.
endcase.
endmodule.
In GUI_STATUS_0100 i told about buttons that i used
It might help you. Good luck!
There must be event(s) trigger along side with BACK, LEAVE and CANCEL.
Double check the function code of 3 buttons, ensure they only appears in Exit-command and when triggered, ensure there is no other subroutines inside/next to the LEAVE, RETURN... statement
If possible, please post some code.

Wait for 1 second before starting code again - VB.NET

I desperately need help with a game I am making. For a bit of context, i am making a memory game and i have the following piece of code that is being troublesome. I have a bunch of labels on the form, 16 to be exact, with 1 randomly generated symbol placed in each. Each symbol appears in the labels twice.
------------------------------Continued----------------------------------------
'MsgBox("hello") 'used to check if the second inccorect press shows up - it does show but instantly changes colour
'''''''''''''''''NEED SOME CODE THAT PAUSES IT HERE'''''''''''''''
labels(0).ForeColor = Color.DarkRed
sender.ForeColor = Color.DarkRed
End If
flips = 1
End If
End If
tmrmemory.Enabled = True ' starts the timer after the user clicks the first label
End Sub
What's supposed to happen is that when the labels clicked don't match, it should show both the clicked labels for a short period before changing them both back to "DarkRed" which is the colour of the form's background.
I have tried using a timer but then i can't use sender.forecolor=color.darkred because it is not declared globally.
I have also tried using the command Threading.Thread.Sleep(500) but it still doesn't show the second incorrect click. I know that the code i have used works because when i use the message box, i can see both symbols and when the two clicks are correct, it stays.
Threading.Thread.Sleep(500) will actually pause your code for half a second. However during this time it won't do anything, not even refresh your controls. To get the effect you want, you need to call the YourControl.Refresh method before calling Threading.Thread.Sleep to force the control to redraw immediately.
On a side note, I would advise you not to call Threading.Thread.Sleep on UI thread. It will give a feeling of program hang. Instead do your work on a separate thread. You can either do all the work yourself right from creating a separate thread to destroying it, or use the BackgroundWorker control which has all the functionality built in.
Here is the link to an article I wrote a long time ago regarding BackgroundWorker that might be useful for you:
http://www.vbforums.com/showthread.php?680130-Correct-way-to-use-the-BackgroundWorker
Declare a variable outside the sub that stores what label should be flipped when the timer ends.
Label click sets
storedLabel = sender
Timer tick sets storedLabel.ForeColor = Color.DarkRed

Disable Fn+F4 with AutoHotKey using time

I want to use AutoHotKey to disable Alt+F4 when they are pressed within 0.05 seconds of each other. Otherwise, I'd like it to work as normal.
Explanation:
My Lenovo Yoga 2 Pro has alternate functions for the function keys.
For example: "F3" is mapped to volume+, "F4" is mapped to "close active window"
There are two modes:
Old-school mode: F3 just acts as F3, and you must hold Fn+F3 key to activate volume+
New-school mode: Pressing F3 activates volume+, and Fn+F3 will do the normal F3.
In either mode, I run the risk of closing my active window when I go to use volume+ because they are too close, which is very problematic. Note that AutoHotKey cannot detect the Fn key, thus I cannot use that to solve my issue.
The image below shows the AutoHotKey Key History tool. In New-school mode, I typed "asdf" and then pressed "F4" which is "close active window". You can see this actually simulates ALT+F4, and there is a very short duration between ALT and F4...
I'm thinking that I could disable this "close active window" function by having AutoHotKey interrupt an ALT+F4 combo when there is less than 0.05 seconds between the two keys. Can this be done?
Edit:
In response to Blauhirn's code, here is the original, edited for a shorter wait duration, (from 50 to 10). It works most of the time, though 1/10 times the window is still cosed:
~alt::
hotkey, alt, off
hotkey, !F4, doNothing, on
sleep, 10
hotkey, !F4, doNothing, off
while(getKeyState("alt"))
sleep, 1
hotkey, alt, on
return
doNothing:
return
Here is a change I thought would fix my focus issue by sending a 2nd Alt when the "close active window" was detected:
doNothing:
send {LAlt}
return
However, the 2nd Alt is not sent. It IS sent when the delay is above 40ish, however I find that is way too long, and in turn it interferes with my manual use of Alt+F4.
Have you tried using simply
F4::return
? Maybe this will override the Lenovo action for F4
Other than that, here are the two approaches I can think of:
Disabling the ALT+F4 standard win hotkey by default. Adding a custom hotkey for a delayed F4
!F4:: ; by default:
doNothing: ; this is a label (see GoSub)
return ; == do nothing
~alt:: ; alt was pressed
sleep, 50 ; wait 50 milliseconds
if(!getKeyState("alt")) ; if alt is NOT pressed down anymore, exit
return
else ; (else is actually unnecessary here)
hotkey, !F4, close ; Add new AltF4-hotkey
return
close:
winclose, A ; close the Active window
return
~alt up:: ; alt is being released
hotkey, !F4, doNothing ; remove the new AltF4 hotkey and go back to custom standard behaviour: do nothing.
return
it still triggers Alt, which usually leaves me in the menu of the active window (File, Edit, View, etc), or if typing within a textarea (such is this), it will remove typing focus.
well yes. If you decide to keep the lenovo keys, I don't think there is a way to prevent it. As you suggested, sending ALT again should solve the problem
using Input, after ALT has been pressed. Input blocks user input for a configurable time, as long as the V option is used.
(3. disabling your Lenovo Yoga 2 Pro special keys. If you need the F3 function, you can do that in AutoHotkey e.g. using send {volume_up}

vb.net register hotkey "capslock"

is there possible to register "CapsLock" as a hotkey instead of registering 2keys? i dont want to use ctrl+key, alt+key. I want to toggle "CapsLock" to start/break my loop. Like if i toggle on the capslock, the loop will run and so on. I solve this making a timer and checking the keystate of capslock whether is it on or off. but i dont like it, coz my application is keep showing the notifyballon message i make when toggling the capslock every time the timer's tick. so im hoping someone can help me with this.
im using this code to register some of my hotkey, and is this possible to edit for "CapsLock"?
RegisterHotKey(Me.Handle, 1, MOD_CTRL, Keys.Oem3)
thx
Why not just run the code for the keyup event on the form. Use an if statement to see if the capslock key was pressed, and run loop if it did. Have a boolean value change each time you press the capslock key to tell the loop when to quit.
If e.KeyData = Keys.CapsLock Then
boolvalue = Not boolvalue
While boolvalue
' Do your thing.
End While
End If

Autohotkey Win XP automating small task

I have a small task I would like to automate with Autohotkey and it looks like it is more or less directly transferable to autohotkey syntax:
1. Ctrl+v
2. Alt+tab
3. Click certain link in a window (no combo-key for this but it's always in the same place)
4. Enter (carriage return)
5. Alt+s
6. Ctrl+v
7. Enter
Now it would be nice to map this combo to something else e.g. Windows Key+Space.
What I have got so far is:
0. SetWinDelay 100 (using a connection to an remote computer)
0. SetKeyDelay 0
1. Send, ^c
1. ClipWait, 0.1
2. Send, {Alt down}{tab}
2. Send, {Alt up}
3. ?????
4. Send, {enter}
5. Send, !s
6. Send, ^v
7. Send, {enter}
Is this approximately right? Anyone up for helping me fix it or filling in the holes, so to speak :)
Another alternative to step 3, 4 and 6 would be to simply loop though the contents of the clipboard (a number string) and sending each letter of the string to keypresses? Maybe this would be the easier way
If you want to "click" on a certain position, to open a menu, you can first right click on your AutoHotKey icon and open the "window spy". This window spy will show you the mouse position. Yo can use the mouse positions to perform your actions in the active application.
Example:
SoundBeep 1000, 300 ; Wake up user
SplashTextOn, 200, 100, Script Preparations, Please Click on the person icon link. ; Show new Instructions text
WinMove, Script Preparations,, (A_ScreenWidth/2)+150, (A_ScreenHeight/2)+200 ; Move the window with the name "Script Preparations" Down and Right on the main screen
KeyWait, LButton, D ; Wait for LeftMouseButton click Down
MouseGetPos, xposE ,yposE ; Store the position where the mouse was clicked (Employee)
MouseClick, left, %xposE% ,%yposE%, 2 ; Perform a double mouse click on the captured mouse location
SplashTextOff ; Remove Text box
In this case, I first ask the user to manually click on the right location. This is only required when the position to click changes WITHIN the active window (variable tiles within the active window). Once you have the position stored, you can re-use it all throughout your script.
b.t.w. instead of using Alt+Tab, I suggest using this:
settitlematchmode, 1 ; Set search in title to start with....
settitlematchmode, Fast ; Slow is not required here. Slow is only required when hidden text needs to be found.
SwitchWindow("Microsoft Excel - 1 QRM Upload and Change Template") ; Activate the
window with the title: Microsoft Excel - 1 QRM Upload and Change Template
You could even use someting like this:
SetTitleMatchMode, 2 ; Ensure that the Title Match mode is set to 2: Find anywhere in the title
SetTitleMatchMode, Fast ; Ensure that the Title Match mode is set to FAST
winactivate, %WindowName% ; Activate the window with the title stored in the variable WindowName
WinWaitActive, %WindowName%, , 5 ; Wait up to five seconds for the screen
if ErrorLevel ; Execute this when the window is not activated within 5 seconds
{ ; Start-If Wait failed
SoundBeep 1000 , 1000 ; Warn the user
MsgBox,4097,Time Out, Script timed out while waiting for %WindowName%.`n`rYou Must manually activate %WindowName% and then continue the script by pressing OK. ; Message to user
IfMsgBox, Cancel ; Do when the user clicked on Cancel
{ ; Start-If User clicked Cancel
ExitApp ; Exit this program when the user clicked on Cancel
} ; End-If User clicked Cancel
WinWaitActive, %WindowName%, , 5 ; Try to activate the window AGAIN
if ErrorLevel ; If window can't be found
{ ; Start-If window can't be found
MsgBox,4096,Exit, %WindowName% still NOT Active. ; Warn user
ExitApp ; Exit this program when the expected window is still not found
} ; End-If window can't be found
} ; End-If Wait failed
Regards,
Robert Ilbrink