Menu and submenu selection on specific app via Autohotkey - autohotkey

I have a dictionary application in which Ctrl+C does not work, so the only way to copy is to go from the menu, Edit > Copy. I have tried using the following code and variations of it, but it did not work.
!l::
WinActivate, MAGENTA - Dictionaries Explorer II
WinMenuSelectItem, ahk_class TMainForm,, Edit, Copy
return
WinSpy data:
MAGENTA - Dictionaries Explorer II
ahk_class TMainForm
ahk_exe MgDE2.EXE
ahk_pid 2580

Forgetting AHK for a minute, if you just press and release the Alt key (all by itself) what happens?
If the File menu activates (blue box), then you can just send the ALT keystroke followed by directional movement as needed and finally sending ENTER to activate the item
Like this
SendInput {Alt}{Right}{Down}{Enter}
If you needed to go right 4 elements and then down 2 entries you would use this way:
SendInput {Alt}{Right 4}{Down 2}{Enter}

Related

How to hold a modifier key so ahk sends keypresses to a different window

I'm pretty new to ahk.
Say I have two separate vlc windows open and playing videos.
If one of the vlc windows is active, then I want to be able to hold a key to make all keypresses go to the other vlc window.
ie if I press Left, then it sends Left to the active vlc window, but if I hold ALT+Left, then it sends Left to the other vlc window.
If no vlc window is active, then I don't want autohotkey to do anything.
This is so I can control two vlc windows without having to click and choose which one is active.
I looked up GroupAdd hoping I could use a group that includes both vlc windows, but couldn't find a way to target specific vlc windows from the group to send keys to it.
edit: I got a very basic version working, but I feel it's pretty ugly. I would like a way to send any key that's pressed if you hold Shift to the other vlc window. Also this seems a bit unreliable in switching focus if you use it a few times quickly in succession.
GroupAdd, vlcgroup, ahk_exe vlc.exe
return
#IfWinActive ahk_exe vlc.exe
+Left:: ; shift-left
GroupActivate, vlcgroup, r
Send {Left}
GroupActivate, vlcgroup, r
return
A simple approach could be done like this:
#IfWinActive, ahk_exe vlc.exe
+Left::
WinGet, WindowList, List, ahk_exe vlc.exe
BottomMostVlcHwnd := WindowList%WindowList%
ControlSend, , {Left}, % "ahk_id " BottomMostVlcHwnd
return
^+Left::
WinGet, WindowList, List, ahk_exe vlc.exe
BottomMostVlcHwnd := WindowList%WindowList%
ControlSend, , ^{Left}, % "ahk_id " BottomMostVlcHwnd
return
...
#IfWinActive
You'd write out each hotkey.
WinGet, , List(docs) returns a legacy pseudo-array(docs) of hwnds to Vlc windows.
The last element in that array will be the bottom most window.
You can get the last element of a pseudo array via a dynamic variable trick WindowList%WindowList%.
Essentially you're accessing a variable named WindowListN, where N is the number for the last element in the pseudo-array.
Then ControlSend(docs) is used to send keys to the background window without the need to activate it.
And you refer to the background window by a window name like ahk_id 0x1234567(docs).
Of course writing out the hotkey for each key is pretty repetitive, so we can do something much better:
#IfWinActive, ahk_exe vlc.exe
+Left::
^+Left::
+Right::
^+Right::
+PgUp::
+PgDn::
WinGet, WindowList, List, ahk_exe vlc.exe
ControlSend, , % StrReplace(A_ThisHotkey, "+", "{") "}", % "ahk_id " WindowList%WindowList%
return
#IfWinActive
The hotkey definitions are just stacked on top of each other.
(If there were even more definitions, a loop with the Hotkey(docs) command could be nicer)
A_ThisHotkey(docs) will contain the hotkey that was used, and StrReplace(docs) is used to automatically replace the + with a {.
And finally the closing brace } is appended to the end.

AHK shortcuts for Alt+Space in Windows

running AHK in Windows 10, and I'm trying to create shortcuts for the Alt+Space menu. Specifically, I often use this sequence:
Press keys Alt+Space (bring up the window menu)
Press key S (select Size to resize)
Press key Left (now moving the mouse is resizing your window horizontally)
Press key Up (now moving the mouse is resizing your window in all directions)
Once this sequence is pressed, you can move your mouse to resize the active window as if you click-dragged the top-right corner, without having to hunt for that corner. (to finalize the resizing you can press Enter of LeftMouseKey, or Esc to abort). I'd like to get to this state with a single shortcut.
Here is my current script, binding to Winkey+Ctrl+Shift+1
;resize window from Top-Left
#^+1::
SendInput !{Space}
Sleep 100
SendInput s
Sleep 100
SendInput {Left}+{Up}
Return
It works mostly, but sometimes the active window will consume the s {Left} {Up} commands, rather than the popup menu. Thus, sometimes this shortcut will result in the active window like VSCode having the "s" character and the cursor 1 line up from before (as if typing s {Left} {Up}), and a visible Alt+Space menu.
I initially used Sleep 10 and thought Sleep 100 would fix this, but it didn't. The shortcut already feels slow with 2x Sleep 100 built in.
I'd like to test if the Alt+Space menu is open before SendInput s and preferably make sure I'm sending to the menu rather than the main application.
I was unable to reproduce the problem using your method. Perhaps try using Send, SendEvent, SendPlay, SendRaw, #InstallKeybdHook, #UseHook
Alternatively, use Autohotkey's WinMove statement:
This resizes the active window such that the upper left hand corner is at the current mouse position
#^+1::
CoordMode Mouse, screen
id := WinExist("A")
WinGetPos x, y, width, height, ahk_id %id%
MouseGetPos mx, my
neww := width + x - mx
newh := height + y - my
WinMove % "ahk_id" id,, mx, my, neww, newh
return
The menu itself is ahk_class #32768, so waiting for it to exist seems to work for me.
#^+1::
Send , !{space}
WinWait , ahk_class #32768 ,, 1 ; Waits 1s for menu to exist
If !ErrorLevel ; ErrorLevel is 0 if menu exists
Send , s{left}+{up}
Return
Jim U's alternative solution is a more reliable way of doing what you're trying to achieve, but this will make what you currently have work.

