Sign in to follow this  
Followers 0
Jon

Anyone know of a COM method that uses a byref?

13 posts in this topic

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?

Share this post


Link to post
Share on other sites



#2 ·  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

Share this post


Link to post
Share on other sites

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
);

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

LOL I meant that in For/Next.

Edit:

No one should try to write code that early in the morning.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

I tried to find something in my scripts but no luck.

So used Google and here is one promising link:

Calling a Method with Byref and Optional Arguments

http://msdn.microsoft.com/en-us/library/cc237584%28v=prot.10%29.aspx

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Is it just arrays that aren't implemented perhaps?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
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
Sign in to follow this  
Followers 0