Autohotkey not always sending keys? (Whats going on here) - autohotkey

Basically I don't understand what's going on, any clarification would help
I am trying to set the hotkey "_" and "alt _" in my program. So I made an autohotkey script to replace "/" with "_" and ever other press with "alt _" but it doesn't appear to always work in my program? (unless i spam the command)
My script:
/::
Send _ ;if I keep clicking "/" I always get the desired effect
return
But when I open up my program and press "/" its not launching the specified scene unless I do something like this (however its always replacing "/" with _ in text.
/::
Send_ ; This code works fine, I don't need to keep clicking "/" it works the first time but the codes awful
Send_
Send_
Send_
Send_
return
When I use the above code the streamlabs OBS program picks it up every single time and swaps to the appropriate scene. But when I just use one Send _ it sometimes works right away and sometimes I need to press it multiple times.
My full code (which is seemingly working fine) is as follows:
+/:: ; This is the hotkey I press "Shift /" to start the script
toggler := !toggler ; this changes a boolean every time the script is run
if (toggler) { ; Every odd run this happens (hides scene)
Send +-
Send +-
Send +-
Send +- ;; I feel like all these lines are redundant
Send +-
Send +-
Send +-
Send +-
Send +-
Send +-
} else { ; every even run this happens (shows scene)
Send !+-
Send !+-
Send !+-
Send !+- ;; again idk why I need all these lines instead of just 1
Send !+-
Send !+-
Send !+-
Send !+-
Send !+-
Send !+-
}
return
Basically streamlab obs doesnt let you toggle scenes on/off with the same hotkey so thats what I did but i cant stand my solution :(

Related

AutoHotkey v1 use one shortcut as switch control given loop action on or off

I am making a macro for a game I play, in where I can sit watching a terminal.
I hope when I press Alt+P it presses E on the terminal, it scrolls down so screen can show the item mouse needs to click, then clicks given coordinate and waits 20 seconds. (repeat forever until press Alt+O to stop)
!p::
while toggle==0
(send e)
Loop 3
send {WheelDown}
send {click,1210,670}
Sleep, 20000
!o:: toggle=(toggle+1)
However it keeps the E key held down indefinitely.
The reason e appears to be being held is because your while-loop is only executing the "(send e)" line. If you need the while-loop to execute more than one line of code, enclose the code block in brackets. Also, unless your individual hotkeys are one line, you'll want to put a Return at the end each; otherwise, it will continue to execute into the next hotkey's code and so on.
Here is my untested version of your code. Please let me know if this works for you.
!p::
While !toggle
{
Send , e{WheelDown 3}{click , 1210 , 670}
Sleep , 20000
}
toggle := !toggle
Return
!o::toggle := !toggle

Automatic translation

im really new to all this and i was trying to make an Autohotkey for translation. i was digging for some time looking for examples that only confused me more, even if the code looked simple, i didn't understand half of it.
So, what I'm trying to do is: select a paragraph and replace it automatically with its translation.
i was hooping it to be somenthing as simple as CTRJ + C, Translate, CTRL + V, but i can't find the command to go to google translate or somenthing similar, it's not on the autohotkey help file so i'm guessing i don't have libraries?
I'm at my wits end, please help.
You came to the right place. Check out AutoHotKey for sure.
First, how to do it by hand? Those are the steps for ahk. So, lets say you have a paragraph of text selected. You will hit the ahk shortcut and that shortcut will:
first ahk figures out what window its in (using WinGetActiveTitle) and then sends the keystrokes Ctrl+c to copy the selection ("send, ^c" and "Clipwait"), then
ahk can access the clipboard containing the text, do a string manipulation or regex to replace all spaces with the html escape sequence %20 (eg, transtext := StrReplace(Clipboard, " ", "%20")) and
construct a URL to do the Google Translate, something like (where sl is source language and tl is translation language, and text is what you want translated): transurl := "https://translate.google.com/#view=home&op=translate&sl=en&tl=es&text=" . transtext
AHK runs that url and opens a browser window showing result (run % transurl).
This part sucks. Now, you need to use a mouse click at a location (or maybe you can find a controlsend or a combination of keystrokes moving the cursor with tabs and such) to land on the "Copy translation" button. Or how bout you do it manually (try sleep, 8000 to wait while you hit the button)
then have ahk close the window (optionally, or you just do it by hand during the sleep time) and
ahk switches back to the application with the original selected paragraph (WinActivate or do it yourself) and
send ctrl+v to paste the translated text over the original (send ^v).
A starter pack of AHK code (edited per user comments):
WinGetActiveTitle, activewin
Clipboard =
SendInput, ^c
ClipWait
transtext := StrReplace(Clipboard, " ", "%20")
transurl := "https://translate.google.com/#view=home&op=translate&sl=en&tl=es&text=" . transtext
Run, % transurl
Sleep, 6000 ; adjust to taste.
SendEvent, {tab 10} ; adjust to taste.
Sleep 1000
SendInput, {enter}
Sleep, 1000
SendInput, ^{F4}
WinActivate, activewin
sleep, 1000
SendInput, ^v
Try it and let us know how else to help.
OKOK, first of all, thank you all, the script works just fine now. I'm able to copy, translate and paste any text now. Only a few questions lingering.
1) i'm not sure i get what the step number 5 is suppose to do. whatever it is, it works so i don't touch it.
2) is there a way to reset google.translate so it dosent open a new window every time? that could save a lot of time.
3) this one doesn't have a chance, but i ask anyway. Is there a way to not open google chrome at all? because i know that u can translate from excel automatically. (i know that if it is possible will be super hard)
This is the code i ended with:
^a::
clipboard := ""
sendinput, ^c
ClipWait [,,Waitforanydata]
transtext := StrReplace(Clipboard, " ", "%20")
transurl := "https://translate.google.com/#view=home&op=translate&sl=en&tl=es&text=" .
transtext
run % transurl
Sleep, 4000
SendEvent, {tab 9}
SendEvent, {enter}
Winactivate, NAME.pdf - PROGRAM
sendinput, ^v

