[AHK V2]WinEvent - 简单的检测窗口打开关闭、移动、最大化、最小化等

WinEvent简介

WinEvent 可以监视所有窗口或特定窗口的窗口事件。目前支持以下事件:显示、创建、关闭、激活、非激活、移动、开始移动、结束移动、最小化、还原、最大化。有关详细信息,请参见库中函数的注释。
该库最新版可在Git Hub上获得。
WinEvent.ahk ,以下是2024年5月的版本:

#Requires AutoHotkey v2/*** The WinEvent class can monitor window events for all windows or specific windows.  * Currently the following events are supported: `Show`, `Create`, `Close`, `Active`, `NotActive`, `Move`, * `MoveStart`, `MoveEnd`, `Minimize`, `Restore`, `Maximize`. See comments for the functions for more information.* * All the event initiation methods have the same syntax: * `WinEvent.EventType(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="")`* where Callback is the function that will be called once the event happened, and Count specifies* the maximum amount of callbacks. * The function returns an event hook object that describes the hook (see descriptions down below).* NOTE: if all WinTitle criteria are left empty then any window will match. To match for Last Found*       Window, use WinExist() as WinTitle.* * `Callback(eventObj, hWnd, dwmsEventTime)`*      `eventObj`     : the event hook object describing the hook*      `hWnd`         : the window handle that triggered the event*      `dwmsEventTime`: the `A_TickCount` for when the event happened* * Hook object properties:* `EventHook.EventType`*      The name of the event type (Show, Close, etc)* `EventHook.MatchCriteria`*      The window matching criteria in array format `[WinTitle, WinText, ExcludeTitle, ExcludeText]`* `EventHook.Callback`*      The callback function* `EventHook.Count`*      The current count of how many times the callback may be called* `EventHook.Pause(NewState:=1)*      Pauses or unpauses the hook. 1 = pause, 0 = unpause, -1 = toggle* `EventHook.IsPaused`*      Used to get or set whether the hook is currently active or paused* * Hook object methods:* `EventHook.Stop()`*      Stops the event hook* * WinEvent methods (in addition to the event methods):* `WinEvent.Stop(EventType?, WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")`*      Stops one or all event hooks.* `WinEvent.Pause(NewState:=1)*      Pauses or unpauses all event hooks. 1 = pause, 0 = unpause, -1 = toggle* `WinEvent.IsRegistered(EventType, WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="")*      Checks whether an event with the specified type and criteria is registered.* `WinEvent.IsEventTypeRegistered(EventType)`*      Checks whether any events for a given event type are registered.* * WinEvent properties:* `WinEvent.IsPaused`*      Can be used to get or set the paused state of all events. */
class WinEvent {; A curated list of event enumerationsstatic EVENT_OBJECT_CREATE         := 0x8000,EVENT_OBJECT_DESTROY        := 0x8001,EVENT_OBJECT_SHOW           := 0x8002,EVENT_OBJECT_FOCUS          := 0x8005,EVENT_OBJECT_LOCATIONCHANGE := 0x800B,EVENT_SYSTEM_MINIMIZESTART  := 0x0016,EVENT_SYSTEM_MINIMIZEEND    := 0x0017,EVENT_SYSTEM_MOVESIZESTART  := 0x000A,EVENT_SYSTEM_MOVESIZEEND    := 0x000B,EVENT_SYSTEM_FOREGROUND     := 0x0003,EVENT_OBJECT_NAMECHANGE     := 0x800C/*** When a window is shown* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Show(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") =>this("Show", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is created, but not necessarily shown* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Create(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("Create", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is destroyed/closed* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Close(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("Close", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is activated/focused* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Active(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("Active", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is inactivated/unfocused* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static NotActive(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("NotActive", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is moved or resized* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Move(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("Move", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is starting to be moved or resized* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static MoveStart(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("MoveStart", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window has been moved or resized* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static MoveEnd(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("MoveEnd", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is minimized* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Minimize(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("Minimize", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is restored* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Restore(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("Restore", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** When a window is maximized* @param {(eventObj, hWnd, dwmsEventTime) => Integer} Callback* - `hWnd`         : the window handle that triggered the event* - `dwmsEventTime`: the `A_TickCount` for when the event happened* @param {Number} Count Limits the number of times the callback will be called (eg for a one-time event set `Count` to 1).* @returns {WinEvent} */static Maximize(Callback, WinTitle:="", Count:=-1, WinText:="", ExcludeTitle:="", ExcludeText:="") => this("Maximize", Callback, Count, [WinTitle, WinText, ExcludeTitle, ExcludeText])/*** Stops one or all event hooks* @param EventType The name of the event function (eg Close).* If this isn't specified then all event hooks will be stopped.*/static Stop(EventType?, WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="") {local MatchMap, Hookif !IsSet(EventType) {for EventType, MatchMap in this.__RegisteredEventsfor MatchCriteria, Hook in MatchMapHook.Stop()this.__New()return}if !this.__RegisteredEvents.Has(EventType)returnWinTitle := this.__DeobjectifyWinTitle(WinTitle)for MatchCriteria, EventObj in this.__RegisteredEvents[EventType].Clone()if MatchCriteria[1] = WinTitle && MatchCriteria[2] = WinText && MatchCriteria[3] = ExcludeTitle && MatchCriteria[4] = ExcludeTextEventObj.Stop()}/*** Pauses or unpauses all event hooks. This can also be get/set via the `WinEvent.IsPaused` property. * @param {Integer} NewState 1 = pause, 0 = unpause, -1 = toggle pause state.*/static Pause(NewState := 1) => (this.IsPaused := NewState = -1 ? !this.IsPaused : NewState)/*** Checks whether an event with the specified type and criteria is registered* @param EventType The name of the event function (eg Close)*/static IsRegistered(EventType, WinTitle:="", WinText:="", ExcludeTitle:="", ExcludeText:="") {if !this.__RegisteredEvents.Has(EventType)return 0WinTitle := this.__DeobjectifyWinTitle(WinTitle)for MatchCriteria, EventObj in this.__RegisteredEvents[EventType]if MatchCriteria[1] = WinTitle && MatchCriteria[2] = WinText && MatchCriteria[3] = ExcludeTitle && MatchCriteria[4] = ExcludeTextreturn 1return 0}/*** Checks whether any events for a given event type are registered* @param EventType The name of the event function (eg Close)*/static IsEventTypeRegistered(EventType) => this.__RegisteredEvents.Has(EventType); Stops the event hook, same as if the object was destroyed.Stop() => (this.__Delete(), this.MatchCriteria := "", this.Callback := "")/*** Pauses or unpauses the event hook. This can also be get/set via the `EventHook.IsPaused` property. * @param {Integer} NewState 1 = pause, 0 = unpause, -1 = toggle pause state.*/Pause(NewState := 1) => (this.IsPaused := NewState = -1 ? !this.IsPaused : NewState)class Hook {/*** Sets a new event hook using SetWinEventHook and returns on object describing the hook. * When the object is released, the hook is also released.* @param {(hWinEventHook, event, hwnd, idObject, idChild, idEventThread, dwmsEventTime) => Integer} callbackFunc The function that will be called, which needs to accept 7 arguments.* @param {Integer} [eventMin] Optional: Specifies the event constant for the lowest event value in the range of events that are handled by the hook function.  *  Default is the lowest possible event value.  * - See more about [event constants](https://learn.microsoft.com/en-us/windows/win32/winauto/event-constants)* - [Msaa Events List](Https://Msdn.Microsoft.Com/En-Us/Library/Windows/Desktop/Dd318066(V=Vs.85).Aspx)* - [System-Level And Object-Level Events](Https://Msdn.Microsoft.Com/En-Us/Library/Windows/Desktop/Dd373657(V=Vs.85).Aspx)* - [Console Accessibility](Https://Msdn.Microsoft.Com/En-Us/Library/Ms971319.Aspx)* @param {Integer} [eventMax] Optional: Specifies the event constant for the highest event value in the range of events that are handled by the hook function.*  If eventMin is omitted then the default is the highest possible event value.*  If eventMin is specified then the default is eventMin.* @param {Integer|String} [winTitle=0] Optional: WinTitle of a certain window to hook to. Default is system-wide hook.* @param {Integer} [PID=0] Optional: process ID of the process for which threads to hook to. Default is system-wide hook.* @param {Integer} [flags=0] Flag values that specify the location of the hook function and of the events to be skipped.*  Default is `WINEVENT_OUTOFCONTEXT` = 0. * @returns {WinEventHook} */__New(callbackFunc, eventMin?, eventMax?, winTitle := 0, PID := 0, flags := 0) {if !IsSet(eventMin)eventMin := 0x00000001, eventMax := IsSet(eventMax) ? eventMax : 0x7fffffffelse if !IsSet(eventMax)eventMax := eventMinif !HasMethod(callbackFunc)throw ValueError("The callbackFunc argument must be a function", -1)this.callback := callbackFunc, this.winTitle := winTitle, this.flags := flags, this.eventMin := eventMin, this.eventMax := eventMax, this.threadId := 0if winTitle != 0 {if !(this.winTitle := WinExist(winTitle))throw TargetError("Window not found", -1)this.threadId := DllCall("GetWindowThreadProcessId", "Int", this.winTitle, "UInt*", &PID)}this.pCallback := CallbackCreate(callbackFunc, "C", 7), this.hHook := DllCall("SetWinEventHook", "UInt", eventMin, "UInt", eventMax, "Ptr", 0, "Ptr", this.pCallback, "UInt", this.PID := PID, "UInt", this.threadId, "UInt", flags)}__Delete() {DllCall("UnhookWinEvent", "Ptr", this.hHook), CallbackFree(this.pCallback)}}; ONLY INTERNAL METHODS AHEADstatic __RequiredHooks := Map("Show", [this.EVENT_OBJECT_SHOW], "Create", [this.EVENT_OBJECT_CREATE], "Close", [this.EVENT_OBJECT_CREATE, this.EVENT_OBJECT_NAMECHANGE, this.EVENT_OBJECT_DESTROY], "Active", [this.EVENT_SYSTEM_FOREGROUND], "NotActive", [this.EVENT_SYSTEM_FOREGROUND], "Move", [this.EVENT_OBJECT_LOCATIONCHANGE], "MoveStart", [this.EVENT_SYSTEM_MOVESIZESTART], "MoveEnd", [this.EVENT_SYSTEM_MOVESIZEEND], "Minimize", [this.EVENT_SYSTEM_MINIMIZESTART], "Maximize", [this.EVENT_OBJECT_LOCATIONCHANGE]); Internal variables: keep track of registered events (the match criteria) and registered window hooksstatic __RegisteredEvents := Map(), __Hooks := Map(), IsPaused := 0static __New() {this.Prototype.__WinEvent := thisthis.__RegisteredEvents := Map(), this.__RegisteredEvents.CaseSense := 0this.__Hooks := Map(), this.__Hooks.CaseSense := 0}; Extracts hWnd property from an object-type WinTitlestatic __DeobjectifyWinTitle(WinTitle) => (IsObject(WinTitle) ? WinTitle.hWnd : WinTitle); Activates all necessary window hooks for a given WinEvent typestatic __AddRequiredHooks(EventType) {local _, Hookfor _, Hook in this.__RequiredHooks[EventType]this.__AddHook(Hook)}; Removes (and/or decreases ref count) all necessary window hooks for a given WinEvent typestatic __RemoveRequiredHooks(EventType) {local _, Hookfor _, Hook in this.__RequiredHooks[EventType]this.__RemoveHook(Hook)}; Internal use: activates a new hook if not already active and increases its reference countstatic __AddHook(Hook) {if !this.__Hooks.Has(Hook)this.__Hooks[Hook] := this.Hook(this.__HandleWinEvent.Bind(this), Hook), this.__Hooks[Hook].RefCount := 0this.__Hooks[Hook].RefCount++}; Internal use: decreases a hooks reference count and removes it if it falls to 0static __RemoveHook(Hook) {this.__Hooks[Hook].RefCount--if !this.__Hooks[Hook].RefCountthis.__Hooks.Delete(Hook)}; Internal use: creates a new WinEvent object, which contains info about the registered event; such as the type, callback function, match criteria etc.__New(EventType, Callback, Count, MatchCriteria) {__WinEvent := this.__WinEvent, this.EventType := EventType, this.MatchCriteria := MatchCriteria, this.Callback := Callback, this.Count := Count, this.IsPaused := 0MatchCriteria[1] := __WinEvent.__DeobjectifyWinTitle(MatchCriteria[1])this.MatchCriteria.IsBlank := (MatchCriteria[1] == "" && MatchCriteria[2] == "" && MatchCriteria[3] == "" && MatchCriteria[4] == "")if InStr(MatchCriteria[1], "ahk_id")this.MatchCriteria.ahk_id := (RegExMatch(MatchCriteria[1], "ahk_id\s*([^\s]+)", &match) ? (match[1] ? Integer(match[1]) : 0) : 0)else if IsInteger(MatchCriteria[1])this.MatchCriteria.ahk_id := MatchCriteria[1]elsethis.MatchCriteria.ahk_id := 0if EventType = "Close" {this.__UpdateMatchingWinList()__WinEvent.__UpdateWinList()} else if EventType = "NotActive" {try this.__IsActive := WinActive(MatchCriteria*)catchthis.__IsActive := 0}if !__WinEvent.__RegisteredEvents.Has(EventType)__WinEvent.__RegisteredEvents[EventType] := Map()__WinEvent.__RegisteredEvents[EventType][MatchCriteria] := this__WinEvent.__AddRequiredHooks(EventType)}; Internal use: once a WinEvent object is destroyed, deregister the match criteria and remove ; the hook (if no other WinEvent objects depend on it)__Delete() {if !this.MatchCriteriareturnthis.__WinEvent.__RegisteredEvents[this.EventType].Delete(this.MatchCriteria)this.__WinEvent.__RemoveRequiredHooks(this.EventType)}; Internal use: sets a timer for the callback function (to avoid the thread being Critical; because the HandleWinEvent thread is Critical). Also keeps track of how many times the ; callback has been called.__ActivateCallback(args*) {SetTimer this.Callback.Bind(args*), -1if --this.Count = 0this.Stop()}; Internal use: handles the event called by SetWinEventHook. static __HandleWinEvent(hWinEventHook, event, hwnd, idObject, idChild, idEventThread, dwmsEventTime) {Critical -1static OBJID_WINDOW := 0, INDEXID_CONTAINER := 0, EVENT_OBJECT_CREATE := 0x8000, EVENT_OBJECT_DESTROY := 0x8001, EVENT_OBJECT_SHOW := 0x8002, EVENT_OBJECT_FOCUS := 0x8005, EVENT_OBJECT_LOCATIONCHANGE := 0x800B, EVENT_SYSTEM_MINIMIZESTART := 0x0016, EVENT_SYSTEM_MINIMIZEEND := 0x0017, EVENT_SYSTEM_MOVESIZESTART := 0x000A, EVENT_SYSTEM_MOVESIZEEND := 0x000B, EVENT_SYSTEM_FOREGROUND := 0x0003, EVENT_OBJECT_NAMECHANGE := 0x800C ; These are duplicated here for performance reasonsif this.IsPausedreturnlocal PrevDHW := DetectHiddenWindows(1), HookObj, MatchCriteriaidObject := idObject << 32 >> 32, idChild := idChild << 32 >> 32, event &= 0xFFFFFFFF, idEventThread &= 0xFFFFFFFF, dwmsEventTime &= 0xFFFFFFFF ; convert to INT/UINTif (event = EVENT_OBJECT_DESTROY) {if !this.WinList.Has(hWnd)goto Cleanupfor MatchCriteria, HookObj in this.__RegisteredEvents["Close"] {if !HookObj.IsPaused && HookObj.MatchingWinList.Has(hWnd)HookObj.__ActivateCallback(HookObj, hWnd, dwmsEventTime)HookObj.__UpdateMatchingWinList()}this.__UpdateWinList()goto Cleanup}if (idObject != OBJID_WINDOW || idChild != INDEXID_CONTAINER || !DllCall("IsTopLevelWindow", "ptr", hWnd))goto Cleanupif (event = EVENT_OBJECT_NAMECHANGE || event = EVENT_OBJECT_CREATE) && this.__RegisteredEvents.Has("Close") {for MatchCriteria, HookObj in this.__RegisteredEvents["Close"]HookObj.__UpdateMatchingWinList()if event = EVENT_OBJECT_CREATEthis.__UpdateWinList()}if (event = EVENT_OBJECT_LOCATIONCHANGE && this.__RegisteredEvents.Has("Maximize")) { ; Only handles "Maximize"for MatchCriteria, HookObj in this.__RegisteredEvents["Maximize"] {if !HookObj.IsPaused && (MatchCriteria.IsBlank || (MatchCriteria.ahk_id ? MatchCriteria.ahk_id = hWnd && WinExist(MatchCriteria*) : WinExist(MatchCriteria[1] " ahk_id " hWnd, MatchCriteria[2], MatchCriteria[3], MatchCriteria[4]))) {if WinGetMinMax(hWnd) != 1continueHookObj.__ActivateCallback(HookObj, hWnd, dwmsEventTime)}}} if ((event = EVENT_OBJECT_LOCATIONCHANGE && EventName := "Move")|| (event = EVENT_OBJECT_CREATE && EventName := "Create") || (event = EVENT_OBJECT_SHOW && EventName := "Show")|| (event = EVENT_SYSTEM_MOVESIZESTART && EventName := "MoveStart")|| (event = EVENT_SYSTEM_MOVESIZEEND && EventName := "MoveEnd")|| (event = EVENT_SYSTEM_MINIMIZESTART && EventName := "Minimize")|| (event = EVENT_SYSTEM_MINIMIZEEND && EventName := "Restore")|| (event = EVENT_SYSTEM_FOREGROUND && EventName := "Active")) && this.__RegisteredEvents.Has(EventName) {for MatchCriteria, HookObj in this.__RegisteredEvents[EventName] {if !HookObj.IsPaused && (MatchCriteria.IsBlank || (MatchCriteria.ahk_id ? MatchCriteria.ahk_id = hWnd && WinExist(MatchCriteria*) : WinExist(MatchCriteria[1] " ahk_id " hWnd, MatchCriteria[2], MatchCriteria[3], MatchCriteria[4])))HookObj.__ActivateCallback(HookObj, hWnd, dwmsEventTime)}} if (event = EVENT_SYSTEM_FOREGROUND && this.__RegisteredEvents.Has("NotActive")) {for MatchCriteria, HookObj in this.__RegisteredEvents["NotActive"] {try hWndActive := WinActive(MatchCriteria*)catchhWndActive := 0try if !HookObj.IsPaused && HookObj.__IsActive && !hWndActive {HookObj.__ActivateCallback(HookObj, HookObj.__IsActive, dwmsEventTime)HookObj.__IsActive := 0}if hWndActive = hWndHookObj.__IsActive := hWnd}}Cleanup:DetectHiddenWindows PrevDHWSleep(-1) ; Check the message queue immediately}; Internal use: keeps track of all open windows to only handle top-level windowsstatic __UpdateWinList() {local WinList := WinGetList(),  WinListMap := Map(), hWndfor hWnd in WinListWinListMap[hWnd] := 1this.WinList := WinListMap}; Internal use: keeps track of open windows that match the criteria, because matching for name; class etc wouldn't work after the window is already destroyed. __UpdateMatchingWinList() {if !this.MatchCriteriareturnlocal MatchingWinList := WinGetList(this.MatchCriteria*), MatchingWinListMap := Map(), hWndfor hWnd in MatchingWinListMatchingWinListMap[hWnd] := 1this.MatchingWinList := MatchingWinListMap}
}

