# ComObjQuery() [v1.0.96.00+]

Queries a COM object for an interface or service.

    InterfacePointer := ComObjQuery(ComObject, SID, IID)

## Parameters

ComObject

  A COM wrapper object or raw interface pointer.

IID

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

SID

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

## General 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.

## Related

ObjRelease(), ComObjCreate(), ComObjGet(), ComObjActive(), ComObjError()

## 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 a pointer to the object's IProvideClassInfo interface.
    if !(pci := ComObjQuery(obj, IID_IProvideClassInfo))
    {
        MsgBox IProvideClassInfo interface not supported.
        return
    }

    ; Call GetClassInfo to retrieve a pointer to the ITypeInfo interface.
    DllCall(vtable(pci, 3), "ptr", pci, "ptr*", ti)

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

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

    ; Release raw interface pointers.
    ObjRelease(ti)
    ObjRelease(pci)

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

    vtable(ptr, n) {
        ; NumGet(ptr+0) returns the address of the object's virtual function
        ; table (vtable for short). The remainder of the expression retrieves
        ; the address of the nth function's address from the vtable.
        return NumGet(NumGet(ptr+0), n*A_PtrSize)
    }

#2: Automate an existing Internet Explorer window.

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

    GetWebBrowser()
    {
        ; Get a raw pointer to the document object of the top-most IE window.
        static msg := DllCall("RegisterWindowMessage", "Str", "WM_HTML_GETOBJECT")
        SendMessage msg, 0, 0, Internet Explorer_Server1, ahk_class IEFrame
        if (ErrorLevel = "FAIL")
            return  ; IE not found.
        lResult := ErrorLevel
        DllCall("oleacc\ObjectFromLresult", "Ptr", lResult
            , "Ptr", GUID(IID_IHTMLDocument2,"{332C4425-26CB-11D0-B483-00C04FD90119}")
            , "Ptr", 0, "Ptr*", pdoc)

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

        ; Release the document object pointer.
        ObjRelease(pdoc)

        ; Return the WebBrowser object, wrapped for usability:
        static VT_DISPATCH := 9, F_OWNVALUE := 1
        return ComObject(VT_DISPATCH, pweb, F_OWNVALUE)
    }

    GUID(ByRef GUID, sGUID) ; Converts a string to a binary GUID and returns its address.
    {
        VarSetCapacity(GUID, 16, 0)
        return DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", &GUID) >= 0 ? &GUID : ""
    }