Solution to a "dynamic"/"unstable" ahk_class name? - autohotkey

In AutoHotKey, ahk_class NAME has been a good identifier for programs. Typically, I now use it in the following two ways:
Simply calling the most recently called active instance:
; Pressing Win+Shift+X will bring up (or switch to) the Windows Journal
Application
#+x::
IfWinExist ahk_class JournalApp
WinActivate ahk_class JournalApp
else
Run C:\Program Files\Windows Journal\Journal.exe
return
Grouping windows with the same ahk_class and looping through them:
GroupAdd, FIRE, ahk_class MozillaWindowClass
; Pressing Win+3 will go through all open Firefox windows one by one.
#3::
IfWinExist ahk_class MozillaWindowClass
GroupActivate, FIRE, r
else
Run firefox
return
However, there are certain programs that do not have a stable ahk_class name. For example, the ArcMap.exe should
display the following information in the "Windows Spy" window of AHK:
>>>>>>>>>>( Window Title & Class )<<<<<<<<<<<
Untitled - ArcMap
ahk_class Afx:012F0000:b:00010003:00000006:001C0BB0
Any idea how could I refer to this application that has dynamic ahk_class?
I am aware that there is also something called ahk_exe. However, I did not find it compatible with the method GroupAdd,
GroupActivate or IfWinExist.

You definitely are on the right track trying to incorporate ahk_exe. GroupAdd (and every other command receiving a WinTitle parameter at that) is compatible with ahk_exe in AHK_L; this sample code works perfectly on my machine:
GroupAdd, notepad, ahk_exe notepad.exe
Run, notepad.exe
WinWaitActive, ahk_group notepad
Sleep, 1000
WinClose, ahk_group notepad
I suspect you're not using the most recent version of AHK. Get it here and have another try.

Related

WinActivate on specific criteria (include / exclude windows)