举几个例子

第一个例子 监测WinEvent.Show事件

监测Notepad窗口被创建事件,以Notepad记事本为例,当探测到Notepad窗口创建时,显示一个ToolTip提示。
说明,需要将本脚本与WinEvent.ahk放到同一个目录里进行测试。

#Requires AutoHotkey v2
#include WinEvent.ahk;检测何时创建了Notepad窗口. 按 F1 启动Notepad 来测试.
WinEvent.Show(NotepadCreated, "ahk_class Notepad ahk_exe notepad.exe")
; WinEvent.Show(NotepadCreated, "ahk_exe notepad.exe",1)  ;仅仅监控1次。
Persistent()NotepadCreated(hook, hWnd, dwmsEventTime) {ToolTip "Notepad 窗口创建于" dwmsEventTime ", 句柄为" hWnd "`n"SetTimer ToolTip, -3000
}F1::Run("notepad.exe")

第二个例子 监测WinEvent.Close事件

监测Notepad窗口关闭事件。请注意,如果使用"A"替换掉WinExist("A")将检测到任何活动窗口的关闭,而不是Notepad窗口。
第3个参数1表示一旦回调函数被调用一次,钩子就会停止。

#Requires AutoHotkey v2
#include WinEvent.ahkRun "notepad.exe"
WinWaitActive "ahk_exe notepad.exe"
; Notepad窗口关闭时,会回调ActiveWindowClosed。
WinEvent.Close(ActiveWindowClosed, WinExist("A"), 1)
Persistent()ActiveWindowClosed(*) {MsgBox "Notepad 窗口关闭了,点击 确定 按钮 退出"ExitApp
}

