Page 1 of 3

OnWin() - call function on window event (WinWaitXXX async)

Posted: 18 Feb 2015, 23:41
by Coco
OnWin.ahk

Version: 1.1.00.00

License: WTFPL

Requirements: Latest version of AutoHotkey


Installation:
Copy into a function lib folder (for auto-#Inclusion) or use #Include manually. Note: Script must not be copy-pasted into the main script
Syntax: OnWin( event, WinTitle, callback )

Parameter(s):
  • event - Window event to monitor. Valid values are: Exist, Active, Show, Hide, Move, Minimize, Maximize, NotActive/!Active, Close/NotExist/!Exist, CloseAll/NotExistAll/!ExistAll
  • WinTitle - see WinTitle. Due to limitations, ahk_group GroupName is not supported directly. To specify a window group, pass an array of WinTitle(s) instead. OnWin() uses A_TitleMatchMode and A_TitleMatchModeSpeed.
  • callback - Function name, Func object or object. The callback will receive an event object with the ff properties: Event and Window, as its first argument.
About Window Events:
Spoiler
Example Usage:

Code: Select all

#Include <OnWin>
#Persistent
 
OnWin("Exist", "Calculator", Func("C"))
Sleep, 1000
Run, calc.exe
return
 
C(this)
{
	static window
	event := this.Event, window := this.WinTitle
	MsgBox, Event: %event%`nWindow: %window%
	OnWin("Close", window, Func("X"))
	SetTimer, close, -1000
	return
close:
	WinClose, %window%
	return
}
 
X(this)
{
	event := this.Event, window := this.WinTitle
	MsgBox, Event: %event%`nWindow: %window%
	SetTimer, exit, -1 ; allow function to return
	return
exit:
	ExitApp
}
Edit: Changed example code

Credits to Lexikos for demonstrating ObjRegisterActive and jNizM for CreateGUID. I have integrated some parts as needed.

Edit:[list][*]Bumped version to v1.0.03.00, see commit 151bda8 - 02/23/2015
[*]Updated to reflect commit 7878f45 - 02/21/2015
[*]Updated to reflect commit ab9052a - 02/19/2015[/list]

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 01:18
by joedf
Awesome.

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 01:32
by boiler
This is going to be very useful. Thanks for sharing it. Is there a limit to how many windows and/or events can be set to be monitored simultaneously?

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 01:39
by boiler
Another question: I don't see Resize as an event. Will a resize of a window without its x,y changing trigger the Move event?

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 01:52
by Coco
boiler wrote:This is going to be very useful. Thanks for sharing it. Is there a limit to how many windows and/or events can be set to be monitored simultaneously?
It should be able to handle lots of windows events. However, ahk_group is not supported (OP updated regarding this).
boiler wrote:Another question: I don't see Resize as an event. Will a resize of a window without its x,y changing trigger the Move event?
Yes, window sizing is covered my Move

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 02:29
by Guest
It is a good practice when making a function/class to include version (of your script/class/function) and links to your code as a comment top of the file.

This is going to be useful, thanks.

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 02:50
by Coco
Guest wrote:It is a good practice when making a function/class to include version (of your script/class/function) and links to your code as a comment top of the file.

This is going to be useful, thanks.
Thanks for the advice. I'm really poor w/ versioning and just rely on the commit. I guess I'll start now. Will make the changes on the next commit. :) OK I've officially version-ed the script + added link to GitHub and forum topic + some minor improvements.

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 03:55
by empardopo
Thanks! More examples are also very useful.

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 06:56
by Coco
Update:
Added support for window groups. Instead of passing ahk_group GroupName, pass an array of WinTitle(s). (e.g.: ["Untitled - Notepad", "Calculator" . . . ]

Demo does not work

Posted: 19 Feb 2015, 09:03
by hoppfrosch
Hmmm... what is supposed to happen in your demo?
Opening notepad - as soon as Notepad window exists I would expect a msgbox to be fired- On closing Notepad a msgbox should be fired as well

... but no msgboxes can be seen here (running most recent example and just having cloned your github-repository) (OnWin v1.0.01.0)

My system:

AutoHotkey : v1.1.19.03-28+gc7055e7 Unicode 32-bit (Installed)
SystemType : x64-based PC
SystemOS : WIN_7 64-bit Service Pack 1 v6.1.7601 (WIN32_NT)

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 09:12
by Coco
v1.1.19.03-28+gc7055e7, I see that you're running the test build. Just tested and works fine here...Same OS except 32bit. make sure you #Include it and not copy-paste into the main script.

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 09:26
by hoppfrosch
Coco wrote:v1.1.19.03-28+gc7055e7, I see that you're running the test build. Just tested and works fine here...Same OS except 32bit. make sure you #Include it and not copy-paste into the main script.
Already included it (tried #include <OnWin> as well as #include %A_Scriptdir%/OnWin.ahk) and verified correctly stepping in OnWin-function via debug-output ... (which skows that OnWin is only called for NP_Exist)
... but no Msgboxes are fired.

Will try several variants of AHK (2.0/1.19 Test/Non-Test, Ansi/Unicode, 32/64) ...

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 09:37
by Coco
I've tested it w/ 1.1.19.03 32-bit(Unicode and ANSI), 1.1.19.03-28+gc7055e7 32-bit(Unicode) and 2.0-a058-fa7ed04 - works fine on all.

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 10:07
by Relayer
Coco,

I like it because I can replace timers that check for existence of windows periodically. I have a script that runs when an Excel spreadsheet becomes active but I'm finding that your utility does not sense the close of the Excel program unless I set "DetectHiddenWindows" to "Off" in your code. I don't quite understand it largely because I don't understand all of the nuances of hidden windows.

Relayer

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 11:45
by Coco
Edit: Ok, I found a nuance (for the Close event) when multiple windows match the WinTitle criteria. Apparently, WinWaitClose %WinTitle%(WinTitle specified explicitly) seems to trigger only until the last of the matched windows is closed. An option is to add a way to customize the behavior for Close on whether to behave like WinWaitClose %WinTitle%(WinTitle specified explicitly) OR WinWaitClose(uses the "last found" window, obviously WinExist() should be called prior)

@Relayer, use the Close/NotExist/!Exist event to detect when the window no longer exists(destroyed). Otherwise, if you want to detect if it's just hidden(e.g. minimized to tray, etc.), use the Hide event. You need not change DetectHiddenWindows. Close works for me with Excel using SetTitleMatchMode 2 and specifying Microsoft Excel for WinTitle. Also, make sure that the WinTitle does not change etc., OS version might play a part as well. Try the code below: (Run MS Excel first, then run the code, then close MS Excel)

Code: Select all

#Include <OnWin>

SetTitleMatchMode 2
OnWin("Close", "Microsoft Excel", "X")
return

X(this)
{
	event := this.Event, window := this.Window
	MsgBox Event: %event%`nWindow: %Window%
	SetTimer exit, -1
	return
exit:
	ExitApp
}
I'll be doing some tests with commonly used applications to improve detection... I don't really play with AHK's window commands so it's trial and error on my end as well. :)

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 19 Feb 2015, 15:00
by mozmax
Awesome! Thanks!

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 20 Feb 2015, 00:42
by hoppfrosch
Coco wrote:I've tested it w/ 1.1.19.03 32-bit(Unicode and ANSI), 1.1.19.03-28+gc7055e7 32-bit(Unicode) and 2.0-a058-fa7ed04 - works fine on all.
I've tested with all available current variants of Autohotkey (Test/NonTest, AHK1/AHK2) - all with the same results: the callback NP_EXist() is never called ... :?

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 20 Feb 2015, 01:21
by amun
By the demo in German you have to change "notepad" to "editor"

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 21 Feb 2015, 06:41
by Coco
Updated to v1.0.02.00
Added CloseAll/NotExistAll/!ExistAll event. This is mainly geared towards window groups and multiple matching windows. Unlike Close(and its alternative names), with the All suffix, the event will trigger when all matching windows no longer exist. Without the suffix, only the first matching window is required to trigger the event. This behavior is based on WinWaitClose when multiple windows match the WinTitle parameter.

Re: OnWin() - call function on window event (WinWaitXXX asyn

Posted: 21 Feb 2015, 07:28
by Coco
hoppfrosch wrote:I've tested with all available current variants of Autohotkey (Test/NonTest, AHK1/AHK2) - all with the same results: the callback NP_EXist() is never called ...
Please try the updated demo.
amun wrote:By the demo in German you have to change "notepad" to "editor"
I've changed the demo to use Calculator, I' not sure if the window title is the same in German but it should be easier to replace.