Autohotkey: task to copy from browser and paste on text editor

I'm trying to build a script that uses both a browser and a texteditor. The workflow I can summarize as follows:
Right click on a video for streaming
Click on the option to copy the redirection link
Switch to a text editor (Slickedit in my case)
Paste the copied link
Go back to the browser and await next command.
I want to automate this with a single key press while I am standing on the link with the mouse. This has been
my attempt:
^+!a::
Click Right, 392, 64 ;execute in browser
Click Left, 410, 79 ;
Send, !{Tab} ;switch to text editor
Send, ^V ;paste in text editor
Send, !{Tab} ;switch back to browser
return
The script isn't working correctly because it appears not to be executing the ^V command.
I suspect it's because it is executing it before Slickedit is even active. How can I syncronize
these KeyPreses so that they are executed at the right times? Also is there a nicer way for me to
switch to Slickedit without relying on the alt-tab?
There are a few things you could use to make your script better. WinActivate, clipboard, and improved mouse movement seem to be good ones to add.
^+!a::
clipboard = ; clears clipboard
Click Right ; execute in browser
MouseMove, 18, 15, 50, R ; Moves mouse relative to start location
Click Left
ClipWait, 2 ; Waits 2 seconds for clipboard to contain something
WinActivate, Slickedit ; Switch to text editor
WinWaitActive, Slickedit
Send % clipboard ; paste in text editor
WinActivate, ahk_class Chrome_WidgetWin_1 ; or your browser of choice
Return
Use the included Window Spy to find the correct Window titles or classes to be used in the WinActivate commands.

Creating a Mouse Hotkey

I've been using AHK in a very simple form for years, but multiple attempts at learning the more advanced functions has just resulted in confusion and frustration.
At the moment I'm trying to create a script that'll send the hotkey "CTRL + W" to Google Chrome when I hold the tilde key and left click inside the Google Chrome window. Whenever I trigger the script, it seems to close every single tab then the browser itself.
My script is below - what am I doing wrong?
#IfWinActive ahk_class Chrome_WidgetWin_1 ;Checks that the active window is Google Chrome.
` & LButton:: ;Tilde + Left Mouse Button
Send, ^+w ;Sends CTRL + W to the window.
return ;Ends the script.
Your script looks almost right. Try this. After you defined all the keys, you must "close" #ifwinactive ...
#IfWinActive, ahk_class Chrome_WidgetWin_1
` & LButton::Send, ^+w
#IfWinActive
Splitting the hotkey over multiple lines in not wrong, but in this case it can be done in one line. When you run into a problem like this. Try to isolate the issues. First ONLY try a bare ' & LButton::Send X to see if this works and be aware that you now loose the ` sign. Then try it with ^+w and when that works try it with #IfWinActive.
When you want to "restore" the tilde key, you could add this line:
~`::Return
The ~ will pass on the key data to the OS before executing the NOP (Return).

How does this AHK script work?

The following AHK script automatically brings up the menu that you would normally get when you right-click on the uTorrent icon in the system task-bar tray:
DetectHiddenWindows, On
Process, Exist, utorrent.exe
WinGet, W, List, ahk_pid %ErrorLevel%
Loop %W%
{
WinGetClass, Class, % "ahk_id" W%A_Index%
If InStr( Class, "µTorrent" ) {
hWnd := W%A_Index%
Break
}}
PostMessage, 0x8001, 0,0x204,, ahk_id %hWnd% ; Right Click down
PostMessage, 0x8001, 0,0x205,, ahk_id %hWnd% ; Right Click Up
I understand most of it except the last two lines. 0x8001 is WM_APP+1. Why is a message in the WM_APP range used, and what exactly happens when these two messages are issued? Many thanks for the explanation.
According to MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644927(v=vs.85).aspx#system_defined)
If your application is marked version 4.0, you can use message-identifier values in the range 0x8000 (WM_APP) through 0xBFFF for private messages.
So this would indicate that 0x8001 is an identifier that utorrent has chosen for a message. The 0x204 and 0x205 values are for the Right-Click Down and Up events respectively. My guess is that this code is intended to simulate a Right-Click on utorrent's icon in the Windows tray.
Also, if you're using Autohotkey_L the code can probably be simplified to three lines and perform the same:
DetectHiddenWindows, On
PostMessage, 0x8001, 0,0x204,, ahk_exe utorrent.exe ahk_class µTorrent ; Right Click down
PostMessage, 0x8001, 0,0x205,, ahk_exe utorrent.exe ahk_class µTorrent ; Right Click Up
When you right click on something, the context menu is shown. The context menu can also be shown by pressing the appskey button on the keyboard. When you press it, Windows sends the application a message, i.e., the WM_APP message. Most applications respond by showing a context menu. In the case of the tray icon, the response is the same as the response to a right-click.
Seems that the WM_APP+1 message number is a choice made in the development of the application, in this case utorrent. Could have been another message #, nothing magic. I believe the code I presented (which is from the AHK forums) figured out the message to send through reverse engineering.