Jump to content

Recommended Posts

Posted
#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.
autoit_scripter_blue_userbar.png

Posted (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 by MattyD
Posted
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?

Posted

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.

Posted

I don't really know where I'm going here - but I guess this might be a step in the right direction.. 

#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?

Posted
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.

Posted

 

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...

Posted

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.
autoit_scripter_blue_userbar.png

Posted
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 ! :lol:
I run virtual machines to an absurd count ( too much of anything is a bad thing ) :D 
..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.
autoit_scripter_blue_userbar.png

Posted
5 hours ago, MattyD said:

maybe we should just do something simple that's easy to follow?

...I woke up chatty :D

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 !" :lol:
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.
autoit_scripter_blue_userbar.png

Posted

 

22 hours ago, argumentum said:

I've said it before and I'll say it again: VMs, VMs, VMs ! :lol:

 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 :P

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: 

#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

 

Posted

image.png.1ee57353e0be4172994798b409f0504d.png

...welcome to the future :tv_horror:

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.
autoit_scripter_blue_userbar.png

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...