[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.rhkb.cn/news/323084.html

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

相关文章

百面算法工程师 | 支持向量机面试相关问题——SVM

本文给大家带来的百面算法工程师是深度学习支持向量机的面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们还将介绍一些常见的深度学习算法工程师面试问题&#xff0c;并提供参考的回答…

python代码无法点击进入,如何破???

python代码无法点击进入&#xff0c;如何破&#xff1f;&#xff1f;&#xff1f; 举个栗子&#xff1a; model.chat是无法进入的&#xff0c;这时可以使用如下的命令进行操作&#xff1a; ?model.chat

Jmeter用jdbc实现对数据库的操作

我们在用Jmeter进行数据库的操作时需要用到配置组件“JDBC Connection Configuration”&#xff0c;通过配置相应的驱动能够让我们通过Jmeter实现对数据库的增删改查&#xff0c;这里我用的mysql数据库一起来看下是怎么实现的吧。 1.驱动包安装 在安装驱动之前我们要先查看当前…

【LAMMPS学习】八、基础知识(5.9)LAMMPS 近场动力学

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各种模拟。 …

这 7 道 Redis 基础问题,很常见!!

后端项目如果用到分布式缓存的话&#xff0c;一般用的都是 Redis。不过&#xff0c;Redis 不仅仅能做缓存&#xff0c;还能用作分布式锁、延时队列、限流等等。 什么是 Redis&#xff1f; Redis[1] &#xff08;REmote DIctionary Server&#xff09;是一个基于 C 语言开发的…

基于Springboot+Vue+Java的校园资料分享平台

&#x1f49e; 文末获取源码联系 &#x1f649; &#x1f447;&#x1f3fb; 精选专栏推荐收藏订阅 &#x1f447;&#x1f3fb; &#x1f380;《Java 精选实战项目-计算机毕业设计题目推荐-期末大作业》&#x1f618; 更多实战项目~ https://www.yuque.com/liuyixin-rotwn/ei3…

springboot3项目练习详细步骤(第一部分:用户业务模块)

目录 环境准备 用户模块 注册 注册接口文档 ​编辑 实现结构 Spring Validation 登录 登录的接口文档 实现登录逻辑 JWT令牌 完善登录认证 拦截器 获取用户详细信息 接口文档 Usercontroller类中编写方法接口 忽略属性返回 优化代码ThreadLocal 更新用户基本信…

点击短信链接唤起Android App实战

一.概述 在很多业务场景中,需要点击短信链接跳转到App的指定页面。在Android系统中,想要实现这个功能,可以通过DeepLink或AppLink实现。二.方案 2.1 DeepLink 2.1.1 方案效果 DeepLink是Android系统最基础、最普遍、最广泛的外部唤起App的方式,不受系统版本限制。当用户…

YOLOv8+PyQt5蔬菜识别检测(26种不同蔬菜类型,yolov8模型,从图像、视频和摄像头三种路径识别检测)

1.基于最新的YOLOv8训练的蔬菜检测模型&#xff0c;和基于PyQt5制作的可视蔬菜检测系统&#xff0c;该系统可自动检测和识别图片或视频当中出现的26种蔬菜&#xff1a;鸡蛋, 姜, 菜椒, 南瓜, 山药, 辣椒, 霉豆, 蘑菇, 香菜, 茼蒿, 油菜, 黄瓜, 角瓜, 莲藕, 西兰花, 菜花, 土豆,…

Linux的基础IO:文件描述符 重定向本质

目录 前言 文件操作的系统调用接口 open函数 close函数 write函数 read函数 注意事项 文件描述符-fd 小补充 重定向 文件描述符的分配原则 系统调用接口-dup2 缓冲区 缓冲区的刷新策略 对于“2”的理解 小补充 前言 在Linux中一切皆文件&#xff0c;打开文件…

libcity笔记:参数设置与参数优先级

1 参数优先级 高优先级的参数会覆盖低优先级的同名参数 Libcity中的优先级顺序维&#xff1a; 命令行参数&#xff08;命令行python run_model.py时导入的&#xff09; > 用户定义配置文件&#xff08;命令行python run_model.py时由config_file导入的&#xff09; >…

Windows下,基于Gradle用Docker发布自己的程序

方案1&#xff1a; windows下打包程序&#xff0c;然后&#xff0c;上传到linux下&#xff0c;生成docker镜像&#xff0c;然后执行。 首先&#xff1a; 由于是采用Gradle管理的项目&#xff0c;打包的时候需要执行build任务。执行完成后&#xff0c;再build\libs目录下应该…

机器学习:基于TF-IDF算法、决策树,使用NLTK库对亚马逊美食评论进行情绪分析

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

js原生手写一个拖拽小功能

先上效果图 附上代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"widthd…

【强训笔记】day16

NO.1 代码实现&#xff1a; class StringFormat { public:string formatString(string A, int n, vector<char> arg, int m) {string ret;int j0;for(int i0;i<n;i){if(A[i]%){if(i1<n&&A[i1]s){retarg[j];i;}else {retA[i];}}else {retA[i];}}while(j&l…

PyQt5中重要的概念:信号与槽

PyQt中信号与槽概念定义如下&#xff08;网络上引用的&#xff09;&#xff1a; 信号&#xff08;signal&#xff09;和槽&#xff08;slot&#xff09;是Qt的核心机制&#xff0c;也是在PyQt编程中对象之间进行通信的机制。在创建事件循环之后&#xff0c;通过建立信号和槽的…

我们的小程序每天早上都白屏,真相是。。。

大家好&#xff0c;我是程序员鱼皮。最近我们在内测一款面试刷题小程序&#xff0c;没错&#xff0c;就是之前倒下的 “面试鸭”&#xff01; 在我们的内测交流群中&#xff0c;每天早上都会有同学反馈&#xff1a;打开小程序空白&#xff0c;没任何内容且登录不上。 然后过了…

Day3 | Java基础 | 4常见类

Day3 | Java基础 | 4 常见类 基础版Object类equalshashCode&#xff08;散列码&#xff09;hashCode和equals clone方法String类 问题回答版Object类Object类的常见方法有哪些&#xff1f;和equals()的区别是什么&#xff1f;为什么要有hashCode&#xff1f;hashCode和equals的…

chrome extension插件替换网络请求中的useragent

感觉Chrome商店中的插件不能很好的实现自己想要的效果,那么就来自己动手吧。 本文以百度为例: 一般来说网页请求如下: 当前使用的useragent是User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safar…

解决WordPress无法强制转换https问题

原因&#xff1a;我在用cs的时候&#xff0c;突然老鸟校园网突然断了&#xff0c;客户端cs连不上了&#xff0c;进程也杀不死&#xff0c;cpu占用100%&#xff0c;只能重启&#xff0c;但是重启后我的blog网站打不开了 开始以为是Nginx的问题&#xff0c;重启它说配置出了问题…