AHK WinActive not recognizing window - window

I'm trying to make a hotkey available to only a sub-window (or toolbox-stlye-window) of Reaper.
Using this "tutorial" on AHK #If and If:
https://stackoverflow.com/a/36175810/7863776
I got this far:
#If (WinActive("Plug-in pin connector"))
^Space::
Click
MouseMove, 16, 16, 0, R
Click
MouseMove, 16, 16, 0, R
Return
#If
When I use the hotkey after clicking into the correct window, the keypress isn't caught by AHK. Doing this with the hotkey outside an If, AHK catches the hotkey but nothing happens. This leads me to believe WinActive isn't seeing the window, while Windowspy clearly does.
These also don't help:
SetTitleMatchMode, 2
DetectHiddenWindows, On
Windowspy shows this
The only sure way to make this hotkey exclusive to that window is with the title "Plug-in pin connector", though neither "ahk_exe reaper.exe", nor "ahk_class #32770" work. I'd be happy if they did.
AHK is running as admin.

Based on our discoveries with ACC viewer, please see if this works for you:
^Space::
WinGetText , sWinText , A
If InStr( sWinText , "Plug-in pin connector" )
MsgBox , It worked!
Else
MsgBox , It didn't work....`n`nHere's what was found: %sWinText%
Return
Edit: As found by OP in comments below, ControlGetText can be used to detect whether the "Plug-in pin connector" window is active.

Related

How to adjust window placement with AutoHotkey?

I can run all of my programs with AutoHotkey, but I'm trying to open them all in specific locations on my 3 monitors. I played with some code but couldn't get it to change at all. This is what I have so far for one of my folders that I'm trying to open with this hotkey:
Run, C:\Python\LPTHW
WinActivate
WinMove A,, 10, 10, A_ScreenWidth-20, A_ScreenHeight-20
I got this code partially from another forum and I only kind of understand what it does, but modifying the numbers doesn't change anything about how it opens, and every once in a while it makes all my desktop icons disappear when I run it.
Couple things you should probably know. The A tells WinMove to move the active window. It's best to call out specifically what you're trying to move. And, the Width and Height parameters need to be forced as expressions. Take a look and see if you can alter your code to work based on the notepad example below.
Run, notepad
WinWaitActive, Untitled - Notepad
WinMove, Untitled - Notepad,, 0, 0, % A_ScreenWidth/2, % A_ScreenHeight/2

Steal focus as SetForegroundWindow can't do it

I know this sounds evil but my intention is not this at all.
A user has clicked "delay shot" and a countdown starts, during that time they go focus another application, then after countdown user expects my app to take back focus.
SetForegroundWindow fails when it runs from appliction with PID X while application with PID Y is focused.
This worked to bring my window forward, but it doesn't get focus:
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
It sets the window to be always on top. However focus is not put into my window. And then setting it back to HWND_NOTOPMOST leaves it there, even though its not top most, but it still doesnt have focus. Running SetForegroundWindow won't do the trick after these calls to SetWindowPos Is there anyway to steal focus?
I have tried a combination of:
SwitchToThisWindow
SetWindowPos
ShowWindow
SetForegroundWindow
But can't seem to figure it out.
Another reason I think this has to be possible is because Mac OSX allows it with NSApplication activateIgnoringOtherApps: and Linux's allow it too. I'd like to get this cross platform.
As a last resort I was going to use the HWND_TOPMOST method, then GetWindowRect then SetCursorPos and send single click to my window at pos 0,0, I really don't want to though as there might be something at 0,0 and it shouldn't be auto clicked on.
This always works, no matter what app is in foreground (like Task Manager, etc.):
AllocConsole();
auto hWndConsole = GetConsoleWindow();
SetWindowPos(hWndConsole, 0, 0, 0, 0, 0, SWP_NOZORDER);
FreeConsole();
SetForegroundWindow(hWnd);
As the comment says, SetForegroundWindow is sometimes useless intentionally. Basically, two ways are used to bypass restrictions:
Simulate keyboards / mouses
Get privileges
There is some smarter magic to achieve the goal without directly clicking the window you are going to activate. Since I'm not familiar with GUI, I would suggest inject code directly into current foreground window and hand over the foreground right.
Besides there're some examples on simulating.
http://www.codeproject.com/Tips/76427/How-to-bring-window-to-top-with-SetForegroundWindo.aspx

