Jump to content

Recommended Posts

  • Administrators
Posted

I need a simple com object method that uses a byref / "out" parameter (other than the return value) to test some changes. AutoItX doesn't use any so does anyone have a simple one?


 

Posted (edited)

IE's ClientToWindow.

$oIE = ObjCreate("Shell.Explorer.2")
;... 
$oIE.ClientToWindow(...)

edit:

Actually no. That one is probably not good, remarks says "The WebBrowser object ...blah"

Here's other, IADsPropertyValue2::GetObjectProperty Method

; Error monitoring
Global $oError = ObjEvent("AutoIt.Error", "_ErrFunc")
Func _ErrFunc()
    ConsoleWrite("COM Error, ScriptLine(" & $oError.scriptline & ") : Number 0x" & Hex($oError.number, 8) & " - " & $oError.windescription & @CRLF)
EndFunc   ;==>_ErrFunc

Global Const $ADSTYPE_CASE_IGNORE_STRING = 3
Global Const $ADSTYPE_UNKNOWN = 26

Global $oPropList = ObjGet("WinNT://./Administrators,group")

$oPropList.GetInfo()

Global $iADsType = $ADSTYPE_UNKNOWN ; documentation says to set this to ADSTYPE_UNKNOWN if I don't know in advance what type to set

ConsoleWrite("$iADsType before = " & $iADsType & @CRLF)
Global $oPropEntry = $oPropList.GetPropertyItem("description", $iADsType)

;*** THIS! ***
ConsoleWrite("$iADsType after = " & $iADsType & @CRLF) ; This should be 3 ($ADSTYPE_CASE_IGNORE_STRING) now according to the example on the link

Global $sDescString
For $vProp In $oPropEntry.Values
    ConsoleWrite("-> " & $vProp.GetObjectProperty($ADSTYPE_CASE_IGNORE_STRING) & @CRLF)
Next
Edited by trancexx

♡♡♡

.

eMyvnE

  • Administrators
Posted

HRESULT GetPropertyItem(
  [in]      BSTR bstrName,
  [in]      LONG lnADsType,
  [in, out]  VARIANT *pVariant
);

The "out" on that seems to be the return value which I handle separately, so need another one. Something like looks like:

HRESULT GetPropertyItemFake(
  [in]      BSTR bstrName,
  [in, out]     LONG lnADsType,
  [in, out]  VARIANT *pVariant
);


 

  • Administrators
Posted

From looking at how wrong the code is, would I be right in saying that the current AutoIt implementation doesn't work with byref calls?


 

  • Administrators
Posted

The GetPropertyItem one is returning E_NOTIMPL for GetTypeInfo so I can't do much with that one (or I don't know what to do in that case). ANy others?


 

Posted

This:

Global $oObj = ObjGet("winmgmts:\\.\root\cimv2")
Global $sOwner
Global $sDomain
Global $oProcesses = $oObj.ExecQuery("Select * from Win32_Process")
For $objProcess In $oProcesses
    $sOwner = ""
    $sDomain = ""
    ; GetOwner Method of the Win32_Process Class
    ; http://msdn.microsoft.com/en-us/library/aa390460(v=VS.85).aspx
    If $objProcess.GetOwner($sOwner, $sDomain) = 0 Then ; Successful Completion
        ConsoleWrite("$objProcess.Name = " & $objProcess.Name & @CRLF)
        ConsoleWrite("$sOwner = " & $sOwner & @CRLF)
        ConsoleWrite("$sDomain = " & $sDomain & @CRLF)
        ConsoleWrite(@CRLF)
    EndIf
Next

That works already and GetTypeInfo will work.

♡♡♡

.

eMyvnE

  • Administrators
Posted

It was doing something that I thought was incredibly dangerous. Our implementation currently passes _all_ parameters by reference and it can really mess up because it involves a conversion from au3 to com and then back again even if the function didn't do anything. This caused a problem with certain conversions. For example, an autoit pointer (HWND) gets converted to a VT_UI4 (on x86) but after the COM function finishes the COM variable is converted back to AU3 but it messes up because VT_UI4 just gets converted into an AutoIt integer not a pointer.

My initial change was to get information about the COM method parameters so that after the Invoke we only attempted byref behaviour on those parameters that are explicitly marked as having an "out". My code works in some cases, but sometimes it just can't find the param information and fails.


 

Posted

How about the following from the IAccessible interface (located in oleacc.dll, defined in <OleAcc.h>:

HRESULT accLocation(
            [out] int* pxLeft, 
            [out] int* pyTop, 
            [out] int* pcxWidth, 
            [out] int* pcyHeight, 
            [in,optional] VARIANT varChild
        );

Code sample:

#include <WinAPI.au3>
Global Const $sIID_IAccessible = "{618736E0-3C3D-11CF-810C-00AA00389B71}"
Global $hOLEACC=DllOpen('oleacc.dll')
; ===================================================================================================================
; Func _AccessibleObjectFromWindow($hWnd,$iObjectID=0)
;
; $iObjectID = Object ID identifier (default 0 = OBJID_WINDOW) - see MSDN
; $bRetAsPtr = If non-zero (or True), return a pointer instead of an Object
;   This is implemented for AutoItObject's purpose
;
; Author: KaFu, slight modifications: Ascend4nt
; ===================================================================================================================

Func _AccessibleObjectFromWindow($hWnd,$iObjectID=0,$bRetAsPtr=0)
    If Not IsHWnd($hWnd) Then Return SetError(1,0,0)
    Local $stGUID,$pGUID,$aRet,$sType="idispatch*"
    $stGUID=_WinAPI_GUIDFromString($sIID_IAccessible)
    If @error Then Return SetError(-1,@error,0)
    If $bRetAsPtr Then $sType='ptr*'
    $pGUID=DllStructGetPtr($stGUID)
    $aRet=DllCall($hOLEACC,"int","AccessibleObjectFromWindow","hwnd",$hWnd,"dword",$iObjectID,"ptr",DllStructGetPtr($stGUID),$sType,0)
    If @error Then Return SetError(2,@error,0)
    If $aRet[0] Then Return SetError(3,$aRet[0],0)
    Return $aRet[4]
EndFunc   ;==>_AccessibleObjectFromWindow

Local $hWnd=WinGetHandle("[REGEXPCLASS:(Explore|Cabinet)WClass]")

Local $oIAccessible=_AccessibleObjectFromWindow($hWnd)

ConsoleWrite("Name:"&$oIAccessible.accName(0)&@CRLF)

;~ HRESULT accLocation([out] int* pxLeft, [out] int* pyTop, [out] int* pcxWidth, [out] int* pcyHeight, [in,optional] VARIANT varChild );

Local $iX1,$iY1,$iXWidth,$iYHeight
$oIAccessible.accLocation($iX1,$iY1,$iXWidth,$iYHeight,0)

ConsoleWrite("X1:"&$iX1&", Y1:"&$iY1&", Width:"&$iXWidth&", Height:"&$iYHeight&@CRLF)

There's also some other members that fail to work under AutoIt 3.3.6.1, which is why I use AutoItObject to get further info. accSelection is one of the tricky methods that can return either an IEnumVariant interface, or just one item.

  • Administrators
Posted

Thanks, that confirms that it's even more broken than I thought.


 

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
×
×
  • Create New...