I'm stumped on how to best re-write my hotkey. What I want to do is simple. I have a script that switches to File Explorer IF it's currently open Else it will open a new file explorer window.
Here's the catch - It's hard to "identify" if the Explorer window is open. I used to just do this by using WinActivate, 00123456 because that's the name of the folder (eight-digit random number). But the problem with that is that these are support ticket numbers. And that number will also be within the title of my current Chrome session and sometimes other windows too (Firefox, Snagit, notepad, etc). So it will inadvertently switch to those other programs. So that led me to exclude in this way:
Ticket_Out := clipboard
xclude:= Ticket_Out . " | Salesforce - Google Chrome"
WinActivate, % Ticket_Out, , % xclude
That's handy except for it only excludes 1 window at a time. How could I implement something that excludes a second application? OR --- another thought, how could I just say: look for Explorer.exe with window title "00123456" ?
You can use ahk_exe to filter by the process name too:
WinActivate, ahk_exe explorer.exe %Ticket_Out%
Another way would be to look for the window class - since depending on the Windows version Explorer can use either CabinetWClass or ExploreWClass, you can use a group, as shown in the docs:
; Define the group: Windows Explorer windows
GroupAdd, Explorer, ahk_class ExploreWClass ; Unused on Vista and later
GroupAdd, Explorer, ahk_class CabinetWClass
; Activate any window matching the above criteria and the title
WinActivate, ahk_group Explorer %Ticket_Out%
Note on CherryDT's answer the two WinActivate examples are missing a comma between the WinTitle, and WinText parameters...
Should be....
WinActivate, ahk_exe explorer.exe, %Ticket_Out%
Second example (when using GroupAdd)
WinActivate, ahk_group Explorer, %Ticket_Out%
Caught me out for awhile.
(I would comment on the answer, but as a new user don't have 50 reputation)

Autohotkey : Wildcard ahk_class match

I used winspy to grab an ahk_class for my autohotkey macro. Sometimes that application has 2+ ahk_classes associated with that program
Example:
HwndWrapper[program.exe;;1111-1111]
HwndWrapper[program.exe;;2222-2222]
How can I use winNotExist to simply just match both names? Or perhaps use a ||, OR etc?
E.g.
F12::
IfWinNotExist, ahk_class "HwndWrapper.+"
Run, AQ8.exe
GroupAdd, kjexplorers11, ahk_class "HwndWrapper.+" ;You have to make a new group for each application, don't use the same one for all of them!
if WinActive("ahk_exe AQ8.exe")
GroupActivate, kjexplorers11, r
else
WinActivate ahk_class ahk_class "HwndWrapper.+" ;you have to use WinActivatebottom if you didn't create a window group.
Return
I finally figured it out. SetTitleMatchMode, Regex.
This command affects the behavior of all windowing commands, e.g. WinExist and WinActivate
Then write some javascript-like regex statements as arguments.
The full list of window commands is on AHK site
Script, revised
F12::
SetTitleMatchMode,RegEx
IfWinNotExist, ahk_class HwndWrapper.+
Run, AQ8.exe
GroupAdd, kjexplorers11, ahk_class HwndWrapper.+ ;You have to make a new group for each application, don't use the same one for all of them!
if WinActive("ahk_exe AQ8.exe")
GroupActivate, kjexplorers11, r
else
WinActivate ahk_class ahk_class HwndWrapper.+ ;you have to use WinActivatebottom if you didn't create a window group.
Return
So now I can cycle through any application with more than 1 ahk_Class name. Example of what script does

autohotkey to focus / open on google chromium

I have this autohotkey script that opens chrome if its not already on windows, and if it is, cycles through tabs within it. It also puts that chrome window on top of any other windows (e.g. excel docs, word docs, etc)
IfWinNotExist, ahk_class Chrome_WidgetWin_1
Run, chrome.exe
if WinActive("ahk_class Chrome_WidgetWin_1")
Send ^{tab}
else
WinActivate ahk_class Chrome_WidgetWin_1
Return
I can't seem to figure out how to get this to work for google chromium though. Both exe names are "chrome.exe", so I'm not sure what the run commands is if there's an overlap.
Also, I ran winSpy but still am not 100% sure what ahk_class name is. Below is the information from winSpy
I ended up settling for a different solution
After 2 days of tweaking and testing some workflows, this is what I settled with. I ran a combination of both phrase-express (any macro program works here) and autohotkey here, so I can have an extremely flexible layout
F1 → Binded to WIN+1 key
F2 → Binded to WIN+2 key
F3 → Binded to Win+4 key
F4 → Binded to Win+4 key
For F5 to F7 keys, I used autohotkey
F5::
IfWinNotExist, ahk_class Chrome_WidgetWin_1
Run, chrome.exe
GroupAdd, kjexplorers5, ahk_class Chrome_WidgetWin_1 ;You have to make a new group for each application, don't use the same one for all of them!
if WinActive("ahk_exe chrome.exe")
GroupActivate, kjexplorers5, r
else
WinActivate ahk_class Chrome_WidgetWin_1 ;you have to use WinActivatebottom if you didn't create a window group.
Return
F6::
IfWinNotExist, ahk_class ConsoleWindowClass
Run, cmd.exe
GroupAdd, kjexplorers6, ahk_class ConsoleWindowClass ;You have to make a new group for each application, don't use the same one for all of them!
if WinActive("ahk_exe cmd.exe")
GroupActivate, kjexplorers6, r
else
WinActivate ahk_class ConsoleWindowClass ;you have to use WinActivatebottom if you didn't create a window group.
Return
F7::
IfWinNotExist, ahk_class QWidget
Run, anki.exe
GroupAdd, kjexplorers7, ahk_class QWidget ;You have to make a new group for each application, don't use the same one for all of them!
if WinActive("ahk_exe anki.exe")
GroupActivate, kjexplorers7, r
else
WinActivate ahk_class QWidget ;you have to use WinActivatebottom if you didn't create a window group.
Return
F5 to F7 uses the same variant autohotkey, I just changed up the groupnames, the .exe files , and the ahk_class names.
This is how I organize the structure of my windows taskbar
So I press
F5 (3 times), and it pushes each chrome window I have up to the top of each of my 3 monitors.
F6 and I can quickly pop out whatever command prompts I have open, one command prompt for gulp commands, and one for git, independent of any IDE.
F7 twice to quickly add some new flashcards
I can restructure F1 F2 F3 F4 to whatever app I'm currently using. Anything that goes here I only keep one window per app at a time. Like I only run one firefox window (to watch tutorial youtube videos), only one running application of PHPstorm, etc.
Demonstration of F6 key in action (command prompt)

What is ahk_class? How can I use it for window matching?

The AutoHotkey Beginner Tutorial includes a sample script to demonstrate window specific hotkeys and hotstrings.
#IfWinActive ahk_class Notepad
::msg::You typed msg in Notepad
#IfWinActive
#IfWinActive untitled - Paint
::msg::You typed msg in MSPaint!
#IfWinActive
The second example is fairly self-explanatory: Check for a window named "untitled - Paint". It's the first example's use of ahk_class that has me confused.
I haven't been able to find any explanation of the variable in the AHK documentation. According to an AHK forum post, ahk_class is the name of a window as given by Windows Spy, the post didn't go into any more detail.
Would there be any difference between using ahk_class Notepad and Untitled - Notepad? Would the second example work if replaced with #IfWinActive ahk_class Paint?
What is ahk_class and how can I use it for window matching?
From https://autohotkey.com/docs/misc/WinTitle.htm#ahk_class
A window class is a set of attributes that the system uses as a template to create a window. In other words, the class name of the window identifies what type of window it is.
In other words you can use it to identify windows of the same type, if you open notepad the title will be Untitled - Notepad if you save it to temp.txt the title will become temp - Notepad. ahk_class on the other hand will always remain Notepad.
The second example will work if you replace it with #IfWinActive ahk_class MSPaintApp because that's the class of mspaint.
Usually you find ahk_class using Window Spy and then use it in your scripts. If you don't have Window Spy you can use the following hotkey:
#1::WinGetClass, Clipboard, A ; Will copy the ahk_class of the Active Window to clipboard
After you found it you can use it in any place you can use window title for example instead of writing WinActivate, Untitled - Notepad you can write WinActivate, ahk_class Notepad.
Check this article. Ahk_class is the class that is given to you when you use the WindowSpy tool. This tool should be in the same folder as your AutoHotkey executable.

AutoHotKey select pop-up window not work

I write a script to test selecting pop-up windows.
SetTitleMatchMode, 2
winTitle:="RGui (64-bit) ahk_class Rgui Workspace ahk_exe Rgui.exe"
popWin:="ahk_class #32770 ahk_exe Rgui.exe"
IfWinExist,%winTitle%
{
WinActivate
send !{F4}
}
IfWinExist,%popWin%
{
WinActivate
WinWaitActive, %popWin%
WinGetClass, outputvar, %popWin%
MsgBox %outputvar%
}
This script is intended to send ALT-F4 to close an opened R window, and when the confirmation pop-up window occurs, display the pop-up window's class name.
The first if block works fine. However, the send if block sometimes works, sometimes not. Active window info shows the pop-up windows' class info is:
Window Title, Class and Process
Question
ahk_class #32770
ahk_exe Rgui.exe
snapshot of the above info
I don't know why IfWinExist,%popWin% does not work. I tried changing popWin:="ahk_class #32770 ahk_exe Rgui.exe" to popWin:="ahk_class #32770", still it sometimes works, and sometimes not. So what should I do to select the pop-up windows correctly?
I have changed your AutoHotkey code, such that it should give you the functionality you require.
SetTitleMatchMode, 2
winTitle:="RGui (64-bit) ahk_class Rgui Workspace ahk_exe Rgui.exe"
popWin:="ahk_class #32770 ahk_exe Rgui.exe"
if (hWnd := WinExist(winTitle)) ;this assigns hWnd, it does not compare hWnd with WinExist(winTitle)
{
;WinActivate, ahk_id %hWnd%
;send !{F4}
WinClose, ahk_id %hWnd% ;WinClose is more direct than Alt+F4 if it works (Send can potentially send key presses to the wrong window if a new window suddenly appears)
}
WinWait, %popWin%, , 5 ;wait for window to exist, give up after 5 seconds
if !ErrorLevel ;if window found within 5 seconds
{
WinGet, hWnd, ID, %popWin%
WinActivate, ahk_id %hWnd%
WinGetClass, outputvar, ahk_id %hWnd%
MsgBox %outputvar%
}
Note:
In most cases WinActivate requires a window title/hWnd be specified.
The second part of your code works sometimes but not other times, probably because if the popup appears very quickly, then IfWinExist will find the window, but if the popup appears slowly, then the IfWinExist check will occur before the window exists, and will thus not find the window.