ComObjQuery

Queries a COM object for an interface or service.

InterfacePointer := ComObjQuery(ComObject, SID, IID)

Parameters

ComObject

Type: Object or Integer

A COM wrapper object, an interface pointer, or an object with a Ptr property which returns an interface pointer.

IID

Type: String

An interface identifier (GUID) in the form "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".

SID

Type: String

A service identifier in the same form as IID. When omitting this parameter, also omit the comma.

Return Value

Type: ComObject

This function returns a COM wrapper object with the type VT_UNKNOWN (13).

Remarks

In its two-parameter mode, this function is equivalent to IUnknown::QueryInterface. When SID and IID are both specified, it internally queries for the IServiceProvider interface, then calls IServiceProvider::QueryService. In either case, the return value is either zero or a pointer to the requested interface. Generally this pointer must be released when the script is finished with it.

ComCall can be used to call native interface methods.

Related

ComCall, ComObjCreate, ComObjGet, ComObjActive

Examples

#1: Determine the class name of an object.

obj := ComObjCreate("Scripting.Dictionary")

MsgBox "Interface name: " ComObjType(obj, "name")

IID_IProvideClassInfo := "{B196B283-BAB4-101A-B69C-00AA00341D07}"

; Request the object's IProvideClassInfo interface.
try
    pci := ComObjQuery(obj, IID_IProvideClassInfo)
catch
{
    MsgBox "IProvideClassInfo interface not supported."
    return
}

; Call GetClassInfo to retrieve a pointer to the ITypeInfo interface.
ComCall(3, pci, "ptr*", ti := 0)

; Wrap ti to ensure automatic cleanup.
ti := ComObject(13, ti)

; Call GetDocumentation to get the object's full type name.
ComCall(12, ti, "int", -1, "ptr*", pname := 0, "ptr", 0, "ptr", 0, "ptr", 0)

; Convert the BSTR pointer to a usable string.
name := StrGet(pname, "UTF-16")

; Clean up.
DllCall("oleaut32\SysFreeString", "ptr", pname)
pci := ti := ""

; Display the type name!
MsgBox "Class name: " name

#2: Automate an existing Internet Explorer window.

sURL := "https://www.autohotkey.com/boards/"
if WebBrowser := GetWebBrowser()
    WebBrowser.Navigate(sURL)

GetWebBrowser()
{
    ; Get a raw pointer to the document object of the top-most IE window.
    static msg := DllCall("RegisterWindowMessage", "Str", "WM_HTML_GETOBJECT")
    lResult := SendMessage(msg, 0, 0, "Internet Explorer_Server1", "ahk_class IEFrame")
    if !lResult
        return  ; IE not found.
    static IID_IHTMLDocument2 := GUID("{332C4425-26CB-11D0-B483-00C04FD90119}")
    static VT_UNKNOWN := 13
    DllCall("oleacc\ObjectFromLresult", "Ptr", lResult
        , "Ptr", IID_IHTMLDocument2, "Ptr", 0
        , "Ptr*", pdoc := ComObject(VT_UNKNOWN, 0))
    
    ; Query for the WebBrowserApp service. In this particular case,
    ; the SID and IID are the same, but it isn't always this way.
    static IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
    static SID_SWebBrowserApp := IID_IWebBrowserApp
    pweb := ComObjQuery(pdoc, SID_SWebBrowserApp, IID_IWebBrowserApp)
    
    ; Return the WebBrowser object as IDispatch for usability.
    ; This works only because IWebBrowserApp is derived from IDispatch.
    ; pweb will release its ptr automatically, so AddRef to counter that.
    ObjAddRef(pweb.ptr)
    static VT_DISPATCH := 9
    return ComObject(VT_DISPATCH, pweb.ptr)
}

GUID(sGUID) ; Converts a string to a binary GUID and returns it in a Buffer.
{
    GUID := BufferAlloc(16, 0)
    if DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", GUID) < 0
        throw Exception("Invalid parameter #1", -1, sGUID)
    return GUID
}