首页  编辑  

IDispatch的方法和属性的动态调用

Tags: /超级猛料/COM、ActiveX,DDE/   Date Created:
IDispatch 的方法和属性的动态调用
How to dynamic to set or get property of a dispatch?
How to dynamic to invoke a method of dispatch by name?
By Kingron, 2006,版权所有,禁止转载
IDispatch的属性可以用以下两个过程存取:
use ComObj;
SetDispatchPropValue
GetDispatchPropValue
例如:
 WordApp := GetObject('Word.Application');
procedure TForm1.Button5Click(Sender: TObject);
begin
 SetDispatchPropValue(WordApp, 'Visible', not GetDispatchPropValue(WordApp, 'Visible'));
end;
下面的代码演示了如何来动态调用一个方法:
function DispatchMethodInvoke(Disp: IDispatch; const MethodName: string; Params: array of const;
    var VarResult: Variant): Boolean;
Var
    ArgErr: DWord;
    P: TDispParams;
    id: Integer;
    ExcepInfo: TExcepInfo;
    Resultat: HResult;
    N: Widestring;
    Args: array [0 .. 63] of TVariantArg;
    i: Integer;
    L: Integer;
    dispidName: Longint;
begin
    try
        N := StringToOleStr(MethodName);
        OleCheck(Disp.GetIDsOfNames(GUID_NULL, @N, 1, LOCALE_USER_DEFAULT, @id));
        FillChar(Args, SizeOf(Args), 0);
        FillChar(P, SizeOf(P), 0);
        L := High(Params);
        for i := Low(Args) to High(Args) do
        begin
            Args[i].vt := VT_ERROR;
            Args[i].scode := DISP_E_PARAMNOTFOUND;
        end;
        for i := High(Params) downto Low(Params) do
            case Params[i].VType of
                vtAnsiString:
                    begin
                        Args[L - i].vt := VT_BSTR;
                        Args[L - i].bstrVal := StringToOleStr(Params[i].VPChar);
                    end;
                vtBoolean:
                    begin
                        Args[L - i].vt := VT_BOOL;
                        Args[L - i].vbool := Params[i].VBoolean;
                    end;
                vtInteger:
                    begin
                        Args[L - i].vt := VT_INT;
                        Args[L - i].intVal := Params[i].VInteger;
                    end;
                vtVariant:
                    if VarIsEmptyParam(Params[i].VVariant^) then
                    begin
                        Args[L - i].vt := VT_ERROR;
                        Args[L - i].scode := DISP_E_PARAMNOTFOUND;
                    end
                    else
                    begin
                        Args[L - i].vt := VT_VARIANT;
                        Args[L - i].pvarVal := Params[i].VVariant;
                    end;
                /// ...
            else
                Args[L - i].vt := VT_ERROR;
                Args[L - i].scode := DISP_E_PARAMNOTFOUND;
            end;
        P.rgvarg := @Args;
        P.cArgs := Length(Params);
        P.cNamedArgs := 0;
        OleCheck(Disp.Invoke(id, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, P, @VarResult, @ExcepInfo, @ArgErr));
        Result := True;
    except
        Result := False;
    end;
end;
Demo:
var
 R : Variant;
/// Quit有三个参数!
DispatchMethodInvoke(WordApp, 'Quit', [True, EmptyParam, EmptyParam], R);
/// 下面的代码演示如何调用Open方法,Open有12参数
DispatchMethodInvoke(WordInterFace, 'Open', ['C:\Demo.doc'], R);