junkew Posted August 21, 2013 Share Posted August 21, 2013 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 FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
trancexx Posted August 27, 2013 Share Posted August 27, 2013 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: expandcollapse popup$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 junkew 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
junkew Posted August 28, 2013 Author Share Posted August 28, 2013 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) FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
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