第三个例子 监测WinEvent.Maximize事件

监测窗口最大化事件,这里没指定特定窗口标识,将监视所有窗口的最大化。

#Requires AutoHotkey v2
#include WinEvent.ahk; 监测所有窗口的最大化事件
WinEvent.Maximize(WindowMaximizedEvent)
Persistent()WindowMaximizedEvent(hook, hWnd, dwmsEventTime) {if MsgBox("一个窗口最大化于 " dwmsEventTime ", 句柄" hWnd "`n`n停止监控?",, 0x4) = "Yes"hook.Stop()
}F1::Run("notepad.exe")

第四个例子 监测WinEvent.Active事件

测WinEvent.Active事件,实现当窗口激活时显示激活窗口的一些信息。

#Requires AutoHotkey v2
#include WinEvent.ahkWinEvent.Active(ActiveWindowChanged)
Persistent()ActiveWindowChanged(hook, hWnd, *) {ToolTip "激活窗口变了! 新窗口信息为: `n" WinGetInfo(hWnd)SetTimer ToolTip, -5000
}/*** Gets info about a window (title, process name, location etc)* @param WinTitle Same as AHK WinTitle* @param {number} Verbose How verbose the output should be (default is 1):*  0: Returns window title, hWnd, class, process name, PID, process path, screen position, min-max info, styles and ex-styles*  1: Additionally returns TransColor, transparency level, text (both hidden and not), statusbar text*  2: Additionally returns ClassNN names for all controls* @param WinText Same as AHK WinText* @param ExcludeTitle Same as AHK ExcludeTitle* @param ExcludeText Same as AHK ExcludeText* @param {string} Separator Linebreak character(s)* @returns {string} The info as a string. * @example MsgBox(WinGetInfo("ahk_exe notepad.exe", 2))*/
WinGetInfo(WinTitle:="", Verbose := 1, WinText:="", ExcludeTitle:="", ExcludeText:="", Separator := "`n") {if !(hWnd := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText))throw TargetError("Target window not found!", -1)out := 'Title: 'try out .= '"' WinGetTitle(hWnd) '"' Separatorcatchout .= "#ERROR" Separatorout .=  'ahk_id ' hWnd Separatorout .= 'ahk_class 'try out .= WinGetClass(hWnd) Separatorcatchout .= "#ERROR" Separatorout .= 'ahk_exe 'try out .= WinGetProcessName(hWnd) Separatorcatchout .= "#ERROR" Separatorout .= 'ahk_pid 'try out .= WinGetPID(hWnd) Separatorcatchout .= "#ERROR" Separatorout .= 'ProcessPath: 'try out .= '"' WinGetProcessPath(hWnd) '"' Separatorcatchout .= "#ERROR" Separatorout .= 'Screen position: 'try { WinGetPos(&X, &Y, &W, &H, hWnd)out .= "x: " X " y: " Y " w: " W " h: " H Separator} catchout .= "#ERROR" Separatorout .= 'MinMax: 'try out .= ((minmax := WinGetMinMax(hWnd)) = 1 ? "maximized" : minmax = -1 ? "minimized" : "normal") Separatorcatchout .= "#ERROR" Separatorstatic Styles := Map("WS_OVERLAPPED", 0x00000000, "WS_POPUP", 0x80000000, "WS_CHILD", 0x40000000, "WS_MINIMIZE", 0x20000000, "WS_VISIBLE", 0x10000000, "WS_DISABLED", 0x08000000, "WS_CLIPSIBLINGS", 0x04000000, "WS_CLIPCHILDREN", 0x02000000, "WS_MAXIMIZE", 0x01000000, "WS_CAPTION", 0x00C00000, "WS_BORDER", 0x00800000, "WS_DLGFRAME", 0x00400000, "WS_VSCROLL", 0x00200000, "WS_HSCROLL", 0x00100000, "WS_SYSMENU", 0x00080000, "WS_THICKFRAME", 0x00040000, "WS_GROUP", 0x00020000, "WS_TABSTOP", 0x00010000, "WS_MINIMIZEBOX", 0x00020000, "WS_MAXIMIZEBOX", 0x00010000, "WS_TILED", 0x00000000, "WS_ICONIC", 0x20000000, "WS_SIZEBOX", 0x00040000, "WS_OVERLAPPEDWINDOW", 0x00CF0000, "WS_POPUPWINDOW", 0x80880000, "WS_CHILDWINDOW", 0x40000000, "WS_TILEDWINDOW", 0x00CF0000, "WS_ACTIVECAPTION", 0x00000001, "WS_GT", 0x00030000), ExStyles := Map("WS_EX_DLGMODALFRAME", 0x00000001, "WS_EX_NOPARENTNOTIFY", 0x00000004, "WS_EX_TOPMOST", 0x00000008, "WS_EX_ACCEPTFILES", 0x00000010, "WS_EX_TRANSPARENT", 0x00000020, "WS_EX_MDICHILD", 0x00000040, "WS_EX_TOOLWINDOW", 0x00000080, "WS_EX_WINDOWEDGE", 0x00000100, "WS_EX_CLIENTEDGE", 0x00000200, "WS_EX_CONTEXTHELP", 0x00000400, "WS_EX_RIGHT", 0x00001000, "WS_EX_LEFT", 0x00000000, "WS_EX_RTLREADING", 0x00002000, "WS_EX_LTRREADING", 0x00000000, "WS_EX_LEFTSCROLLBAR", 0x00004000, "WS_EX_CONTROLPARENT", 0x00010000, "WS_EX_STATICEDGE", 0x00020000, "WS_EX_APPWINDOW", 0x00040000, "WS_EX_OVERLAPPEDWINDOW", 0x00000300, "WS_EX_PALETTEWINDOW", 0x00000188, "WS_EX_LAYERED", 0x00080000, "WS_EX_NOINHERITLAYOUT", 0x00100000, "WS_EX_NOREDIRECTIONBITMAP", 0x00200000, "WS_EX_LAYOUTRTL", 0x00400000, "WS_EX_COMPOSITED", 0x02000000, "WS_EX_NOACTIVATE", 0x08000000)out .= 'Style: 'try {out .= (style := WinGetStyle(hWnd)) " ("for k, v in Styles {if v && style & v {out .= k " | "style &= ~v}}out := RTrim(out, " |")if styleout .= (SubStr(out, -1, 1) = "(" ? "" : ", ") "Unknown enum: " styleout .= ")" Separator} catchout .= "#ERROR" Separatorout .= 'ExStyle: 'try {out .= (style := WinGetExStyle(hWnd)) " ("for k, v in ExStyles {if v && style & v {out .= k " | "style &= ~v}}out := RTrim(out, " |")if styleout .= (SubStr(out, -1, 1) = "(" ? "" : ", ") "Unknown enum: " styleout .= ")" Separator} catchout .= "#ERROR" Separatorif Verbose {out .= 'TransColor: 'try out .= WinGetTransColor(hWnd) Separatorcatchout .= "#ERROR" Separatorout .= 'Transparent: 'try out .= WinGetTransparent(hWnd) Separatorcatchout .= "#ERROR" SeparatorPrevDHW := DetectHiddenText(0)out .= 'Text (DetectHiddenText Off): 'try out .= '"' WinGetText(hWnd) '"' Separatorcatchout .= "#ERROR" SeparatorDetectHiddenText(1)out .= 'Text (DetectHiddenText On): 'try out .= '"' WinGetText(hWnd) '"' Separatorcatchout .= "#ERROR" SeparatorDetectHiddenText(PrevDHW)out .= 'StatusBar Text: 'try out .= '"' StatusBarGetText(1, hWnd) '"' Separatorcatchout .= "#ERROR" Separator}if Verbose > 1 {out .= 'Controls (ClassNN): ' Separatortry {for ctrl in WinGetControls(hWnd)out .= '`t' ctrl Separator} catchout .= "#ERROR" Separator}return SubStr(out, 1, -StrLen(Separator))
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/6994.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VsCode插件 -- Power Mode

