[Class] WinHook

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
FanaticGuru
Posts: 1946
Joined: 30 Sep 2013, 22:25

[Class] WinHook

19 Nov 2018, 20:39

This is a class to make working with Window Shell Hooks and Window Event Hooks easier.

These type hooks can be set manually with DllCall("RegisterShellHookWindow"...) and DllCall("SetWinEventHook"...) but it is rather complicated.

[Class] WinHook

Code: Select all

; [Class] WinHook
; Fanatic Guru
; 2019 02 18 v2
;
; Class to set hooks of windows or processes
;
;{============================	
;
;	Class (Nested):		WinHook.Shell
;
;		Method:
; 			Add(Func, wTitle:="", wClass:="", wExe:="", Event:=0)
;
;		Desc: Add Shell Hook
;
;   	Parameters:
;		1) {Func}		Function name or Function object to call on event
;   	2) {wTitle}	window Title to watch for event (default = "", all windows)
;   	3) {wClass}	window Class to watch for event (default = "", all windows)
;   	4) {wExe}		window Exe to watch for event (default = "", all windows)
;   	5) {Event}		Event (default = 0, all events)
;
;		Returns: {Index}	index to hook that can be used to Remove hook
;
;				Shell Hook Events:
;				1 = HSHELL_WINDOWCREATED
;				2 = HSHELL_WINDOWDESTROYED
;				3 = HSHELL_ACTIVATESHELLWINDOW
;				4 = HSHELL_WINDOWACTIVATED
;				5 = HSHELL_GETMINRECT
;				6 = HSHELL_REDRAW
;				7 = HSHELL_TASKMAN
;				8 = HSHELL_LANGUAGE
;				9 = HSHELL_SYSMENU
;				10 = HSHELL_ENDTASK
;				11 = HSHELL_ACCESSIBILITYSTATE
;				12 = HSHELL_APPCOMMAND
;				13 = HSHELL_WINDOWREPLACED
;				14 = HSHELL_WINDOWREPLACING
;				32768 = 0x8000 = HSHELL_HIGHBIT
;				32772 = 0x8000 + 4 = 0x8004 = HSHELL_RUDEAPPACTIVATED (HSHELL_HIGHBIT + HSHELL_WINDOWACTIVATED)
;				32774 = 0x8000 + 6 = 0x8006 = HSHELL_FLASH (HSHELL_HIGHBIT + HSHELL_REDRAW)
;
;		Note: ObjBindMethod(obj, Method) can be used to create a function object to a class method
;					WinHook.Shell.Add(ObjBindMethod(TestClass.TestNestedClass, "MethodName"), wTitle, wClass, wExe, Event)
;
; ----------
;
;		Desc: Function Called on Event
;			FuncOrMethod(Win_Hwnd, Win_Title, Win_Class, Win_Exe, Win_Event)
;		
;		Parameters:
;		1) {Win_Hwnd}		window handle ID of window with event 
;   	2) {Win_Title}		window Title of window with event
;   	3) {Win_Class}		window Class of window with event
;   	4) {Win_Exe}			window Exe of window with event
;   	5) {Win_Event}		window Event
;
;		Note: FuncOrMethod will be called with DetectHiddenWindows On.
;
; --------------------
;
;		Method: 	Report(ByRef Object)
;
;		Desc: 		Report Shell Hooks
;
;		Returns:	string report
;						ByRef	Object[Index].{Func, Title:, Class, Exe, Event}
;
; --------------------
;
;		Method:		Remove(Index)
;		Method:		Deregister()
;
;{============================	
;
;	Class (Nested):		WinHook.Event
;
;		Method:
;			Add(eventMin, eventMax, eventProc, idProcess, WinTitle := "") 			
;
;		Desc: Add Event Hook
;
;   	Parameters:
;		1) {eventMin}		lowest Event value handled by the hook function
;   	2) {eventMax}		highest event value handled by the hook function
;   	3) {eventProc}		event hook function, call be function name or function object
;   	4) {idProcess}		ID of the process from which the hook function receives events (default = 0, all processes)
;   	5) {WinTitle}			WinTitle to identify which windows to operate on, (default = "", all windows)
;
;		Returns: {hWinEventHook}	handle to hook that can be used to unhook
;
;				Event Hook Events:
;				0x8012 = EVENT_OBJECT_ACCELERATORCHANGE
;				0x8017 = EVENT_OBJECT_CLOAKED
;				0x8015 = EVENT_OBJECT_CONTENTSCROLLED
;				0x8000 = EVENT_OBJECT_CREATE
;				0x8011 = EVENT_OBJECT_DEFACTIONCHANGE
;				0x800D = EVENT_OBJECT_DESCRIPTIONCHANGE
;				0x8001 = EVENT_OBJECT_DESTROY
;				0x8021 = EVENT_OBJECT_DRAGSTART
;				0x8022 = EVENT_OBJECT_DRAGCANCEL
;				0x8023 = EVENT_OBJECT_DRAGCOMPLETE
;				0x8024 = EVENT_OBJECT_DRAGENTER
;				0x8025 = EVENT_OBJECT_DRAGLEAVE
;				0x8026 = EVENT_OBJECT_DRAGDROPPED
;				0x80FF = EVENT_OBJECT_END
;				0x8005 = EVENT_OBJECT_FOCUS
;				0x8010  = EVENT_OBJECT_HELPCHANGE
;				0x8003 = EVENT_OBJECT_HIDE
;				0x8020 = EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED
;				0x8028 = EVENT_OBJECT_IME_HIDE
;				0x8027 = EVENT_OBJECT_IME_SHOW
;				0x8029 = EVENT_OBJECT_IME_CHANGE
;				0x8013 = EVENT_OBJECT_INVOKED
;				0x8019 = EVENT_OBJECT_LIVEREGIONCHANGED
;				0x800B = EVENT_OBJECT_LOCATIONCHANGE
;				0x800C = EVENT_OBJECT_NAMECHANGE
;				0x800F = EVENT_OBJECT_PARENTCHANGE
;				0x8004 = EVENT_OBJECT_REORDER
;				0x8006 = EVENT_OBJECT_SELECTION
;				0x8007 = EVENT_OBJECT_SELECTIONADD
;				0x8008 = EVENT_OBJECT_SELECTIONREMOVE
;				0x8009 = EVENT_OBJECT_SELECTIONWITHIN
;				0x8002 = EVENT_OBJECT_SHOW
;				0x800A = EVENT_OBJECT_STATECHANGE
;				0x8030 = EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED
;				0x8014 = EVENT_OBJECT_TEXTSELECTIONCHANGED
;				0x8018 = EVENT_OBJECT_UNCLOAKED
;				0x800E = EVENT_OBJECT_VALUECHANGE
;				0x0002 = EVENT_SYSTEM_ALERT
;				0x8016 = EVENT_SYSTEM_ARRANGMENTPREVIEW
;				0x0009 = EVENT_SYSTEM_CAPTUREEND
;				0x0008 = EVENT_SYSTEM_CAPTURESTART
;				0x000D = EVENT_SYSTEM_CONTEXTHELPEND
;				0x000C = EVENT_SYSTEM_CONTEXTHELPSTART
;				0x0020 = EVENT_SYSTEM_DESKTOPSWITCH
;				0x0011 = EVENT_SYSTEM_DIALOGEND
;				0x0010 = EVENT_SYSTEM_DIALOGSTART
;				0x000F = EVENT_SYSTEM_DRAGDROPEND
;				0x000E = EVENT_SYSTEM_DRAGDROPSTART
;				0x00FF = EVENT_SYSTEM_END
;				0x0003 = EVENT_SYSTEM_FOREGROUND
;				0x0007 = EVENT_SYSTEM_MENUPOPUPEND
;				0x0006 = EVENT_SYSTEM_MENUPOPUPSTART
;				0x0005 = EVENT_SYSTEM_MENUEND
;				0x0004 = EVENT_SYSTEM_MENUSTART
;				0x0017 = EVENT_SYSTEM_MINIMIZEEND
;				0x0016 = EVENT_SYSTEM_MINIMIZESTART
;				0x000B = EVENT_SYSTEM_MOVESIZEEND
;				0x000A = EVENT_SYSTEM_MOVESIZESTART
;				0x0013 = EVENT_SYSTEM_SCROLLINGEND
;				0x0012 = EVENT_SYSTEM_SCROLLINGSTART
;				0x0001 = EVENT_SYSTEM_SOUND
;				0x0015 = EVENT_SYSTEM_SWITCHEND
;				0x0014 = EVENT_SYSTEM_SWITCHSTART

