argumentum Posted July 14 Posted July 14 expandcollapse popup#include <GuiMenu.au3> #include <SendMessage.au3> #include <WinAPIGdi.au3> #include <WinAPIMisc.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> Local $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword') Global $g_tRECT, $g_iIndex, $g_hMenu = 0 OnAutoItExitRegister('OnAutoItExit') Local $hEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_MENUPOPUPSTART, $EVENT_SYSTEM_MENUPOPUPEND, DllCallbackGetPtr($hEventProc)) ;~ Run(@SystemDir & '\notepad.exe') Local $iNotepad_PID = ShellExecute('notepad.exe') While ProcessExists($iNotepad_PID) Sleep(1000) WEnd Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) EndFunc ;==>OnAutoItExit Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) ConsoleWrite('- Func _EventProc(' & $hEventHook & ', ' & $iEvent & ', ' & $hWnd & ', ' & $iObjectID & ', ' & $iChildID & ', ' & $iThreadId & ', ' & $iEventTime & ') - _WinAPI_GetWindowFileName($hWnd) >' & _WinAPI_GetWindowFileName($hWnd) & '< -' & @CRLF) #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime Local Static $iAddCalc = True Switch $iEvent Case $EVENT_SYSTEM_MENUPOPUPSTART ; Add "View - Calculator" If $iAddCalc Then $g_hMenu = _SendMessage($hWnd, $MN_GETHMENU) ConsoleWrite('@@(' & @ScriptLineNumber & ') : _GUICtrlMenu_GetItemText($g_hMenu, 0)=' & _GUICtrlMenu_GetItemText($g_hMenu, 0) & @CRLF) ConsoleWrite('@@(' & @ScriptLineNumber & ') : _GUICtrlMenu_IsMenu($g_hMenu)=' & _GUICtrlMenu_IsMenu($g_hMenu) & @CRLF) ;~ If (_GUICtrlMenu_IsMenu($g_hMenu)) And (StringInStr(_GUICtrlMenu_GetItemText($g_hMenu, 0), 'Status Bar')) And (StringInStr(_WinAPI_GetWindowFileName($hWnd), 'notepad.exe')) Then If (_GUICtrlMenu_IsMenu($g_hMenu)) And ((StringInStr(_GUICtrlMenu_GetItemText($g_hMenu, 0), 'Status Bar')) Or (StringInStr(_GUICtrlMenu_GetItemText($g_hMenu, 0), '&Zoom'))) And (StringInStr(_WinAPI_GetWindowFileName($hWnd), 'notepad.exe')) Then ConsoleWrite('@@(' & @ScriptLineNumber & ') : _GUICtrlMenu_GetItemText($g_hMenu, 0)=' & _GUICtrlMenu_GetItemText($g_hMenu, 0) & @CRLF) $g_iIndex = _GUICtrlMenu_GetItemCount($g_hMenu) _GUICtrlMenu_InsertMenuItem($g_hMenu, $g_iIndex, 'Calculator' & @TAB & ':-)') $g_tRECT = _GUICtrlMenu_GetItemRectEx($hWnd, $g_hMenu, $g_iIndex) ;~ $iAddCalc = False Else $g_hMenu = 0 EndIf EndIf Case $EVENT_SYSTEM_MENUPOPUPEND If $g_hMenu Then _GUICtrlMenu_DeleteMenu($g_hMenu, $g_iIndex) Local $tPOINT = _WinAPI_GetMousePos() If _WinAPI_PtInRect($g_tRECT, $tPOINT) Then ConsoleWrite('@@(' & @ScriptLineNumber & ') : Run calc' & @CRLF) ;~ Run(@SystemDir & '\calc.exe') Run(@ComSpec & ' /c start calc', @TempDir, @SW_HIDE) EndIf $g_hMenu = 0 EndIf EndSwitch EndFunc ;==>_EventProc My "go at it" to make it run everywhere but am at a loss. Maybe one of you can make it run everywhere ? Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
MattyD Posted Tuesday at 01:33 PM Posted Tuesday at 01:33 PM (edited) Hey Mate, I'd say MN_GETHMENU is probably a non-starter because this is not your traditional Win32 menu anymore. In the hook, we probably used to see: $iObjectID = $OBJID_MENU (-4) _WinAPI_GetClassName($hWnd) = "#32768" (menu class) but with the new notepad we now get: _WinAPI_GetClassName($hWnd) = "Windows.UI.Input.InputSite.WindowClass" So not too sure what we can do with that... Edited Tuesday at 01:34 PM by MattyD WildByDesign 1
WildByDesign Posted Tuesday at 02:12 PM Posted Tuesday at 02:12 PM On 7/14/2025 at 12:23 PM, argumentum said: Maybe one of you can make it run everywhere ? Some great points from MattyD. Notepad in general is more difficult for examples these days because the handling is different whether it’s classic or modern Notepad. Is it possible to use an example that is not Notepad and not menu related?
WildByDesign Posted Tuesday at 02:19 PM Posted Tuesday at 02:19 PM Similar to the infosec world (my area), “popping calc” with a proof of concept exploit is also not what it used to be. Most PoC examples would follow up by running calc.exe if successful. But now Calculator is a slow as molasses UWP app and things are different.
argumentum Posted Tuesday at 02:31 PM Author Posted Tuesday at 02:31 PM 54 minutes ago, MattyD said: ...this is not your traditional Win32 menu anymore. Yeap !. Nonetheless if a working example could be provided.., that would be nice. ( am into too many things right now to take a crack at it 🤷♂️ ) Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
MattyD Posted Wednesday at 08:15 AM Posted Wednesday at 08:15 AM I don't really know where I'm going here - but I guess this might be a step in the right direction.. expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y ;x86 is broken - future Matt's problem!. #include <GuiMenu.au3> #include <SendMessage.au3> #include <WinAPIGdi.au3> #include <WinAPIMisc.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> #include <APIErrorsConstants.au3> Global Const $S_OK = 0, $S_FALSE = 1 Global Enum $VT_EMPTY = 0, _ $VT_I4 = 3, _ $VT_BSTR = 8, _ $VT_DISPATCH = 9 Global Const $sIID_NULL = "{00000000-0000-0000-0000-000000000000}" Global Const $sIID_IDispatch = "{00020400-0000-0000-C000-000000000046}" Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_IAccessible = "{618736e0-3c3d-11cf-810c-00aa00389b71}" ;~ Global Const $sIID_ITypeInfo = "{00020401-0000-0000-C000-000000000046}" ;~ Global Const $sIID_ITypeLib = "{00020402-0000-0000-C000-000000000046}" Global $tagIDiapatch = "GetTypeInfoCount hresult(uint*);" & _ "GetTypeInfo hresult(uint;int;ptr*);" & _ "GetIDsOfNames hresult(struct*;wstr;uint;int;int);" & _ "Invoke hresult(int;struct*;int;word;ptr*;ptr*;ptr*;uint*);" ;Use struct* instead of variant for input. if sending 0 as variant, the value doesn't seem to be sent as VT_I4. (Probably VT_EMPTY) Global $tagIAccessible = $tagIDiapatch & _ "get_accParent hresult(ptr*);" & _ "get_accChildCount hresult(long*);" & _ "get_accChild hresult(struct*;ptr*);" & _ "get_accName hresult(struct*;bstr*);" & _ "get_accValue hresult(struct*;bstr*);" & _ "get_accDescription hresult(struct*;bstr*);" & _ "get_accRole hresult(struct*;variant*);" & _ "get_accState hresult(struct*;variant*);" & _ "get_accHelp hresult(struct*;bstr*);" & _ "get_accHelpTopic hresult(bstr*;struct*;long*);" & _ "get_accKeyboardShortcut hresult(struct*;bstr*);" & _ "get_accFocus hresult(struct*);" & _ "get_accSelection hresult(variant*);" & _ "get_accDefaultAction hresult(struct*;bstr*);" & _ "accSelect hresult(long;struct*);" & _ "accLocation hresult(long*;long*;long*;long*;struct*);" & _ "accNavigate hresult(long;variant;variant*);" & _ "accHitTest hresult(long;long;variant*);" & _ "accDoDefaultAction hresult(struct*);" & _ "put_accName hresult(struct*;bstr);" & _ "put_accValue hresult(struct*;bstr);" Global $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword') Global $g_tRECT, $g_iIndex, $g_hMenu = 0 OnAutoItExitRegister('OnAutoItExit') Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_MENUPOPUPSTART, $EVENT_SYSTEM_MENUPOPUPEND, DllCallbackGetPtr($hEventProc)) Global $iNotepad_PID = ShellExecute('notepad.exe') While ProcessExists($iNotepad_PID) Sleep(1000) WEnd Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) EndFunc ;==>OnAutoItExit Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) ConsoleWrite(StringFormat('hHook[%s] iEvent[%s] hWnd[%s] iObjectID[%s] iChildID[%s] $iThreadId[%s] iEventTime[%s]', $hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) & @CRLF) #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime Switch $iEvent Case $EVENT_SYSTEM_MENUPOPUPSTART ConsoleWrite(_WinAPI_GetClassName($hWnd) & @CRLF) Local $pObj = _WinAPI_AccessibleObjectFromEvent($hWnd, $iObjectID, $iChildID) If Not @error Then Local $oObj = ObjCreateInterface($pObj, $sIID_IAccessible, $tagIAccessible) Local $sName, $iCount, $oChildObj Local $tVt_I4 = DllStructCreate("align 2;ushort vt;word Pad[3];int int") $tVt_I4.vt = $VT_I4 SetError($oObj.get_accName($tVt_I4, $sName)) If @error Then $sName = StringFormat("ERR[0x%08x]", @error) ConsoleWrite("MENU: " & $sName & @CRLF) $oObj.get_accChildCount($iCount) Local $pChildObj Local $aChild = _WinAPI_AccessibleChildren($pObj, 0, $iCount) For $i = 0 To UBound($aChild) - 1 $sName = "" $oChildObj = 0 ConsoleWrite("CHILD[" & $i & "]: ") If IsPtr($aChild[$i]) Then ;Child has been retrieved as an object in its own right $oChildObj = ObjCreateInterface($aChild[$i], $sIID_IAccessible, $tagIAccessible) $tVt_I4.Int = 0 Else $tVt_I4.Int = $aChild[$i] SetError($oObj.get_accChild($tVt_I4, $pChildObj)) Switch @error Case $S_OK ;We shouldn't end up here. AccessibleChildren probably would've retuned a VT_DISPATCH for the child. $oChildObj = ObjCreateInterface($pChildObj, $sIID_IAccessible, $tagIAccessible) $tVt_I4.Int = 0 Case $S_FALSE ;Child is an Element (get detials from this object.) $oChildObj = $oObj Case Else ConsoleWrite("ERROR: 0x" & Hex(@error) & @CRLF) EndSwitch EndIf SetError($oChildObj.get_accName($tVt_I4, $sName)) If (@error < $S_OK) Or @error > $S_FALSE Then ConsoleWrite(ConsoleWrite("ERROR: 0x" & Hex(@error) & @CRLF)) Else ConsoleWrite($sName & @CRLF) EndIf Next EndIf Case $EVENT_SYSTEM_MENUPOPUPEND EndSwitch EndFunc ;==>_EventProc Func _WinAPI_AccessibleObjectFromEvent($hWnd, $iID, $iChildID) Local $tVt_I4 = DllStructCreate("align 2;ushort vt;word Pad[3];int int") Local $aCall = DllCall("Oleacc.dll", "long", "AccessibleObjectFromEvent", "hwnd", $hWnd, "dword", $iID, "dword", $iChildID, "ptr*", 0, "struct*", $tVt_I4) If @error Then Return SetError(@error, 0, 0) ConsoleWrite(StringFormat("AccessibleObjectFromEvent: pIAccessible[%s], iChildID[%d]", $aCall[4], $tVt_I4.int) & @CRLF) Return SetError($aCall[0], 0, $aCall[4]) EndFunc Func _WinAPI_AccessibleChildren($pAccessible, $iChildStart, $iCount) Local $tagVt_Dispatch = "align 2;ushort vt;word Pad[3];dword_ptr data" Local $tagVt_I4 = "align 2;ushort vt;word Pad[3];int data" Local $tBuff = DllStructCreate(StringFormat("byte data[%d]", $iCount * 24)) Local $aCall = DllCall("Oleacc.dll", "long", "AccessibleChildren", "ptr", $pAccessible, "int", $iChildStart, "int", $iCount, "struct*", $tBuff, "long*", 0) If @error Then Return SetError(@error, 0, 0) Local $aChildern[$aCall[5]], $tVt For $i = 0 To $aCall[5] - 1 $tVt = DllStructCreate($tagVt_I4, Ptr(DllStructGetPtr($tBuff) + $i * 24)) If $tVt.Vt = $VT_DISPATCH Then $tVt = DllStructCreate($tagVt_Dispatch, Ptr(DllStructGetPtr($tBuff) + $i * 24)) $aChildern[$i] = $tVt.data If $tVt.Vt = $VT_DISPATCH Then $aChildern[$i] = Ptr($aChildern[$i]) Next ReDim $aChildern[$i] Return SetError($aCall[0], $aCall[5], $aChildern) EndFunc Is the aim just to get a general demonstration of _WinAPI_SetWinEventHook() for the helpfile?? To @WildByDesign's point, maybe we should just do something simple that's easy to follow? KaFu 1
KaFu Posted Wednesday at 10:02 AM Posted Wednesday at 10:02 AM 1 hour ago, MattyD said: Is the aim just to get a general demonstration of _WinAPI_SetWinEventHook() for the helpfile?? To @WildByDesign's point, maybe we should just do something simple that's easy to follow? I think that's the goal, but anyone using _WinAPI_SetWinEventHook() in the first place would prefer a more complex and thorough example (at least I would). Your example above detects the popup on my Win10, but when I go over the popup the script hard-crashes. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
MattyD Posted Wednesday at 10:58 AM Posted Wednesday at 10:58 AM 22 minutes ago, KaFu said: anyone using _WinAPI_SetWinEventHook() in the first place would prefer a more complex and thorough example Fair enough - I just thought we might be pushing the needle a bit into "too convoluted" territory. 49 minutes ago, KaFu said: when I go over the popup the script hard-crashes Hmm, the script is very scruffy at the moment (and also leaky) ... but its not crashing on mine (Win11 24H2). Are you able to elaborate where its dying? I've just been clicking on the top menus and pulling up context menus in notepad. Then clicking on scite menus to test a win32 program...
KaFu Posted Wednesday at 11:31 AM Posted Wednesday at 11:31 AM This call is crashing the script for me: Local $oObj = ObjCreateInterface($pObj, $sIID_IAccessible, $tagIAccessible) OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
MattyD Posted Wednesday at 12:33 PM Posted Wednesday at 12:33 PM OK thanks. I guess I'll find myself a win10 machine tomorrow.
argumentum Posted Wednesday at 12:40 PM Author Posted Wednesday at 12:40 PM My 2 cents: We may have to come up with some implementation of UIA for general consumption/distribution with the product ( AutoIt3 ). But that is a heavy undertaking and it will need collaboration. The two that are established are by MVPs. The question is how to not step in any toes and get full ego free participation. Actually reading this as am typing, it don't sound emotionally correct but, I don't find another way to present my view ( am somewhat autistic and have problems with emotions most of the time ). So, either or. Either we make just an example or, we make a UDF that can be accepted as a regular distribution with AutoIt3. ( and by we, I mean you all, as am not savvy enough for the undertaking ) Therefore, lets have a chat and figure out, among as participants of the post, what we believe would be better for an example. Just the example, or the example based in the future fully integrated into AutoIt3 UDF. PS: The two that I saw by a quick search are by @junkew and by @LarsJ. I'd like any and all to participate as either coders or advisors. Either form of participation will be highly beneficial for this project. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted Wednesday at 12:52 PM Author Posted Wednesday at 12:52 PM 10 minutes ago, MattyD said: OK thanks. I guess I'll find myself a win10 machine tomorrow. I've said it before and I'll say it again: VMs, VMs, VMs ! I run virtual machines to an absurd count ( too much of anything is a bad thing ) ..to the point of coding something to make 'em faster to create. In any case, see if VMs are right for you. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted Wednesday at 01:37 PM Author Posted Wednesday at 01:37 PM 5 hours ago, MattyD said: maybe we should just do something simple that's easy to follow? ...I woke up chatty If simple to follow, it'd be because the heavy/long functions are elsewhere, in a UDF. Hence my proposal of "lets make UDFs !, yey !" Otherwise the example script will be quite large. And in any case, at times UIA is the only way to go at it, if at all. But for M$ stuff ( and those that abide by it ), UIA should be all that's needed. ( I think, I don't know enough to make the claim ) Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
MattyD Posted Thursday at 12:10 PM Posted Thursday at 12:10 PM 22 hours ago, argumentum said: I've said it before and I'll say it again: VMs, VMs, VMs ! yeah so I have a bunch of VMs on a 2011 iMac... but I doubt it'll handle win10. I can test on Win3.1 if you'd like 21 hours ago, argumentum said: lets have a chat and figure out, among as participants of the post, what we believe would be better for an example. It probably depends on what we want to achieve here. In honesty, I'd say the simplest fix to the "it's broken" problem is to just change what the example does. Otherwise sure, let's attempt to replicate the original behavior. It'll be a good learning exercise anyway. If a broader UDF is necessary I'm happy to contribute where I can - but this is probably jumping the gun... ATM I'm just prodding at things to see whats possible, so I'm not there yet! Anyway I've worked out the Win10 thing. You need to use a dll handle with DllCall rather than specifying a string - obvioulsy unloading "Oleacc.dll" causes issues!. I've no idea why the scite menus worked in win10, but the notepad ones cause an access violation.... Here's the update: expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y ;x86 is broken - future Matt's problem!. #include <GuiMenu.au3> #include <SendMessage.au3> #include <WinAPIGdi.au3> #include <WinAPIMisc.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> #include <APIErrorsConstants.au3> Global Const $S_OK = 0, $S_FALSE = 1 Global Enum $VT_EMPTY = 0, _ $VT_I4 = 3, _ $VT_BSTR = 8, _ $VT_DISPATCH = 9 Global $tagVt_I4 = "align 2;ushort vt;word Pad[3];int data" Global $tagVt_Dispatch = "align 2;ushort vt;word Pad[3];ptr data" Global Const $sIID_NULL = "{00000000-0000-0000-0000-000000000000}" Global Const $sIID_IDispatch = "{00020400-0000-0000-C000-000000000046}" Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_IAccessible = "{618736e0-3c3d-11cf-810c-00aa00389b71}" Global $tagIDispatch = "GetTypeInfoCount hresult(uint*);" & _ "GetTypeInfo hresult(uint;int;ptr*);" & _ "GetIDsOfNames hresult(struct*;wstr;uint;int;int);" & _ "Invoke hresult(int;struct*;int;word;ptr*;ptr*;ptr*;uint*);" ;Use struct* instead of variant for input. if sending 0 as variant, the value doesn't seem to be sent as VT_I4. (Probably VT_EMPTY) Global $tagIAccessible = $tagIDispatch & _ "get_accParent hresult(ptr*);" & _ "get_accChildCount hresult(long*);" & _ "get_accChild hresult(struct*;ptr*);" & _ "get_accName hresult(struct*;bstr*);" & _ "get_accValue hresult(struct*;bstr*);" & _ "get_accDescription hresult(struct*;bstr*);" & _ "get_accRole hresult(struct*;variant*);" & _ "get_accState hresult(struct*;variant*);" & _ "get_accHelp hresult(struct*;bstr*);" & _ "get_accHelpTopic hresult(bstr*;struct*;long*);" & _ "get_accKeyboardShortcut hresult(struct*;bstr*);" & _ "get_accFocus hresult(struct*);" & _ "get_accSelection hresult(variant*);" & _ "get_accDefaultAction hresult(struct*;bstr*);" & _ "accSelect hresult(long;struct*);" & _ "accLocation hresult(long*;long*;long*;long*;struct*);" & _ "accNavigate hresult(long;variant;variant*);" & _ "accHitTest hresult(long;long;variant*);" & _ "accDoDefaultAction hresult(struct*);" & _ "put_accName hresult(struct*;bstr);" & _ "put_accValue hresult(struct*;bstr);" Global $__g_hDllOleacc = DllOpen("Oleacc.dll") Global $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword') OnAutoItExitRegister('OnAutoItExit') Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_MENUPOPUPSTART, $EVENT_SYSTEM_MENUPOPUPEND, DllCallbackGetPtr($hEventProc)) Global $iNotepad_PID = ShellExecute('notepad.exe') While ProcessExists($iNotepad_PID) Sleep(1000) WEnd Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) DllClose($__g_hDllOleacc) EndFunc ;==>OnAutoItExit Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) ConsoleWrite(StringFormat('Hook: iEvent[%s] iObjectID[%s] iChildID[%s]', $iEvent, $iObjectID, $iChildID) & @CRLF) #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime Switch $iEvent Case $EVENT_SYSTEM_MENUPOPUPSTART ConsoleWrite(_WinAPI_GetClassName($hWnd) & @CRLF) Local $pObj = _WinAPI_AccessibleObjectFromEvent($hWnd, $iObjectID, $iChildID) If Not @error Then Local $oObj = ObjCreateInterface($pObj, $sIID_IAccessible, $tagIAccessible) Local $sName, $iCount, $oChildObj Local $tVt_I4 = DllStructCreate($tagVt_I4) $tVt_I4.vt = $VT_I4 SetError($oObj.get_accName($tVt_I4, $sName)) If @error Then $sName = StringFormat("ERR[0x%08x]", @error) ConsoleWrite("MENU: " & $sName & @CRLF) $oObj.get_accChildCount($iCount) Local $pChildObj Local $aChild = _WinAPI_AccessibleChildren($pObj, 0, $iCount) For $i = 0 To UBound($aChild) - 1 $sName = "" $oChildObj = 0 ConsoleWrite("CHILD[" & $i & "]: ") If IsPtr($aChild[$i]) Then ;Child has been retrieved as an object in its own right $oChildObj = ObjCreateInterface($aChild[$i], $sIID_IAccessible, $tagIAccessible) $tVt_I4.data = 0 Else $tVt_I4.data = $aChild[$i] SetError($oObj.get_accChild($tVt_I4, $pChildObj)) Switch @error Case $S_OK ;We shouldn't end up here. AccessibleChildren probably would've retuned a VT_DISPATCH for the child. $oChildObj = ObjCreateInterface($pChildObj, $sIID_IAccessible, $tagIAccessible) $tVt_I4.data = 0 Case $S_FALSE ;Child is an Element (get detials from this object.) $oChildObj = $oObj Case Else ConsoleWrite("ERROR: 0x" & Hex(@error) & @CRLF) ContinueLoop EndSwitch EndIf SetError($oChildObj.get_accName($tVt_I4, $sName)) If (@error < $S_OK) Or @error > $S_FALSE Then ConsoleWrite(ConsoleWrite("ERROR: 0x" & Hex(@error) & @CRLF)) Else ConsoleWrite($sName & @CRLF) EndIf Next EndIf Case $EVENT_SYSTEM_MENUPOPUPEND EndSwitch EndFunc ;==>_EventProc Func _WinAPI_AccessibleObjectFromEvent($hWnd, $iID, $iChildID) Local $tVt_I4 = DllStructCreate($tagVt_I4) Local $aCall = DllCall($__g_hDllOleacc, "long", "AccessibleObjectFromEvent", "hwnd", $hWnd, "dword", $iID, "dword", $iChildID, "ptr*", 0, "struct*", $tVt_I4) If @error Then Return SetError(@error, 0, 0) ConsoleWrite(StringFormat("AccessibleObjectFromEvent: pIAccessible[%s], iChildID[%d]", $aCall[4], $tVt_I4.data) & @CRLF) Return SetError($aCall[0], 0, $aCall[4]) EndFunc Func _WinAPI_AccessibleChildren($pAccessible, $iChildStart, $iCount) Local $tBuff = DllStructCreate(StringFormat("byte data[%d]", $iCount * 24)) Local $aCall = DllCall($__g_hDllOleacc, "long", "AccessibleChildren", "ptr", $pAccessible, "int", $iChildStart, "int", $iCount, "struct*", $tBuff, "long*", 0) If @error Then Return SetError(@error, 0, 0) Local $aChildren[$aCall[5]], $tVt For $i = 0 To $aCall[5] - 1 $tVt = DllStructCreate($tagVt_I4, Ptr(DllStructGetPtr($tBuff) + $i * 24)) If $tVt.Vt = $VT_DISPATCH Then $tVt = DllStructCreate($tagVt_Dispatch, Ptr(DllStructGetPtr($tBuff) + $i * 24)) $aChildren[$i] = $tVt.data If $tVt.Vt = $VT_DISPATCH Then $aChildren[$i] = Ptr($aChildren[$i]) Next ReDim $aChildren[$i] Return SetError($aCall[0], $aCall[5], $aChildren) EndFunc KaFu and argumentum 1 1
KaFu Posted Thursday at 12:28 PM Posted Thursday at 12:28 PM Excellent, does not crash for me too 👍. MattyD 1 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2025-May-18) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
argumentum Posted Thursday at 12:50 PM Author Posted Thursday at 12:50 PM ...welcome to the future Running my head on the keyboard: ( typing my thoughts ) I don't know where/what to say, what, in regards to an example that works everywhere. Plus also, who has all the windows versions and stuff M$ is coming up with !. @MattyD, thanks for the code. It does what is coded for. I guess wait and see what the higher ups have to say. ( and they themselves are doing other things too ) @KaFu, what are your thoughts in regards to modernizing the example script to work with current windows versions ? Or the UIA UDF am thinking of ( but never used personally. Don't even know how it does what. ) ? ( but I guess, just guess, that it is the way that these examples would work with ) Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now