ComObjActive() [AHK_L 53+]

OLE로 등록되어 실행 중인 객체를 열람합니다.

ComObject := ComObjActive(CLSID)

매개변수나 반환 값에 건넬 유형 있는 값을 나타내는 객체를 만듭니다.

ParamObj := ComObject(VarType, Value , Flags)

비추천: 아래에 보여주는 사용법은 추천하지 않습니다. 앞으로는 사용이 불가능하거나 바뀔 수 있습니다.

COM 객체의 메쏘드를 호출할 때 선택적인 매개변수의 기본 값 대신에 사용할 객체를 만듭니다. [v1.1.12+]: This function is obsolete. Instead, simply write two consecutive commas, as in Obj.Method(1,,3)

ParamObj := ComObjMissing()

IDispatch 포인터를 객체에 싸 넣고 자동으로 AddRef를 호출합니다.

ComObject := ComObjEnwrap(DispPtr)
DispPtr := ComObjUnwrap(ComObject)

미래를 보장하는 코드를 작성하려면, 대신 다음과 같이 사용하십시오:

ComObject := ComObject(9, DispPtr, 1), ObjAddRef(DispPtr)
DispPtr := ComObjValue(ComObject), ObjAddRef(DispPtr)

매개변수

CLSID

CLSID 또는 사람이-읽을 수 있는 COM 객체의 Prog ID.

ComObject

객체 구문에 사용가능한 COM 객체.

VarType

값의 유형을 나타내는 정수. 유형 목록은 ComObjType()을 참조하십시오.

Value

포장할 값. 현재 오직 정수와 포인터 값만 지원합니다.

Flags

이 함수의 행위와 포장 객체의 행위에 영향을 주는 플래그; 아래 참조.

DispPtr

날 IDispatch 포인터.

Flags

Flag 효과
0

기본 행위. AddRef는 IUnknown과 IDispatch 포인터에 대하여 자동으로 호출됩니다. 그래서 호출자는 ObjRelease()를 사용하여 적절하게 포인터 사본을 놓아 주어야 합니다.

기본 행위는 앞으로 바뀔 수 있으므로, 인터페이스 포인터를 포장할 때 언제나 Flags1로 설정하기를 권장합니다. 그리고 필요하면 ObjAddRef()를 호출하기를 권장합니다.

1 IUnknown, IDispatch 또는 SAFEARRAY 포인터의 소유권을 획득합니다. AddRef는 호출되지 않습니다. 포장 객체에 SAFEARRAY가 들어 있으면 (VT_BYREF는 제외), 포장 객체가 해제될 때 SafeArrayDestroy가 자동으로 호출됩니다.

ByRef [v1.1.17+]

포장 객체의 VarType에 VT_BYREF (0x4000) 플래그가 들어 있으면, 빈 각괄호[]를 사용하여 참조된 값을 읽거나 쓸 수 있습니다.

참조를 생성할 때, Value는 반드시 주어진 유형의 값을 저장하기에 충분한 가용 능력이 있는 변수나 버퍼의 메모리 주소이어야 합니다. 예를 들어, 다음을 사용하면 VBScript 함수가 쓸 수 있는 변수를 만들 수 있습니다:

VarSetCapacity(var, 24, 0)
vref := ComObject(0x400C, &var)  ; 0x400C는 VT_BYREF와 VT_VARIANT의 조합입니다.

vref[] := "in value"
sc.Run("Example", vref)  ; sc는 반드시 아래의 예제와 같이 초기화되어야 합니다.
MsgBox % vref[]

Note that although any previous value is freed when a new value is assigned by vref[] or the COM method, the final value is not freed automatically. Freeing the value requires knowing which type it is. Because it is VT_VARIANT in this case, it can be freed by calling VariantClear with DllCall or by using a simpler method: assign an integer, such as vref[] := 0.

총평

현재 버전에서, "ComObj"로 시작하는 함수가 다른 COM 함수 중 하나와 일치하지 않으면 실제로는 ComObjActive를 호출합니다. 예를 들어, ComObjEnwrap(DispPtr)ComObjActive(DispPtr)는 모두 ComObject(DispPtr)와 동등합니다 (묵시적으로 VarType은 9입니다). 그렇지만, 이 행위는 앞으로 사용하지 못할 것입니다. 그래서 이 페이지에서 보여주는 바와 같이 ComObject()ComObjActive()만 사용하는 것이 제일 좋습니다.

