C++进行COM 自动化调用时的命名参数调用方法

C++进行COM 自动化调用时的命名参数调用方法

C++使用COM自动化组件时,通过获取IDispatch接口,然后通过Invoke方法对COM组件的方法进行调用。在对Office组件的编程中,我们会经常性的使用这一方法。
在VBA中,存在一种命名参数的调用法。如Word的Documents对象中的Open方法:
Documents.Open( FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format, Encoding, Visible, OpenConflictDocument, OpenAndRepair, DocumentDirection, NoEncodingDialog)
其中只有FileName参数为必须的参数,其他参数都为可选的参数。在进行调用时,VBA中可通过指定可选参数名称来向Documents传输任意的可选参数,如下
' 以只读方式打开文档 MyDoc.doc。

Sub  OpenDoc()
    Documents.Open FileName:
= " C:\MyFiles\MyDoc.doc " ReadOnly : = True
End Sub

那么,在C++中,我们应该如何进行这种调用?先看看Invoke方法的声明
HRESULT Invoke(  

  DISPID  dispIdMember,      

  REFIID  riid,              

  LCID  lcid,                

  WORD  wFlags,              

  DISPPARAMS FAR
*   pDispParams,  

  VARIANT FAR
*   pVarResult,  

  EXCEPINFO FAR
*   pExcepInfo,  

  unsigned 
int  FAR *   puArgErr  

);

其中的pDispParams用于方法的参数传递,声明如下
typedef  struct  FARSTRUCT tagDISPPARAMS{

VARIANTARG FAR
*  rgvarg; //  Array of arguments.

DISPID FAR
*  rgdispidNamedArgs;  //  Dispatch IDs of named arguments.

unsigned 
int  cArgs; //  Number of arguments.

unsigned 
int  cNamedArgs;  //  Number of named arguments.

} DISPPARAMS;
通过rgdispidNamedArgs可指定传入的命名参数,因此可以将上述VBA代码转化为下面的C++代码(这里使用了ATL),实现命名参数的调用
       CComPtr < Word::Documents >  qpDocuments;
        m_qpApplication
-> get_Documents( & qpDocuments);
            
        CComDispatchDriver qpDocsDisp 
=  qpDocuments;
        CComVariant varFilename(L
" C:\MyFiles\MyDoc.doc " );
        CComVariant varTrue(
true );
            
        CComVariant varDisp;
        DISPID dispids[
3 ];
        LPOLESTR  names[] 
=  {L " Open " , L " FileName " , L " ReadOnly " };
        hr 
=  qpDocsDisp -> GetIDsOfNames(IID_NULL, names,  3 , LOCALE_USER_DEFAULT, dispids);
        DISPPARAMS dispParams;
        dispParams.cArgs 
=   2 ;
        dispParams.cNamedArgs 
=   2 ;
        dispParams.rgdispidNamedArgs 
=   & dispids[ 1 ];
        VARIANT varParam[
2 ];
        ::VariantInit(
& varParam[ 0 ]);
        ::VariantInit(
& varParam[ 1 ]);
        varParam[
0 =  varFilename;
        varParam[
1 =  varTrue;
        dispParams.rgvarg 
=  varParam;
        hr 
=  qpDocsDisp -> Invoke(dispids[ 0 ], IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,  & dispParams,  & varDisp, NULL, NULL);
        

你可能感兴趣的:(C++进行COM 自动化调用时的命名参数调用方法)