;
;		Note: ObjBindMethod(obj, Method) can be used to create a function object to a class method
;					WinHook.Event.Add((eventMin, eventMax, ObjBindMethod(TestClass.TestNestedClass, "MethodName"), idProcess, WinTitle := "")
;
; ----------
;
;		Desc: Function Called on Event
;			FuncOrMethod(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
;		
;		Parameters:
;		1) {hWinEventHook}		Handle to an event hook instance.
;   	2) {event}						Event that occurred. This value is one of the event constants
;   	3) {hwnd}						Handle to the window that generates the event.
;   	4) {idObject}					Identifies the object that is associated with the event.
;   	5) {idChild}					Child ID if the event was triggered by a child element.
;   	6) {dwEventThread}		Identifies the thread that generated the event.
;   	7) {dwmsEventTime}	Specifies the time, in milliseconds, that the event was generated.
;
;		Note: FuncOrMethod will be called with DetectHiddenWindows On.
;
; --------------------
;
;		Method:	Report(ByRef Object)
;
;		Returns:	string report
;						ByRef	Object[hWinEventHook].{eventMin, eventMax, eventProc, idProcess, WinTitle}
;
; --------------------
;
;		Method: 	UnHook(hWinEventHook)
;		Method: 	UnHookAll()
;
;{============================	
class WinHook
{
	class Shell
	{
		Add(Func, wTitle:="", wClass:="", wExe:="", Event:=0)
		{
			if !WinHook.Shell.Hooks
			{
				WinHook.Shell.Hooks := {}, WinHook.Shell.Events := {}
				DllCall("RegisterShellHookWindow", UInt, A_ScriptHwnd)
				MsgNum := DllCall("RegisterWindowMessage", Str, "SHELLHOOK")
				OnMessage(MsgNum, ObjBindMethod(WinHook.Shell, "Message"))
			}
			if !IsObject(Func)
				Func := Func(Func)
			WinHook.Shell.Hooks.Push({Func: Func, Title: wTitle, Class: wClass, Exe: wExe, Event: Event})
			WinHook.Shell.Events[Event] := true
			return WinHook.Shell.Hooks.MaxIndex()
		}
		Remove(Index)
		{
			WinHook.Shell.Hooks.Delete(Index)
			WinHook.Shell.Events[Event] := {}	; delete and rebuild Event list
			For key, Hook in WinHook.Shell.Hooks
				WinHook.Shell.Events[Hook.Event] := true
		}
		Report(ByRef Obj:="")
		{
			Obj := WinHook.Shell.Hooks
			For key, Hook in WinHook.Shell.Hooks
				Display .= key "|" Hook.Event "|" Hook.Func.Name "|" Hook.Title "|" Hook.Class "|" Hook.Exe "`n"
			return Trim(Display, "`n")
		}
		Deregister()
		{
			DllCall("DeregisterShellHookWindow", UInt, A_ScriptHwnd)
			WinHook.Shell.Hooks := "", WinHook.Shell.Events := ""		
		}
		Message(Event, Hwnd)  ; Private Method
		{
			DetectHiddenWindows, On
			If (WinHook.Shell.Events[Event] or WinHook.Shell.Events[0]) 
			{
				
				WinGetTitle, wTitle, ahk_id %Hwnd%
				WinGetClass, wClass, ahk_id %Hwnd%
				WinGet, wExe, ProcessName, ahk_id %Hwnd%
				for key, Hook in WinHook.Shell.Hooks
					if ((Hook.Title = wTitle or Hook.Title = "") and (Hook.Class = wClass or Hook.Class = "") and (Hook.Exe = wExe or Hook.Exe = "") and (Hook.Event = Event or Hook.Event = 0))
						return Hook.Func.Call(Hwnd, wTitle, wClass, wExe, Event)
			}
		}
	}
	class Event
	{
		Add(eventMin, eventMax, eventProc, idProcess := 0, WinTitle := "")
		{
			if !WinHook.Event.Hooks
			{
				WinHook.Event.Hooks := {}
				static CB_WinEventProc := RegisterCallback(WinHook.Event.Message)
				OnExit(ObjBindMethod(WinHook.Event, "UnHookAll"))
			}
			hWinEventHook := DllCall("SetWinEventHook"
				, "UInt",	eventMin						;  UINT eventMin
				, "UInt",	eventMax						;  UINT eventMax
				, "Ptr" ,	0x0								;  HMODULE hmodWinEventProc
				, "Ptr" ,	CB_WinEventProc					;  WINEVENTPROC lpfnWinEventProc
				, "UInt" ,	idProcess						;  DWORD idProcess
				, "UInt",	0x0								;  DWORD idThread
				, "UInt",	0x0|0x2)  						;  UINT dwflags, OutOfContext|SkipOwnProcess
			if !IsObject(eventProc)
				eventProc := Func(eventProc)
			WinHook.Event.Hooks[hWinEventHook] := {eventMin: eventMin, eventMax: eventMax, eventProc: eventProc, idProcess: idProcess, WinTitle: WinTitle}
			return hWinEventHook
		}
		Report(ByRef Obj:="")
		{
			Obj := WinHook.Event.Hooks
			For hWinEventHook, Hook in WinHook.Event.Hooks
				Display .= hWinEventHook "|" Hook.eventMin "|" Hook.eventMax "|" Hook.eventProc.Name "|" Hook.idProcess "|" Hook.WinTitle "`n"
			return Trim(Display, "`n")
		}
		UnHook(hWinEventHook)
		{
				DllCall("UnhookWinEvent", "Ptr", hWinEventHook)
				WinHook.Event.Hooks.Delete(hWinEventHook)
		}
		UnHookAll()
		{
			for hWinEventHook, Hook in WinHook.Event.Hooks
				DllCall("UnhookWinEvent", "Ptr", hWinEventHook)
			WinHook.Event.Hooks := "", CB_WinEventProc := ""
		}
		Message(event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)  ; 'Private Method 
		{
			DetectHiddenWindows, On
			Hook := WinHook.Event.Hooks[hWinEventHook := this] ; this' is hidden param1 because method is called as func
			WinGet, List, List, % Hook.WinTitle
			Loop % List
				if  (List%A_Index% = hwnd)
					return Hook.eventProc.Call(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
		}
	}
}

A fairly simple example that detects when a Notepad window is Created, Destroyed, Minimized, or Restored.

Code: Select all

WinHook.Shell.Add("Created",,, "NOTEPAD.EXE",1) ; Notepad Window Created
WinHook.Shell.Add("Destroyed",,, "NOTEPAD.EXE",2) ; Notepad Window Destroyed

Esc::ExitApp

Destroyed(Win_Hwnd, Win_Title, Win_Class, Win_Exe, Win_Event)
{
	MsgBox Destroyed
}

Created(Win_Hwnd, Win_Title, Win_Class, Win_Exe, Win_Event)
{
	MsgBox Created
	WinGet, PID, PID, ahk_id %Win_Hwnd%
	EH1 := WinHook.Event.Add(0x0016, 0x0016, "Minimized", PID) 
	EH2 := WinHook.Event.Add(0x0017, 0x0017, "Restored", PID) 
}

Minimized(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
	MsgBox Minimized
}

Restored(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
	MsgBox Restored
}
A Shell look can detect the Created and Destroyed but an Event hook is need then to detect the Minimized and Restored. Those Event hooks are setup when the Created Shell hook is triggered.

This shows how to keep all the called functions in a class as subclasses and methods to keep everything acting on one type of window in one place.

Code: Select all

WinHook.Shell.Add(ObjBindMethod(Excel.Shell, "Button"),,, "EXCEL.EXE",1) ; Excel Window Created

Esc::ExitApp

;{ Excel Call Functions
class Excel
{
	class Shell
	{
		Button(Win_Hwnd, Win_Title, Win_Class, Win_Exe, Win_Event) ; Create Button
		{
			static Button
			; ----- Create WinHook.Event to handle button location with Resize method
			WinGet, PID, PID, ahk_id %Win_Hwnd%
			WinHook.Event.Add(0x800B, 0x800B, ObjBindMethod(Excel.Event, "Resize"), PID, "ahk_id " Win_Hwnd) ; LOCATIONCHANGE
			;~ WinHook.Event.Add(0x000B, 0x000B, ObjBindMethod(Excel.Event, "Resize"), PID, "ahk_id " Win_Hwnd) ; MOVESIZEEND
			; -----
			WinGetPos,,, Win_W, Win_H, ahk_id %Win_Hwnd%
			Gui_X := Win_W - 45 - 49 ; Exact numbers and scaling effected by screen DPI
			Gui_Y := Win_H - 60 - 34 ; Exact numbers and scaling effected by screen DPI
			; Gui Create
			Gui Excel:Default
			Gui +Resize
			Gui, Font, s12, Bold Verdana
			Gui, Margin, 0, 0
			Gui, Add, Button, xp yp Default HWNDButton gButton, Click
			Gui, +LastFound +ToolWindow +AlwaysOnTop -Caption -Border HWNDGui_Hwnd
			Excel.Gui_Hwnd := Gui_Hwnd ; Assign to Class variable to allow access from other Methods
			DllCall("SetParent", "uint", Gui_Hwnd, "uint", Win_Hwnd)
			Gui, Show, x%Gui_X% y%Gui_Y%
			return
			; Gui Actions
			Button:
				MsgBox Clicked
			return
			ExcelGuiSize:
				Excel.Gui_W := A_GuiWidth ; Assign to Class variable to allow access from other Methods
				Excel.Gui_H := A_GuiHeight ; Assign to Class variable to allow access from other Methods
				GuiControl, Move, %Button%, % "W" Excel.Gui_W " H" Excel.Gui_H
			return
		}
	}
	class Event
	{	
		Resize(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
		{
			WinGetPos,,, Win_W, Win_H, ahk_id %hwnd%
			Gui_X := Win_W - 45 - Excel.Gui_W
			Gui_Y := Win_H - 60 - Excel.Gui_H
			WinMove, % "ahk_id " Excel.Gui_Hwnd,, Gui_X, Gui_Y
			return
		}
	}
}
;}
This watches for an Excel window to be created, creates a button Gui in the bottom right corner. It also sets up the subroutines so that button can be resized and clicked on while keeping those subroutines inside the class to keep it neat. Then it sets an event hook to watch for the Excel window changing location with also fires when the window changes size, snaps, maximizes, etc. so that the button can be moved to stay in the button right corner.

Here are a couple of tools to monitor all shell and event hooks to try to find the information needed to make a more targeted hook. The 'Event' code sent back is usually the crucial information needed.

WinHook.Shell Monitor

Code: Select all

Gui, +AlwaysOnTop
Gui, Add, Text,, WinHook.Shell
Gui, Add, ListView, r25 w1000, Win_Hwnd|Win_Title|Win_Class|Win_Exe|Win_Event
Gui, Show

WinHook.Shell.Add("AllShell") ; no additional filter parameters result in all windows

AllShell(Win_Hwnd, Win_Title, Win_Class, Win_Exe, Win_Event)
{
	LV_Insert(1, "", Win_Hwnd, Win_Title, Win_Class, Win_Exe, Win_Event)
	Loop, 5
		LV_ModifyCol(A_Index, "AutoHdr")
}

return
GuiClose:
ExitApp
WinHook.Event Monitor

Code: Select all

Gui, +AlwaysOnTop
Gui, Add, Text,, WinHook.Event
Gui, Add, ListView, r25 w1000, hWinEventHook|Event|hWnd|idObject|idChild|dwEventThread|dwmsEventTime|wTitle|wClass
Gui, Show

WinHook.Event.Add(0x0000, 0xFFFF, "AllEvent") ; 0x0000 to 0xFFFF is all events, also with no process specified it defaults to all processes.

AllEvent(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime)
{
	WinGetTitle, wTitle, ahk_id %Hwnd%
	WinGetClass, wClass, ahk_id %Hwnd%
	LV_Insert(1, "", hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime, wTitle, wClass)
	Loop, 9
		LV_ModifyCol(A_Index, "AutoHdr")
}

return
GuiClose:
ExitApp

I am not entirely sure what happens if a function is triggered faster than Autohotkey can return from the function. Normally the function called needs to resolve pretty quickly. I am not sure what would happen if a function took 10 seconds to resolve and then it is called a hundred times every 10 seconds. So even though WinHook makes it easier to use hooks there is still some required knowledge to find the right event numbers and use them effectively.

FG
Last edited by FanaticGuru on 28 Nov 2022, 17:35, edited 8 times in total.
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: [Class] WinHook

20 Nov 2018, 02:26

Thank you very much for this class is great!
I have some scripts with hooks, with this class, the scripts, will be simpler
Thank you!
Donec Perficiam
User avatar
hoppfrosch
Posts: 449
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: [Class] WinHook

20 Nov 2018, 06:07

:bravo:
CyL0N
Posts: 211
Joined: 27 Sep 2018, 09:58

Re: [Class] WinHook

20 Nov 2018, 06:49

DOPE! Have A :cookie:
live ? long & prosper : regards
burque505
Posts: 1748
Joined: 22 Jan 2017, 19:37

Re: [Class] WinHook

20 Nov 2018, 16:49

Very nice indeed, FG, thank you!
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Class] WinHook

21 Nov 2018, 03:59

Well done :thumbup:.

Some notes, WinHook.Shell.Message doesn't consider what is returned from the user's function, see What the Function Should Return. If the function returns a non-zero integer, that should probably be returned directly. In WinHook.Event.Add, you only need to call registercallback ones, for example, use a static variable static cb := RegisterCallback(WinHook.Event.Message) and pass it to SetWinEventHook. When unhooking, you should probably delete the relevant entry in WinHook.Event.Hooks, beacuse once unhooked, the hook handle is not valid, and to release the user function object.

Cheers.
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

Re: [Class] WinHook

21 Nov 2018, 11:00

This class looks very good. I've spent a lot of time making my wineventhooks work and respond quickly. So far I have not solved the problem of ending the old hook and setting a new hook for the new application PID after it had to be restarted. This is another reason to praise your work! Many Thanks.
User avatar
FanaticGuru
Posts: 1946
Joined: 30 Sep 2013, 22:25

Re: [Class] WinHook

21 Nov 2018, 13:23

Helgef wrote:
21 Nov 2018, 03:59
Some notes, WinHook.Shell.Message doesn't consider what is returned from the user's function, see What the Function Should Return. If the function returns a non-zero integer, that should probably be returned directly. In WinHook.Event.Add, you only need to call registercallback ones, for example, use a static variable static cb := RegisterCallback(WinHook.Event.Message) and pass it to SetWinEventHook. When unhooking, you should probably delete the relevant entry in WinHook.Event.Hooks, beacuse once unhooked, the hook handle is not valid, and to release the user function object.
Great feedback!

I appreciate you taking the time to look at the code and provide your expert insight.

I will update in the near future.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
DRocks
Posts: 565
Joined: 08 May 2018, 10:20

Re: [Class] WinHook

23 Nov 2018, 23:28

Wow thats pretty nice thank you for sharing that. Its currently above my knowledge to follow how you build a class but I will slowly get used to this by reading these kind of great examples. ...at first I didnt get functions and now theyre my hest friends so lets see in the future.. maybe classes too :)
User avatar
FanaticGuru
Posts: 1946
Joined: 30 Sep 2013, 22:25

Re: [Class] WinHook

25 Nov 2018, 16:58

Updated on First Post

Update: 2018 11 23
  • Static RegisterCallBack
  • Added Report method
  • Added Remove method
  • Return Index or Handle from Add method
  • Use Index or Handle to Remove or Unhook
  • Clean up Array of Hooks when Unhooked or Removed
  • DetectHiddenWindows On
  • Return value from user function
Returning value from user function does not really appear to do anything. MSDN documentation talks about returning a non-zero value to cancel action but that does not appear to work with the timing. Maybe I am not passing the value back through the callback correctly but even just putting a MsgBox to pause the user function does not pause the action. For example I could not prevent a window from being destroyed.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: [Class] WinHook

26 Nov 2018, 09:05

very good :thumbup:
burque505
Posts: 1748
Joined: 22 Jan 2017, 19:37

Re: [Class] WinHook

27 Nov 2018, 18:56

Something odd happened following the last update. When I run it now, none of the examples work. Same behavior on Win7 Pro 64-bit SP1 and Win10 Pro with all updates (different computers of course).
Even stranger, the scripts from the old forums like
Spoiler
no longer work on either machine. Very strange ...
Regards,
burque505
User avatar
hoppfrosch
Posts: 449
Joined: 07 Oct 2013, 04:05
Location: Rhine-Maine-Area, Hesse, Germany
Contact:

Re: [Class] WinHook

28 Nov 2018, 00:29

Everything fine here with Win10 Enterprise and AKK 1.1.30.01
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: [Class] WinHook

28 Nov 2018, 02:25

burque505 wrote:
27 Nov 2018, 18:56
Something odd happened following the last update. When I run it now, none of the examples work. Same behavior on Win7 Pro 64-bit SP1 and Win10 Pro with all updates (different computers of course).
Even stranger, the scripts from the old forums like
Spoiler
no longer work on either machine. Very strange ...
Regards,
burque505
Hi burque505
The script also does not work for my in W10 Home x64 AHK v1.1.30.01 64-bit / Unicode
If I run it as an administrator works fine
probably any update wiindows, before I had no problems
I had to put "RunAsAdmin" and "RunAsAdmin_PARAMS scripts in all my scripts
Test and put at top of script, maybe the cause..
Original script in https://autohotkey.com/board/topic/4652 ... arams-lib/

Script RunAsAdmin
Spoiler
Script RunAsAdmin_PARAMS
Spoiler
Donec Perficiam
burque505
Posts: 1748
Joined: 22 Jan 2017, 19:37

Re: [Class] WinHook

28 Nov 2018, 09:58

Hi jmeneses,
Long time no see. Moltes gràcies per la teva l'aportació :)
I tried it on the Win7 box (the Params script, I'd already tried the straight Admin script from the docs) and no luck. I think you're right about the update - there was a massive one for me right before the WinHook update. I'll give it a try on Win10 tonight.
Thanks again!
Regards,
burque505
User avatar
FanaticGuru
Posts: 1946
Joined: 30 Sep 2013, 22:25

Re: [Class] WinHook

28 Nov 2018, 17:11

burque505 wrote:
27 Nov 2018, 18:56
Something odd happened following the last update. When I run it now, none of the examples work. Same behavior on Win7 Pro 64-bit SP1 and Win10 Pro with all updates (different computers of course).
November 27, 2018—KB4467682 (OS Build 17134.441) on Windows 10 Pro, works fine for me.

I had a similar problem with an Windows update messing up some of my scripts like a year ago but I only vaguely remember the solution then. In that case the update changed a security setting in my Registry. I had to use RegEdit to change it back. I can't remember what is was though.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
burque505
Posts: 1748
Joined: 22 Jan 2017, 19:37

Re: [Class] WinHook

28 Nov 2018, 17:22

:) It would be a miracle for me if I remembered back that far. Thanks!
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: [Class] WinHook

28 Nov 2018, 21:33

- @DRocks: Try this. Cheers.
jeeswg's object classes tutorial - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=7&t=54588
- Interesting work FanaticGuru. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: [Class] WinHook

26 Dec 2018, 15:23

Hi,

This class seems pretty good!

Lets say "Control_Id" variable contains the hwnd of a specific control, so, how can I use this class to monitor "Control_Id" events! (Examples below:)

something like:

On(Control_Id, "destroy", Executefunction_A)
On(Control_Id, "hide", Executefunction_B)

Thanks!
User avatar
FanaticGuru
Posts: 1946
Joined: 30 Sep 2013, 22:25

Re: [Class] WinHook

26 Dec 2018, 17:03

User wrote:
26 Dec 2018, 15:23
Lets say "Control_Id" variable contains the hwnd of a specific control, so, how can I use this class to monitor "Control_Id" events! (Examples below:)

something like:

On(Control_Id, "destroy", Executefunction_A)
On(Control_Id, "hide", Executefunction_B)

This script is a wrapper for RegisterShellHookWindow and SetWinEventHook functions that are built into Windows. Those two functions monitor windows, not controls within windows.

I don't think those two functions can catch the control events like you want.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: ThioJoe and 27 guests