If ComObjActive cannot retrieve an active object, it may throw an exception, exit the script or return an empty string, depending on the current ComObjError() setting and other factors.

IDispatch나 IUnknown 인터페이스 포인터를 포장하거나 열람하는 데 이 함수가 사용될 때, 기본 행위는 COM 객체의 참조 횟수를 늘리는 것입니다. 그러므로, 인터페이스 포인터는 더 이상 필요하지 않을 때 수동으로 해제해야 합니다. 포장 객체가 해제될 때, 그 안에 든 참조는 자동으로 해제됩니다.

알려진 한계: COM 객체가 포장될 때마다, 새 포장 객체가 생성됩니다. if (obj1 == obj2) 그리고 array[obj1] := value와 같은 비교와 할당은 같은 COM 객체를 포함하고 있을 지라도 두 개의 포장 객체를 유일한 것으로 취급합니다.

ComObjCreate(), ComObjGet(), ComObjConnect(), ComObjError(), ComObjFlags(), ObjAddRef() / ObjRelease(), ComObjQuery(), GetActiveObject (MSDN)

예제

ComObjUnwrap: 다음 참조 ComObjConnect().

VARIANT ByRef를 COM 함수에 건넵니다.

; 여는 말- ScriptControl은 32-비트 버전의 오토핫키를 요구합니다.
code =
(
Sub Example(Var)
    MsgBox Var
    Var = "out value!"
End Sub
)
sc := ComObjCreate("ScriptControl"), sc.Language := "VBScript", sc.AddCode(code)


; 예제: VARIANT ByRef를 COM 함수에 건넵니다.
var := ComVar()
var[] := "in value"  ; Use [] to assign a value.
sc.Run("Example", var.ref)  ; Pass the VT_BYREF ComObject (.ref).
MsgBox % var[]  ; Use [] to retrieve a value.

; The same thing again, but more direct:
VarSetCapacity(variant_buf, 24, 0)  ; Make a buffer big enough for a VARIANT.
var := ComObject(0x400C, &variant_buf)  ; Make a reference to a VARIANT.
var[] := "in value"
sc.Run("Example", var)  ; Pass the VT_BYREF ComObject itself, no [] or .ref.
MsgBox % var[]
; If a VARIANT contains a string or object, it must be explicitly freed
; by calling VariantClear or assigning a pure numeric value:
var[] := 0


; ComVar: 값을 ByRef로 건네는 데 사용할 수 있는 객체를 생성합니다.
;   ComVar[] 값을 열람합니다
;   ComVar[] := Val은 값을 설정합니다
;   ComVar.ref는 COM 함수에 건네기 위해 ByRef 객체를 열람합니다.
ComVar(Type := 0xC)
{
    static base := { __Get: Func("ComVarGet"), __Set: Func("ComVarSet")
        , __Delete: Func("ComVarDel") } ; For base, see Custom Objects.
    
    ; Create a new object based on base.
    cv := {base: base}
    
    ; Allocate memory for a VARIANT to hold our value. VARIANT is used even
    ; when Type != VT_VARIANT so that VariantClear can be used by __delete.
    cv.SetCapacity("buf", 24), ptr := cv.GetAddress("buf")
    NumPut(0, NumPut(0, ptr+0, "int64"), "int64")
    
    if (Type != 0xC) { ; Not VT_VARIANT.
        NumPut(Type, ptr+0, "ushort") ; Set the variant type for __delete.
        ptr += 8 ; Point to the actual value.
    }
    
    ; Create an object which can be used to pass the variable ByRef.
    cv.ref := ComObject(0x4000|Type, ptr)
    
    return cv
}

ComVarGet(cv, p*) { ; 스크립트가 미지의 필드에 접근하면 호출됩니다.
    if p.MaxIndex() = "" ; 이름/매개변수 없음. 즉, cv[]
        return cv.ref[]
}

ComVarSet(cv, v, p*) { ; 스크립트가 미지의 필드를 설정할 때 호출됩니다.
    if p.MaxIndex() = "" ; 이름/매개변수 없음. 즉, cv[]:=v
        return cv.ref[] := v
}

ComVarDel(cv) { ; 객체가 해제될 때 호출됩니다.
    ; Depending on type, this may be needed to free the value, if set.
    DllCall("oleaut32\VariantClear", "ptr", cv.GetAddress("buf"))
}