一、安装插件 1. 首先在扩展市场里搜索 Power Mode 插件&#xff0c;如下图 二、配置插件 设置 点击小齿轮 打上勾 就可以了 第二种设置方法 1. 安装完成之后&#xff0c;使用快捷键 Ctrl Shift P 打开命令面板&#xff0c;在命令行中输入 settings.json &#xff0c; 选择首…

通过maven命令行mvn的方式,下载依赖jar包

目录 目标步骤执行mvn命令 目标 有时通过idea-maven-reload all maven projects更新项目依赖时&#xff0c;会报错Could not find artifact xxx.xx:xxx.x:xxx.jar (https://repo1.maven.org/maven2/org/)。 此时可尝试通过mvn命令行进行依赖下载&#xff08;需要配置maven本地…

【Python深度学习(第二版)(2)】深度学习之前:机器学习简史

文章目录 一. 深度学习的起源1. 概率建模--机器学习分类器2. 早期神经网络--反向传播算法的转折3. 核方法 -- 忽略神经网络4. 决策树、随机森林和梯度提升机5. 神经网络替代svm与决策树 二. 深度学习与机器学习有何不同 可以这样说&#xff0c;当前工业界所使用的大部分机器学习…

asp.net朱勇项目个人博客(3)

引文:按照书上的项目&#xff0c;我们最后实现管理端的三个增删改查的功能即可,相对与三个增删改查&#xff0c;文章&#xff0c;分类和留言&#xff0c;这里我们所需要用的的关联的一个表就是文章表&#xff0c;因为文章表每一个文章的增加显示和修改都需要对应的一个分类&…

