Jump to content

ObjEvent possible with .AddFocusChangedEventHandler?


 Share

Recommended Posts

In this post I have a working example for 

;~ The main object with acces to the windows automation api 3.0 
Global $objUIAutomation = _AutoItObject_ObjCreate($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation) ;~ Focus Changed Handler Global $oFCEHandler = _AutoItObject_ObjectFromDtag("_MyHandler_", $dtagIUIAutomationFocusChangedEventHandler) $objUIAutomation.AddFocusChangedEventHandler(0, $oFCEHandler.__ptr__)

Now I am rebuilding this thread in this thread

'?do=embed' frameborder='0' data-embedContent>>

So far I am not able to get events from the UIAutomation object without using AutoITObject library

Should I use OBJEvent or should I copy/paste only the relevant callback logic from the AIO library?

MSDN info regarding AddFocusChangedEventHandler

http://msdn.microsoft.com/en-us/library/windows/desktop/ee671509(v=vs.85).aspx

Link to comment
Share on other sites

You can use this function:

Func ObjectFromTag($sFunctionPrefix, $tagInterface, ByRef $tInterface)
    Local Const $tagIUnknown = "QueryInterface hresult(ptr;ptr*);" & _
            "AddRef dword();" & _
            "Release dword();"
    ; Adding IUnknown methods
    $tagInterface = $tagIUnknown & $tagInterface
    Local Const $PTR_SIZE = DllStructGetSize(DllStructCreate("ptr"))
    ; Below line really simple even though it looks super complex. It's just written weird to fit one line, not to steal your eyes
    Local $aMethods = StringSplit(StringReplace(StringReplace(StringReplace(StringReplace(StringTrimRight(StringReplace(StringRegExpReplace($tagInterface, "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF), ";" & @LF, @LF), 1), "object", "idispatch"), "variant*", "ptr"), "hresult", "long"), "bstr", "ptr"), @LF, 3)
    Local $iUbound = UBound($aMethods)
    Local $sMethod, $aSplit, $sNamePart, $aTagPart, $sTagPart, $sRet, $sParams
    ; Allocation. Read http://msdn.microsoft.com/en-us/library/ms810466.aspx to see why like this (object + methods):
    $tInterface = DllStructCreate("ptr[" & $iUbound + 1 & "]")
    If @error Then Return SetError(1, 0, 0)
    For $i = 0 To $iUbound - 1
        $aSplit = StringSplit($aMethods[$i], "|", 2)
        If UBound($aSplit) <> 2 Then ReDim $aSplit[2]
        $sNamePart = $aSplit[0]
        $sTagPart = $aSplit[1]
        $sMethod = $sFunctionPrefix & $sNamePart
        $aTagPart = StringSplit($sTagPart, ";", 2)
        $sRet = $aTagPart[0]
        $sParams = StringReplace($sTagPart, $sRet, "", 1)
        $sParams = "ptr" & $sParams
        DllStructSetData($tInterface, 1, DllCallbackGetPtr(DllCallbackRegister($sMethod, $sRet, $sParams)), $i + 2) ; Freeing is left to AutoIt.
    Next
    DllStructSetData($tInterface, 1, DllStructGetPtr($tInterface) + $PTR_SIZE) ; Interface method pointers are actually pointer size away
    Return ObjCreateInterface(DllStructGetPtr($tInterface), "", $tagInterface, False) ; and first pointer is object pointer that's wrapped
EndFunc

...And you would use it like this:

$objUIAutomation = ...

;~ Focus Changed Handler
Global $tFCEHandler
Global $oFCEHandler = ObjectFromTag("_MyHandler_", $dtagIUIAutomationFocusChangedEventHandler, $tFCEHandler)

$objUIAutomation.AddFocusChangedEventHandler(0, $oFCEHandler())

;... the rest of your code ...

$objUIAutomation.RemoveAllEventHandlers()
; The End


; Handler methods. "_MyHandler_" is the specified prefix:
Func _MyHandler_QueryInterface($pSelf, $pRIID, $pObj)
    Local $tStruct = DllStructCreate("ptr", $pObj)
    Switch _WinAPI_StringFromGUID($pRIID)
        Case $sIID_IUnknown, $sIID_IUIAutomationFocusChangedEventHandler
        Case Else
            ConsoleWrite(@CRLF)
            Return 0x80004002 ; E_NOINTERFACE
    EndSwitch
    DllStructSetData($tStruct, 1, $pSelf)
    Return 0 ; S_OK
EndFunc
Func _MyHandler_AddRef($pSelf)
    #forceref $pSelf
    Return 1
EndFunc
Func _MyHandler_Release($pSelf)
    #forceref $pSelf
    Return 1
EndFunc
Func _MyHandler_HandleFocusChangedEvent($pSelf, $pElem)
    #forceref $pSelf
    If $pElem Then
        Local $oElem = ObjCreateInterface($pElem, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
        Local $sFocused
        $oElem.CurrentClassName($sFocused)
        ConsoleWrite(">>>     Somebody is changing the focus to: " & $sFocused & @CRLF)
    EndIf
    Return 0 ; S_OK
EndFunc

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

thx a zillion times.

I like this comment in your code

; Below line really simple even though it looks super complex. It's just written weird to fit one line, not to steal your eyes    

Local $aMethods = StringSplit( _
                      StringReplace(_
                          StringReplace(_
                              StringReplace(_
                                  StringReplace(_
                                       StringTrimRight(_
                                           StringReplace(_
                                               StringRegExpReplace($tagInterface, "\h*(\w+)\h*(\w+\*?)\h*(\((.*?)\))\h*(;|;*\z)", "$1\|$2;$4" & @LF)
                                           , ";" & @LF, @LF)
                                       , 1), 
                                  "object", "idispatch"), 
                                "variant*", "ptr")
                           , "hresult", "long")
                        , "bstr", "ptr")
                   , @LF, 3)
Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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