Content awareness of AutoHotKey script

Is there a content awareness feature of AutoHotKey? I need to replace some selected text in my application. Imagine the following CSHTML:
#
{
ViewBag.Title = "Welcome";
}
<p>Welcome to this page</p>
I have created a very simple script, that (once text has been selected):
Clears clipboard
Send CTRL+C
Send #normalize("
Send CTRL+V
Send ")
That means, that if I select Welcome to this page, it will be replaced with #normalize("Welcome to this page"). That part works perfectly fine.
However, if I want to replace "Welcome" with the same, I would have to select the quotation marks, which speeds down this automation script quite a lot, because I can't simply double click on the word and select it. Now I would have to press and hold, then drag the mouse across the screen until it reaches the last ending quotation mark.
Instead, I need my AutoHotKey script to do something like:
Send CTRL + C;
var caret = currentCaretTextPosition; //made up
IF caret+1 IS "
Send Delete
IF caret-1 IS "
Send Backspace
Send #normalize("
Send CTRL+V
Send ")
If that makes sense. Basically transforms "Welcome" into:
""
"
#normalize("
#normalize("Welcome
#normalize("Welcome")
This is very basic content awareness stuff, because it checks the surrounding characters of the caret, then acts upon that.
AutoHotKey script (triggered by CTRL+ALT+SHIFT+X):
^!+x::
clipboard:=""
While clipboard
Sleep 10
While !clipboard
{
Send ^c
Sleep 100
}
Sleep 20
Send #normalize("
Sleep 20
Send ^v
Sleep 20
Send ")
return
This solution will check if there are surrounding quotes and proceed accordingly. It may fail if there is nothing to the right (such as end of file). It does stop if nothing is selected initially. It does not check if what is selected already contains quotes.
^!+x::
clipboard := ""
Send , ^x
ClipWait , 1
If ErrorLevel
Return
sNormalize := clipboard
clipboard := ""
Send , {right}+{left 2}^c
ClipWait , 1
Send , % ( clipboard = """""" ? "{del}" : "{left}{right}" )
clipboard := "#normalize""" . sNormalize . """)"
Send , ^v
Return
I've made a not-so-bulletproof fix, but it unfortunately requires me to use another keybinding, which I'm not a fan of:
^!+z::
clipboard:=""
While clipboard
Sleep 10
While !clipboard
{
Send ^x
Sleep 100
}
Sleep 20
Send {Right}
Sleep 5
Send {BackSpace}
Sleep 5
Send {BackSpace}
Send #normalize("
Sleep 20
Send ^v
Sleep 20
Send ")
return
It does what I wanted above, but it's not very bulletproof.
Off topic but thought I'd mention it
If you have many of such snippets an alternative could be Lintalist, it is developed in AutoHotkey so you can extend it with your own scripts and plugins. The above script could be replaced with the following snippet - here it uses the selected text in your editor but you can use the clipboard as well:
#
{
ViewBag.Title = "[[selected]]";
}
<p>[[selected]]</p>
You can group snippets in Bundles per application and/or language, assign hotkeys and search for them.
You can learn more about Lintalist here https://lintalist.github.io/ - available plugins here https://lintalist.github.io/#InteractiveBundleText

Send command, isn't something wrong with AutoHotkey?

So I have this game, called AirMech. It doesn't recognize mouse buttons as controls (yet) so I tried to use AutoHotkey to circumvent it until it's implemented.
#IfWinActive, AirMech
XButton1::Send c
Didn't work. So I tried SendGame, SendPlay and everything else, didn't work either. I googled it, and found out that some games don't recognize any Send commands at all.
Before giving up, I just tried a simple mapping:
#IfWinActive, AirMech
XButton1::c
It actually worked.
Is it expected than no Send command works, but the latter does? What if I wanted to trigger other actions ('c' plus a MsgBox, for instance)?
AutoHotkey has the ability to send keystrokes in a variety of different ways (SendRaw / SendInput / SendPlay / SendEvent). I'm not quite sure what approach the simple key::key mapping uses, but it must be one of them. My guess is that one of SendRaw, SendInput, SendPlay, or SendEvent will work the same as key::key.
Also #IfWinActive sometimes doesn't work exactly the way you expect, especially with fullscreen games. So I usually test my AHK scripts without the #IfWinActive to make sure they're working correctly. Once it's working, I introduce the conditional.
UPDATE
From http://www.autohotkey.com/docs/misc/Remap.htm:
When a script is launched, each remapping is translated into a pair of
hotkeys. For example, a script containing a::b actually contains the
following two hotkeys instead:
*a::
SetKeyDelay -1 ; If the destination key is a mouse button, SetMouseDelay is used instead.
Send {Blind}{b DownTemp} ; DownTemp is like Down except that other Send commands in the script won't assume "b" should stay down during their Send.
return
*a up::
SetKeyDelay -1 ; See note below for why press-duration is not specified with either of these SetKeyDelays. If the destination key is a mouse button, SetMouseDelay is used instead.
Send {Blind}{b Up}
return
My notes:
I suspect the reason a::b is working but a::Send b is not is because of how a::b breaks button down and button up handlers into two separate mappings. The game's gameloop probably polls the gameplay keys for "keydown" state, which would not be maintained consistently if AHK is synthesizing repeats. Remapping a_down->b_down and a_up->b_up probably makes AHK emulate more accurately the act of holding the key down, which may matter for programs which test for key state in particular ways (GetAsyncKeyState?).
The asterisk in the mapping means "Fire the hotkey even if extra modifiers are being held down."

ahk controlclick pokerstars waiting list

I am writing a script that will automatically click on the Waiting List button on the pokerstars lobby. I tried Click x,y and it works, but the problem with this is that if the focus switched from lobby to table, the raise/call button is clicked--DISASTER.
Looking for solutions, I found that ControlClick can do the job for me, but I can't get the script to work. I read about the parameters needed for ControlClick to work, and using different combinations of the paramters that I found using WindowSpy, I can't get the script to work.
Here are some of the lines I have already tried--
a::
SetControlDelay -1
ControlClick PokerStarsButtonClass34, PokerStars Lobby, Waiting List
return
a::
SetControlDelay -1
ControlClick x900 y65, Pokerstars Lobby, Waiting List
return
can you help me fix this--thanks
First, I would try omitting the WinText parameter of your ControlClick calls (that means removing the trailing ", Waiting List") because I'm not sure if the Stars Lobby actually has that text as part of its text visible via the window spy. The WinTitle should be enough.
If you search the AHK forums, you will find that there are many threads of people complaining that ControlClick is not properly sending clicks to buttons or windows. So your problem is not unique.
Now, afaik ControlClick is just a wrapper for sending WM_LBUTTONDOWN messages. But, in some cases, sending the messages directly actually does work, when ControlClick fails. In fact, this function is commonly used in AHK scripts designed for Pokerstars.
PostLeftClick(x, y, hwnd) {
PostMessage, 0x201, 0x0001, ((y<<16)^x), , ahk_id%hwnd% ;WM_LBUTTONDOWN=0x201
PostMessage, 0x202 , 0, ((y<<16)^x), , ahk_id%hwnd% ;WM_LBUTTONUP=0x202
}
So you can try the above function and see if it works. You'll need to get the handle of the lobby first, with something like lobbyhwnd := WinExist("Pokerstars Lobby") and then pass lobbyhwnd as the third param to the above function.
If it doesn't work, I would suggest just using Click normally, but explicitly activating the lobby before sending the click, that way you can be certain that the click gets sent to the correct window. For example:
a::
WinActivate, Pokerstars Lobby
Click x900, y65
return