【Linux】网络连接配置——nmcli工具配置连接增删改查实例

nmcli工具配置连接增删改查实例 &#xff08;一&#xff09;网络连接配置基本项目1.网络接口配置2.主机名配置3.DNS服务器配置 &#xff08;二&#xff09;网络连接配置文件&#xff08;三&#xff09;网络配置方法&#xff08;四&#xff09;nmcli工具配置连接管理1.增2.查3.改…

sql编写规范(word原件)

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目的 2 SQL书写规范 3 SQL编写原则 软件全套资料获取进主页或者本文末个人名片直接获取。

GStreamer日志调试笔记

1、查询所有分类 #gst-launch-1.0 --gst-debug-help 2、查询videotestsrc的日志 #gst-launch-1.0 --gst-debug-help | findstr videotestsrc 结果&#xff1a; 3、使用--gst-debug设置相应日志类型的相应等级&#xff0c;越大显示日志越多&#xff0c;排查内存泄露可以设置为9 …

国内外主流大模型都具备有哪些特点?

文章目录 ⭐ 火爆全网的大模型起点⭐ 国外主流LLM及其特点⭐ 国内主流LLM及其特点⭐ 全球大模型生态的发展 该章节呢&#xff0c;我们主要是看一下关于国内外主流的大语言模型&#xff0c;通过它们都具备哪些特点&#xff0c;来达成对多模型有一个清晰的认知。对于 “多模型” …