AutoHotKey - "Continue" and "Cancel" Buttons

I am a newbie with AutoHotKey, and to this point I consider myself fortunate to have created a script to automate about 90% of the data entry in a window. I'm now trying to kick it up a notch and add a warning/caution GUI to my data entry script. I want to pause the running script and open a GUI that will alert me to look at what has already been entered, with one button to allow things to proceed if a particular entry looks OK, and another to dump out of both the GUI and the remainder of the script if the entry is incorrect.
Here's some code I came up with, mixed with some pseudocode to help show what I want to do.
(Previous data entry script executes to this point)
Stop the script
Gui, New
Gui, Add, Text, 'n Check Authorization Number to be sure it is A1234 (FY 15). ; Wraps text
Gui, Add, Button, Default, Continue
Gui, Add, Button, Quit
Gui, Show, IMPORTANT!
If Continue button is clicked
----Continue with script
If Abort button is clicked
----Close the GUI
----Exit the entire script
(Resume where I left off with rest of the data entry script)
I've read the AHK Help file and am stumped about how to make these buttons work, as well as how to properly return from the GUI back to the script if I hit continue, or quit the whole thing if I spot a problem. I can tweak things like the size of the GUI and the button placement; what's most important is getting the GUI code right. Can someone help with the code? (The last programming class I took was in 2003, so I have forgotten a whole lot!)
In your case, a GUI would be overkill. AHK (and many other languages at that) provide standard dialogs for simple user interaction called message boxes.
Message boxes in AHK can be displayed in two ways:
MsgBox, This is a simple message. Please click "OK".
MsgBox, 4, Attention, Here`, you can choose between "Yes" and "No".
In the second case, we declared an option which controls the buttons that are displayed. You can use IfMsgBox in order to detect what the user has clicked:
IfMsgBox, Yes
MsgBox, 4, Really?, Did you really mean "Yes"?
Putting these pieces together, we can ask the user to decide if they want to continue, without the need to create a GUI, in a few lines:
; Option "1" is "OK/Cancel"
MsgBox, 1, IMPORTANT!, Check Authorization Number to be sure it is A1234 (FY 15).
IfMsgBox, Cancel
{
ExitApp
}
; do stuff
This code addresses each of your other problems, too:
A message box halts the current thread until the user dismisses the dialog or it times out (if you specifically declared a timeout).
To completely stop the execution of our script, we use ExitApp.

AutoIt and WinWaitActive()

I am writing an AutoIt script which attempts to open an application (Vision). When this application is open, the script intends to access an option from the menu which in turn causes another window within the same application to be opened. After configuring and saving some settings, the control is again returned back to the main window in the application (Vision). I intend to automate this whole thing using AutoIt. However, WinActivate() behaves weirdly. How do I resolve this?
The following is my code:
Dim $num, $file_name, $opening_file
$num = 1
$file_name = "Hello"
$opening_file = "Vision - [" & $file_name & "]"
Opt("WinTitleMatchMode", 2);
AutoItSetOption ("TrayIconDebug", 1);0-off
Local $pid_handle = ProcessExists("Vision.exe")
If $pid_handle Then
ProcessClose($pid_handle)
Endif
Run("C:\Program Files\Vision.exe")
WinWait("Vision - [Start Page]")
WinWaitActive("Vision")
SendKeepActive("Vision")
sleep(3000)
Send("!f")
Send("n")
WinWait("Capture Options - ")
WinWaitActive("Capture Options - ")
SendKeepActive("Capture Options")
ControlClick("Capture Options", "", 32494)
sleep(1000)
ControlSetText("Capture Options", "", 1487, $file_name, "")
Send("{DOWN}")
Send("{Tab}")
WinActivate("Capture Options - ")
ControlClick("Capture Options", "", 32494)
sleep(1000)
Send("{DOWN}{Tab}")
ControlCommand("Capture Options", "", 1471, "ShowDropDown", "")
If $num = 1 Then
ControlCommand("Capture Options", "", 1471, "SelectString", "1 - here u go")
Elseif $num = 2 Then
ControlCommand("Capture Options", "", 1471, "SelectString", "2 - blah blah..")
EndIf
sleep(2000)
Send("{ENTER}")
ControlClick("Capture Options", "", 1)
sleep(1000)
WinActivate("Vision")
WinWaitActive("Vision")
SendKeepActive("Vision")
sleep(2000)
Send("^!y")
The problems that I face are as follows:
a) Though the Vision.exe gets opened using the Run() command, if I happen to click on some other window [GUI/Desktop/Browser], the Vision GUI loses focus and the AutoIt script gets stuck up at WinWaitActive() line forever and never returns. Isn't AutoIt supposed to bring the focus onto the Vision GUI by itself?
This way, I see the whole of my automation script fail, if I happen to meddle with the system when it just about happened to open the Vision GUI. How do I fix this?
b) As I said earlier, the flow that needs to happen is:
Vision GUI gets opened.
Using Alt + F or similar commands, I happen to open another dialog box in the GUI. This causes some configuration settings to be applied. I save, and I return back to the vision GUI main window. Now the problem that I face here is that sometimes the Vision GUI's main window is never activated by AutoIt and here too I end up waiting on the WinWaitActive line. Isn't it supposed to have activated Vision main window before reaching the second line?
WinActivate("Vision")
WinWaitActive("Vision")
SendKeepActive("Vision")
sleep(2000)
Send("^!y")
Two main problems... First for your point a) you should just use WinWait instead and then you can use WinActivate to set it as the active one. After WinActivate you don't need to use WinWaitActive - you can check its return code instead.
Second for point b) you need to behave kind of the same way. You can (with absolute care) use BlockInput(True) before you start activating your Window and then sending some keystrokes, etc to prevent the user from "stealing" the Window Focus. And after you are finished, you should immediately use BlockInput(False). However, it might still occur, that some other application pops up and becomes the active window... For this, you might check for your active window always before perfoming something with it... But it's much better for such cases to try to use the Control... functions because they don't depend on the window to be the active one...
And finally, you should just once determine your windows handle ($handle = WinExists("Vision")) at the topmost possibility and then just use its handle for further usage of Win... functions like WinGetTitle($handle). Because especially when you open popup windows within your application, they might have the same word in its title. So it might not be sure that your commands are being executed with the window you suppose them to be. After getting the PID of your newly run window you might consider using it to receive its windows handle - there are functions in the AutoIt forums to receive a handle from a PID. So you can be sure to use the exact window you are supposing to use.
Oh - and the usage of control IDs is really bad. Who can assure you, they won't change? Use some control names instead... see the section about "extended control title definition" or so in the documentation for these possibilities...

alarm on screen change

I have to use a software which list my clients processes. I need a sound alert program if something change on 50x10 pixel region. I try to write a program on autohotkey but i can't succeed in. Anybody have this program?
Here is an example that you can use.
^Launch_Media:: ; Make a reference screenshot with NirSoft NIRCMD by pressing Ctrl+Media or any other program...
run, "C:\Program Files\1 My Programs\nircmd.exe" savescreenshot "c:\Temp\Screenshot.bmp" 33 40 17 20 ; Location of "Save As" Icon in SciTE4AutoHotKey Editor
Return
Launch_Media:: ; Launch this test manually with Media Button
CoordMode Pixel ; Interprets the coordinates below as relative to the screen rather than the active window.
ImageSearch, FoundX, FoundY, 0, 0, 200, 200, C:\Temp\Screenshot.bmp ; search for image in area staring at 0,0 to 200,200
if ErrorLevel = 2
MsgBox Could not conduct the search.
else if ErrorLevel = 1
MsgBox Image could not be found on the screen.
else
SoundBeep, 1000, 1000
MsgBox The Image was found at %FoundX% %FoundY%.
ClickX:=FoundX + 5 ; Move the mouse click away from the edge of the icon
ClickY:=FoundY + 5 ; Move the mouse click away from the edge of the icon
Click, %ClickX%, %ClickY% ; Click on the Save As icon.
Return
When we know more about what you want to test (I think that an area of 50x10 might be too small), and what you want to do in case the area has changed, we might be able to help you with a more suited script.
In this example I used NirSoft's nircmd.exe, but you can create a reference image by other means as well. If You only need an audible alarm, you can comment all the other commands under if, then, else out with ;.
Did you check this post from 2 years ago in the AutoHotKey community?
http://www.autohotkey.com/board/topic/56219-fast-screen-change-check-using-histograms/
The above script might be a little overwhelming, but you can also create a screenshot of a fixed area and do an image comparison in AutoHotKey as others have done before you.

Resources