帮助命令

1.man 原意&#xff1a;manual 所在路径&#xff1a;/usr/bin/man 执行权限&#xff1a;所有用户 语法&#xff1a;man [命令或配置文件] 功能描述&#xff1a;获得帮助信息 例&#xff1a;$ man ls 查看ls命令的帮助信息 查看命令的帮助主要是看这个命令是干什么用的&am…

Vue3+.NET6前后端分离式管理后台实战(十七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(十七)已经在微信公众号更新&#xff0c;有兴趣的扫码关注一起交流学习。

数据治理:数据孤岛是企业信息化发展中难以避免的阶段

随着信息技术的飞速发展&#xff0c;企业对于数据的依赖程度日益加深。在这个过程中&#xff0c;数据治理成为了企业信息化建设的核心环节。然而&#xff0c;在实际操作中&#xff0c;企业往往会遇到一种难以避免的现象——数据孤岛。 一、数据孤岛的定义与成因 数据孤岛&…

电磁兼容(EMC):产品适用静电放电(ESD)标准全解

目录 1. 标准体系 2. 试验方法标准 3. 常见产品的抗扰度标准 自己研发的产品到底需要满足什么样的静电放电标准要求才是满足国家标准要求。客户提出的静电放电接触放电4kV&#xff0c;空气放电8kV要求&#xff0c;是高于国家标准要求还是低于国家标准要求&#xff1f;面对这…

PyCharm 2024新版图文安装教程(python环境搭建+PyCharm安装+运行测试+汉化+背景图设置)

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。—— 苏轼《水调歌头》 创作者&#xff1a;Code_流苏(CSDN) 目录 一、Python环境搭建二、PyCharm下载及安装三、解释器配置及项目测试四、PyCharm汉化五、背景图设置 很高兴你打开了这篇博客&#xff0c;如有疑问&#x…

类的流插入与流提取

1.自定义类型不能直接使用流插入与流提取 为什么内置类型可以直接使用流插入与流提取&#xff1f; 其实本质上是人家已经写好了相关的函数&#xff0c;内置类型可以直接调用cout与cin 对于自定义类型&#xff0c;我们需要自己写相关的函数。 2.解决方法 2.1自己在类里面写一个…

Microsoft Remote Desktop Beta for Mac:远程办公桌面连接工具

Microsoft Remote Desktop Beta for Mac不仅是一款远程桌面连接工具&#xff0c;更是开启远程办公新篇章的利器。 它让Mac用户能够轻松访问和操作远程Windows计算机&#xff0c;实现跨平台办公的无缝衔接。无论是在家中、咖啡店还是旅途中&#xff0c;只要有网络连接&#xff0…

鸿蒙UI复用

鸿蒙UI复用 简介BuilderBuilder的使用方式一Builder的使用方式二Builder的使用方式三 Component使用Component复用UI 简介 在页面开发过程中&#xff0c;会遇到有UI相似的结构&#xff0c;如果每个UI都单独声明一份&#xff0c;会产生大量冗余代码&#xff0c;不利于阅读。遇到…

Python头歌合集(题集附解)

目录 一、Python初识-基本语法 第1关&#xff1a;Hello Python! 第2关&#xff1a;我想看世界 第3关&#xff1a;学好Python 第4关&#xff1a;根据圆的半径计算周长和面积 第5关&#xff1a;货币转换 二、turtle简单绘图 第1关&#xff1a;英寸与厘米转换 第2关&#xff1…

vue-cli+vue3+vite+ts 搭建uniapp项目全过程(一)

unapp官方提供了cli 脚手架创建 uni-app 项目的文档 Vue3/Vite版要求 node 版本 18、20使用Vue3/Vite版创建不会提示选择模板&#xff0c;目前只支持创建默认模板 本文以vue3vitets为例 1、初始化项目 npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project 执行完生成…

037——加入Kconfig机制

目录 一、什么是Kconfig 1.1 由来 1.2 功能 二、 Kconfig的基本语法 2.1 Kconfig 构建项目解析 2.2 怎么调用子makefile做menuconfig 方法一&#xff1a;使用make命令直接调用子目录 方法二&#xff1a;使用变量来指定子目录 方法三&#xff1a;使用include指令包含子…

Java openrasp记录-02

主要分析以下四个部分&#xff1a; 1.openrasp agent 这里主要进行插桩的定义&#xff0c;其pom.xml中定义了能够当类重新load时重定义以及重新转换 这里定义了两种插桩方式对应之前安装时的独立web的jar的attach或者修改启动脚本添加rasp的jar的方式 其中init操作则需要将ras…