调用Invoke,如何传多个参数? 现在有一个COM接口,此接口有5个参数,但不能直接调用它,因为得不到此接口的IID,只所以只能使用Invoke,但不知道如何传这5个参数,请高手指点. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 不知你为何不能获得IID的接口,不过要用IDispatchImp::Invoke进行调用参数设计一般使用如下的模式:1、构造一个结构体;2、在结构体中包含你所需要传送的5个变量;3、创建结构体的实例和指针,把指针赋值给DISPPARAMS* pdispparams……在COM的服务端和调用端都调用这个结构,并对结构体进行操作。 VC调用COM接口,此接口有5个参数,只能使用Invoke调.不知道如何调,以下是我的代码,调用不成功.HRESULT CWriteProperty::CallAddMethod(IDispatchPtr pDisp,VARIANT rgvargName,VARIANT rgvargValue){ VARIANT vLinkToContent,vPropertyType; vLinkToContent.vt = VT_BOOL; vLinkToContent.boolVal = VARIANT_FALSE; vPropertyType.vt = VT_I2; vPropertyType.intVal = msoPropertyTypeString; DISPID dispid; DISPID dispdNamed = DISPATCH_METHOD; DISPPARAMS dispparamsNoArgs = {NULL,NULL,0,0}; dispparamsNoArgs.cArgs = 5; dispparamsNoArgs.rgvarg[0] = rgvargName; dispparamsNoArgs.rgvarg[1] = vLinkToContent; dispparamsNoArgs.rgvarg[2] = vPropertyType; dispparamsNoArgs.rgvarg[3] = rgvargValue;// dispparamsNoArgs.rgvarg[4] = NULL; dispparamsNoArgs.cNamedArgs = 1; dispparamsNoArgs.rgdispidNamedArgs = &dispdNamed;// dispparamsNoArgs[1].cArgs = 1;// dispparamsNoArgs[1].rgvarg = &vLinkToContent;// dispparamsNoArgs[1].cNamedArgs = 1;// dispparamsNoArgs[1].rgdispidNamedArgs = &dispdNamed;//// dispparamsNoArgs[2].cArgs = 1;// dispparamsNoArgs[2].rgvarg = &vPropertyType;// dispparamsNoArgs[2].cNamedArgs = 1;// dispparamsNoArgs[2].rgdispidNamedArgs = &dispdNamed;//// dispparamsNoArgs[3].cArgs = 1;// dispparamsNoArgs[3].rgvarg = rgvargValue;// dispparamsNoArgs[3].cNamedArgs = 1;// dispparamsNoArgs[3].rgdispidNamedArgs = &dispdNamed;//// dispparamsNoArgs[4].cArgs = 0;// dispparamsNoArgs[4].rgvarg = NULL;// dispparamsNoArgs[4].cNamedArgs = 0;// dispparamsNoArgs[4].rgdispidNamedArgs = NULL; BSTR bstrMember(L"Add"); // Code omitted for brevity. HRESULT hresult = pDisp->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid); hresult = pDisp->Invoke( dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, NULL, NULL, NULL); return hresult;} hediant(何)能不能给个具体的代码参考一下. 而且我也不知道如何获得此接口的IID,IDispatchPtr Properties = pWordDoc->GetCustomDocumentProperties();得到此接口的IDispatchPtr ,但从IDispatchPtr如何得到DocumentPropertiesPtr指针呢?直接查询也是空的,如果直接得是空的,不明白为什么?所以只能使用Invoke IDispatch接口(的invoke方法)一般是给脚本解释器一类的程序用的,如果你的com对象支持双接口(dual-interface)的话,最好转成方法调用的方式来调它,这样比较简单。如果不支持双接口,那只能用invoke了。invoke调用的时候参数传递挺麻烦的。看样子好象你的参数传递不对。你说的不成功有什么错误提示么? 但从IDispatchPtr如何得到DocumentPropertiesPtr指针呢?----------如果是dual-interface,可以直接强制转成DocumentPropertiesPtr。 没有什么错误提示,就是添加属性不成功.有没有调用Invoke传多个参数的例子? 可以给出你调的这个接口方法的完整IDL么?要不我没法去判断你给的参数到底对不对啊。 我调用的就是Add方法,它的定义如下Function Add(Name As String, LinkToContent As Boolean, [Type], [Value], [LinkSource]) As DocumentProperty Office.DocumentProperties 的成员 你给的是vb的接口吧,需要idl的定义才行。 [ odl, uuid(2DF8D04D-5BFA-101B-BDE5-00AA0044DE52), helpcontext(0x0003d09a)]interface DocumentProperties : IDispatch { [propget, helpcontext(0x0003d09b)] IDispatch* _stdcall Parent(); [propget, helpcontext(0x0003d09c)] HRESULT _stdcall Item( [in] VARIANT Index, [in, lcid] long lcid, [out, retval] DocumentProperty** ppIDocProp); [propget, helpcontext(0x0003d09d)] HRESULT _stdcall Count([out, retval] long* pc); [helpcontext(0x0003d09e)] HRESULT _stdcall Add( [in] BSTR Name, [in] VARIANT_BOOL LinkToContent, [in, optional] VARIANT Type, [in, optional] VARIANT Value, [in, optional] VARIANT LinkSource, [in, lcid] long lcid, [out, retval] DocumentProperty** ppIDocProp); [propget] HRESULT _stdcall _NewEnum([out, retval] IUnknown** ppunkEnum); [propget, helpcontext(0x0003d0a1)] HRESULT _stdcall Application([out, retval] IDispatch** ppidisp); [propget, helpcontext(0x0003d0a2)] HRESULT _stdcall Creator([out, retval] long* plCreator);};就是要调用DocumentProperties这个接口的Add方法 但从IDispatchPtr如何得到DocumentPropertiesPtr指针呢? ---------- 如果是dual-interface,可以直接强制转成DocumentPropertiesPtr。 智能指针重载了运算符=,只要把IDispatchPtr的值赋给DocumentPropertiesPtr定义的变量,它自然就回调用运算符=,这样就能得到DocumentPropertiesPtr的指针了 看了楼主贴的IDL,这个接口不是dual-interface的。所以,只能通过dispatch接口来调用了。 能不能给个调用Add这个方法的dispatch的例子呀!!!!谢谢! VARIANTARG v[10];v[0].vt = VT_I4, v[0].lVal = ...;v[1].vt = ... , v[1].... = ...;...DISPPARAMS dispparam = {v, ...} sinkileu 能否说的详细点,谢谢!!!! #include "stdafx.h"#include <ole2.h>// // AutoWrap() - Automation helper function...// HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) { // Begin variable-argument list... va_list er; va_start(er, cArgs); if(!pDisp) { MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010); _exit(0); } // Variables used... DISPPARAMS dp = { NULL, NULL, 0, 0 }; DISPID dispidNamed = DISPID_PROPERTYPUT; DISPID dispID; HRESULT hr; char buf[200]; char szName[200]; // Convert down to ANSI WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL); // Get DISPID for name passed... hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID); if(FAILED(hr)) { sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err0x%08lx", szName, hr); MessageBox(NULL, buf, "AutoWrap()", 0x10010); _exit(0); return hr; } // Allocate memory for arguments... VARIANT *pArgs = new VARIANT[cArgs+1]; // Extract arguments... for(int i=0; i<cArgs; i++) { pArgs[i] = va_arg(er, VARIANT); } // Build DISPPARAMS dp.cArgs = cArgs; dp.rgvarg = pArgs; // Handle special-case for property-puts! if(autoType & DISPATCH_PROPERTYPUT) { dp.cNamedArgs = 1; dp.rgdispidNamedArgs = &dispidNamed; } // Make the call! hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL); if(FAILED(hr)) { sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr); MessageBox(NULL, buf, "AutoWrap()", 0x10010); _exit(0); return hr; } // End variable-argument section... va_end(er); delete [] pArgs; return hr;}int main(int argc, char* argv[]){ // Initialize COM for this thread... CoInitialize(NULL); // Get CLSID for Word.Application... CLSID clsid; HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid); if(FAILED(hr)) { ::MessageBox(NULL, "CLSIDFromProgID() failed", "Error", 0x10010); return -1; } // Start Word and get IDispatch... IDispatch *pWordApp; hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pWordApp); if(FAILED(hr)) { ::MessageBox(NULL, "Word not registered properly", "Error", 0x10010); return -2; } // Make Word visible { VARIANT x; x.vt = VT_I4; x.lVal = 1; AutoWrap(DISPATCH_PROPERTYPUT, NULL, pWordApp, L"Visible", 1, x); } // Get Documents collection IDispatch *pDocs; { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pWordApp, L"Documents", 0); pDocs = result.pdispVal; } // Call Documents.Open() to open C:\Doc1.doc IDispatch *pDoc; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"C:\\Doc1.doc"); AutoWrap(DISPATCH_METHOD, &result, pDocs, L"Open", 1, x); pDoc = result.pdispVal; SysFreeString(x.bstrVal); } // Get BuiltinDocumentProperties collection IDispatch *pProps; { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc, L"BuiltinDocumentProperties", 0); pProps = result.pdispVal; } // Get "Subject" from BuiltInDocumentProperties.Item("Subject") IDispatch *pPropSubject; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"Subject"); AutoWrap(DISPATCH_PROPERTYGET, &result, pProps, L"Item", 1, x); pPropSubject = result.pdispVal; SysFreeString(x.bstrVal); } // Get the Value of the Subject property and display it { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pPropSubject, L"Value", 0); char buf[512]; wcstombs(buf, result.bstrVal, 512); ::MessageBox(NULL, buf, "Subject", 0x10000); } // Set the Value of the Subject DocumentProperty { VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"This is my subject"); AutoWrap(DISPATCH_PROPERTYPUT, NULL, pPropSubject, L"Value", 1, x); ::MessageBox(NULL, "Subject property changed, examine document.", "Subject", 0x10000); SysFreeString(x.bstrVal); } // Get CustomDocumentProperties collection IDispatch *pCustomProps; { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc, L"CustomDocumentProperties", 0); pCustomProps = result.pdispVal; } // Add a new property named "CurrentYear" { VARIANT parm1, parm2, parm3, parm4; parm1.vt = VT_BSTR; parm1.bstrVal = SysAllocString(L"CurrentYear"); parm2.vt = VT_BOOL; parm2.boolVal = false; parm3.vt = VT_I4; parm3.lVal = 1; //msoPropertyTypeNumber = 1 parm4.vt = VT_I4; parm4.lVal = 1999; AutoWrap(DISPATCH_METHOD, NULL, pCustomProps, L"Add", 4, parm4, parm3, parm2, parm1); ::MessageBox(NULL, "Custom property added, examine document.", "Custom Property", 0x10000); SysFreeString(parm1.bstrVal); } // Get the custom property "CurrentYear" and delete it IDispatch *pCustomProp; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"CurrentYear"); AutoWrap(DISPATCH_PROPERTYGET, &result, pCustomProps, L"Item", 1, x); pCustomProp = result.pdispVal; SysFreeString(x.bstrVal); AutoWrap(DISPATCH_METHOD, NULL, pCustomProp, L"Delete", 0); ::MessageBox(NULL, "Custom property removed, examine document.", "Custom Property", 0x10000); } // Close the document without saving changes and quit Word { VARIANT x; x.vt = VT_BOOL; x.boolVal = false; AutoWrap(DISPATCH_METHOD, NULL, pDoc, L"Close", 1, x); AutoWrap(DISPATCH_METHOD, NULL, pWordApp, L"Quit", 0); } // Cleanup pCustomProp->Release(); pCustomProps->Release(); pPropSubject->Release(); pProps->Release(); pDoc->Release(); pDocs->Release(); pWordApp->Release(); // Uninitialize COM for this thread... CoUninitialize(); return 0;} #include "stdafx.h"#include <ole2.h>// // AutoWrap() - Automation helper function...// HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp, LPOLESTR ptName, int cArgs...) { // Begin variable-argument list... va_list er; va_start(er, cArgs); if(!pDisp) { MessageBox(NULL, "NULL IDispatch passed to AutoWrap()", "Error", 0x10010); _exit(0); } // Variables used... DISPPARAMS dp = { NULL, NULL, 0, 0 }; DISPID dispidNamed = DISPID_PROPERTYPUT; DISPID dispID; HRESULT hr; char buf[200]; char szName[200]; // Convert down to ANSI WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL); // Get DISPID for name passed... hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID); if(FAILED(hr)) { sprintf(buf, "IDispatch::GetIDsOfNames(\"%s\") failed w/err0x%08lx", szName, hr); MessageBox(NULL, buf, "AutoWrap()", 0x10010); _exit(0); return hr; } // Allocate memory for arguments... VARIANT *pArgs = new VARIANT[cArgs+1]; // Extract arguments... for(int i=0; i<cArgs; i++) { pArgs[i] = va_arg(er, VARIANT); } // Build DISPPARAMS dp.cArgs = cArgs; dp.rgvarg = pArgs; // Handle special-case for property-puts! if(autoType & DISPATCH_PROPERTYPUT) { dp.cNamedArgs = 1; dp.rgdispidNamedArgs = &dispidNamed; } // Make the call! hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL); if(FAILED(hr)) { sprintf(buf, "IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx", szName, dispID, hr); MessageBox(NULL, buf, "AutoWrap()", 0x10010); _exit(0); return hr; } // End variable-argument section... va_end(er); delete [] pArgs; return hr;}int main(int argc, char* argv[]){ // Initialize COM for this thread... CoInitialize(NULL); // Get CLSID for Word.Application... CLSID clsid; HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid); if(FAILED(hr)) { ::MessageBox(NULL, "CLSIDFromProgID() failed", "Error", 0x10010); return -1; } // Start Word and get IDispatch... IDispatch *pWordApp; hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pWordApp); if(FAILED(hr)) { ::MessageBox(NULL, "Word not registered properly", "Error", 0x10010); return -2; } // Make Word visible { VARIANT x; x.vt = VT_I4; x.lVal = 1; AutoWrap(DISPATCH_PROPERTYPUT, NULL, pWordApp, L"Visible", 1, x); } // Get Documents collection IDispatch *pDocs; { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pWordApp, L"Documents", 0); pDocs = result.pdispVal; } // Call Documents.Open() to open C:\Doc1.doc IDispatch *pDoc; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"C:\\Doc1.doc"); AutoWrap(DISPATCH_METHOD, &result, pDocs, L"Open", 1, x); pDoc = result.pdispVal; SysFreeString(x.bstrVal); } // Get BuiltinDocumentProperties collection IDispatch *pProps; { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc, L"BuiltinDocumentProperties", 0); pProps = result.pdispVal; } // Get "Subject" from BuiltInDocumentProperties.Item("Subject") IDispatch *pPropSubject; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"Subject"); AutoWrap(DISPATCH_PROPERTYGET, &result, pProps, L"Item", 1, x); pPropSubject = result.pdispVal; SysFreeString(x.bstrVal); } // Get the Value of the Subject property and display it { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pPropSubject, L"Value", 0); char buf[512]; wcstombs(buf, result.bstrVal, 512); ::MessageBox(NULL, buf, "Subject", 0x10000); } // Set the Value of the Subject DocumentProperty { VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"This is my subject"); AutoWrap(DISPATCH_PROPERTYPUT, NULL, pPropSubject, L"Value", 1, x); ::MessageBox(NULL, "Subject property changed, examine document.", "Subject", 0x10000); SysFreeString(x.bstrVal); } // Get CustomDocumentProperties collection IDispatch *pCustomProps; { VARIANT result; VariantInit(&result); AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc, L"CustomDocumentProperties", 0); pCustomProps = result.pdispVal; } // Add a new property named "CurrentYear" { VARIANT parm1, parm2, parm3, parm4; parm1.vt = VT_BSTR; parm1.bstrVal = SysAllocString(L"CurrentYear"); parm2.vt = VT_BOOL; parm2.boolVal = false; parm3.vt = VT_I4; parm3.lVal = 1; //msoPropertyTypeNumber = 1 parm4.vt = VT_I4; parm4.lVal = 1999; AutoWrap(DISPATCH_METHOD, NULL, pCustomProps, L"Add", 4, parm4, parm3, parm2, parm1); ::MessageBox(NULL, "Custom property added, examine document.", "Custom Property", 0x10000); SysFreeString(parm1.bstrVal); } // Get the custom property "CurrentYear" and delete it IDispatch *pCustomProp; { VARIANT result; VariantInit(&result); VARIANT x; x.vt = VT_BSTR; x.bstrVal = ::SysAllocString(L"CurrentYear"); AutoWrap(DISPATCH_PROPERTYGET, &result, pCustomProps, L"Item", 1, x); pCustomProp = result.pdispVal; SysFreeString(x.bstrVal); AutoWrap(DISPATCH_METHOD, NULL, pCustomProp, L"Delete", 0); ::MessageBox(NULL, "Custom property removed, examine document.", "Custom Property", 0x10000); } // Close the document without saving changes and quit Word { VARIANT x; x.vt = VT_BOOL; x.boolVal = false; AutoWrap(DISPATCH_METHOD, NULL, pDoc, L"Close", 1, x); AutoWrap(DISPATCH_METHOD, NULL, pWordApp, L"Quit", 0); } // Cleanup pCustomProp->Release(); pCustomProps->Release(); pPropSubject->Release(); pProps->Release(); pDoc->Release(); pDocs->Release(); pWordApp->Release(); // Uninitialize COM for this thread... CoUninitialize(); return 0;} 将文件信息显示在文档类里//如何??? 如何用IStream在word文档中写入信息? CList Ctrl 鼠标问题 学习问题 招聘---急 一个问题不知道怎么解决,请大家帮帮忙,先谢了! CEx04aView::CEx04aView():m_rectEllipse(0,0,400,200)是什么东东? 如何注册自己写的拷贝钩子? CreateProcess的问题 异常清除问题 急!急!一个关于TCP模式的socket在recv时的问题 (积分怎么就不长了)pcap_dump_open后捕捉的数据包文件是什么格式?
1、构造一个结构体;
2、在结构体中包含你所需要传送的5个变量;
3、创建结构体的实例和指针,把指针赋值给DISPPARAMS* pdispparams……在COM的服务端和调用端都调用这个结构,并对结构体进行操作。
不知道如何调,以下是我的代码,调用不成功.
HRESULT CWriteProperty::CallAddMethod(IDispatchPtr pDisp,VARIANT rgvargName,VARIANT rgvargValue)
{
VARIANT vLinkToContent,vPropertyType;
vLinkToContent.vt = VT_BOOL;
vLinkToContent.boolVal = VARIANT_FALSE;
vPropertyType.vt = VT_I2;
vPropertyType.intVal = msoPropertyTypeString; DISPID dispid;
DISPID dispdNamed = DISPATCH_METHOD;
DISPPARAMS dispparamsNoArgs = {NULL,NULL,0,0};
dispparamsNoArgs.cArgs = 5;
dispparamsNoArgs.rgvarg[0] = rgvargName;
dispparamsNoArgs.rgvarg[1] = vLinkToContent;
dispparamsNoArgs.rgvarg[2] = vPropertyType;
dispparamsNoArgs.rgvarg[3] = rgvargValue;
// dispparamsNoArgs.rgvarg[4] = NULL;
dispparamsNoArgs.cNamedArgs = 1;
dispparamsNoArgs.rgdispidNamedArgs = &dispdNamed;// dispparamsNoArgs[1].cArgs = 1;
// dispparamsNoArgs[1].rgvarg = &vLinkToContent;
// dispparamsNoArgs[1].cNamedArgs = 1;
// dispparamsNoArgs[1].rgdispidNamedArgs = &dispdNamed;
//
// dispparamsNoArgs[2].cArgs = 1;
// dispparamsNoArgs[2].rgvarg = &vPropertyType;
// dispparamsNoArgs[2].cNamedArgs = 1;
// dispparamsNoArgs[2].rgdispidNamedArgs = &dispdNamed;
//
// dispparamsNoArgs[3].cArgs = 1;
// dispparamsNoArgs[3].rgvarg = rgvargValue;
// dispparamsNoArgs[3].cNamedArgs = 1;
// dispparamsNoArgs[3].rgdispidNamedArgs = &dispdNamed;
//
// dispparamsNoArgs[4].cArgs = 0;
// dispparamsNoArgs[4].rgvarg = NULL;
// dispparamsNoArgs[4].cNamedArgs = 0;
// dispparamsNoArgs[4].rgdispidNamedArgs = NULL;
BSTR bstrMember(L"Add");
// Code omitted for brevity.
HRESULT hresult = pDisp->GetIDsOfNames(IID_NULL, &bstrMember, 1,
LOCALE_USER_DEFAULT, &dispid); hresult = pDisp->Invoke(
dispid,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
&dispparamsNoArgs, NULL, NULL, NULL);
return hresult;
}
能不能给个具体的代码参考一下.
IDispatchPtr Properties = pWordDoc->GetCustomDocumentProperties();
得到此接口的IDispatchPtr ,但从IDispatchPtr如何得到DocumentPropertiesPtr指针呢?
直接查询也是空的,如果直接得是空的,不明白为什么?
所以只能使用Invoke
----------
如果是dual-interface,可以直接强制转成DocumentPropertiesPtr。
有没有调用Invoke传多个参数的例子?
Function Add(Name As String, LinkToContent As Boolean, [Type], [Value], [LinkSource]) As DocumentProperty
Office.DocumentProperties 的成员
odl,
uuid(2DF8D04D-5BFA-101B-BDE5-00AA0044DE52),
helpcontext(0x0003d09a)
]
interface DocumentProperties : IDispatch {
[propget, helpcontext(0x0003d09b)]
IDispatch* _stdcall Parent();
[propget, helpcontext(0x0003d09c)]
HRESULT _stdcall Item(
[in] VARIANT Index,
[in, lcid] long lcid,
[out, retval] DocumentProperty** ppIDocProp);
[propget, helpcontext(0x0003d09d)]
HRESULT _stdcall Count([out, retval] long* pc);
[helpcontext(0x0003d09e)]
HRESULT _stdcall Add(
[in] BSTR Name,
[in] VARIANT_BOOL LinkToContent,
[in, optional] VARIANT Type,
[in, optional] VARIANT Value,
[in, optional] VARIANT LinkSource,
[in, lcid] long lcid,
[out, retval] DocumentProperty** ppIDocProp);
[propget]
HRESULT _stdcall _NewEnum([out, retval] IUnknown** ppunkEnum);
[propget, helpcontext(0x0003d0a1)]
HRESULT _stdcall Application([out, retval] IDispatch** ppidisp);
[propget, helpcontext(0x0003d0a2)]
HRESULT _stdcall Creator([out, retval] long* plCreator);
};
就是要调用DocumentProperties这个接口的Add方法
----------
如果是dual-interface,可以直接强制转成DocumentPropertiesPtr。
智能指针重载了运算符=,只要把IDispatchPtr的值赋给DocumentPropertiesPtr定义的变量,它自然就回调用运算符=,这样就能得到DocumentPropertiesPtr的指针了
谢谢!
v[0].vt = VT_I4, v[0].lVal = ...;
v[1].vt = ... , v[1].... = ...;
...DISPPARAMS dispparam = {v, ...}
能否说的详细点,谢谢!!!!
#include <ole2.h>//
// AutoWrap() - Automation helper function...
//
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp,
LPOLESTR ptName, int cArgs...)
{
// Begin variable-argument list...
va_list er;
va_start(er, cArgs); if(!pDisp) {
MessageBox(NULL, "NULL IDispatch passed to AutoWrap()",
"Error", 0x10010);
_exit(0);
} // Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed...
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT,
&dispID);
if(FAILED(hr)) {
sprintf(buf,
"IDispatch::GetIDsOfNames(\"%s\") failed w/err0x%08lx",
szName, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = new VARIANT[cArgs+1]; // Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(er, VARIANT);
}
// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType,
&dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
sprintf(buf,
"IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx",
szName, dispID, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// End variable-argument section...
va_end(er);
delete [] pArgs;
return hr;}int main(int argc, char* argv[])
{
// Initialize COM for this thread...
CoInitialize(NULL); // Get CLSID for Word.Application...
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid);
if(FAILED(hr)) {
::MessageBox(NULL, "CLSIDFromProgID() failed", "Error",
0x10010);
return -1;
} // Start Word and get IDispatch...
IDispatch *pWordApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,
IID_IDispatch, (void **)&pWordApp);
if(FAILED(hr)) {
::MessageBox(NULL, "Word not registered properly",
"Error", 0x10010);
return -2;
} // Make Word visible
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pWordApp, L"Visible", 1,
x);
} // Get Documents collection
IDispatch *pDocs;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pWordApp, L"Documents",
0); pDocs = result.pdispVal;
} // Call Documents.Open() to open C:\Doc1.doc
IDispatch *pDoc;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"C:\\Doc1.doc"); AutoWrap(DISPATCH_METHOD, &result, pDocs, L"Open", 1, x);
pDoc = result.pdispVal;
SysFreeString(x.bstrVal);
} // Get BuiltinDocumentProperties collection
IDispatch *pProps;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc,
L"BuiltinDocumentProperties", 0);
pProps = result.pdispVal;
} // Get "Subject" from BuiltInDocumentProperties.Item("Subject")
IDispatch *pPropSubject;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"Subject");
AutoWrap(DISPATCH_PROPERTYGET, &result, pProps, L"Item", 1, x);
pPropSubject = result.pdispVal;
SysFreeString(x.bstrVal);
} // Get the Value of the Subject property and display it
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pPropSubject, L"Value",
0);
char buf[512];
wcstombs(buf, result.bstrVal, 512);
::MessageBox(NULL, buf, "Subject", 0x10000);
} // Set the Value of the Subject DocumentProperty
{
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"This is my subject");
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pPropSubject, L"Value", 1,
x);
::MessageBox(NULL,
"Subject property changed, examine document.",
"Subject", 0x10000);
SysFreeString(x.bstrVal);
} // Get CustomDocumentProperties collection
IDispatch *pCustomProps;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc,
L"CustomDocumentProperties", 0);
pCustomProps = result.pdispVal;
} // Add a new property named "CurrentYear"
{
VARIANT parm1, parm2, parm3, parm4;
parm1.vt = VT_BSTR;
parm1.bstrVal = SysAllocString(L"CurrentYear");
parm2.vt = VT_BOOL;
parm2.boolVal = false;
parm3.vt = VT_I4;
parm3.lVal = 1; //msoPropertyTypeNumber = 1
parm4.vt = VT_I4;
parm4.lVal = 1999; AutoWrap(DISPATCH_METHOD, NULL, pCustomProps, L"Add", 4, parm4,
parm3, parm2, parm1);
::MessageBox(NULL, "Custom property added, examine document.",
"Custom Property", 0x10000);
SysFreeString(parm1.bstrVal);
} // Get the custom property "CurrentYear" and delete it
IDispatch *pCustomProp;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"CurrentYear");
AutoWrap(DISPATCH_PROPERTYGET, &result, pCustomProps, L"Item",
1, x);
pCustomProp = result.pdispVal;
SysFreeString(x.bstrVal);
AutoWrap(DISPATCH_METHOD, NULL, pCustomProp, L"Delete", 0);
::MessageBox(NULL,
"Custom property removed, examine document.",
"Custom Property", 0x10000);
}
// Close the document without saving changes and quit Word
{
VARIANT x;
x.vt = VT_BOOL;
x.boolVal = false;
AutoWrap(DISPATCH_METHOD, NULL, pDoc, L"Close", 1, x);
AutoWrap(DISPATCH_METHOD, NULL, pWordApp, L"Quit", 0);
} // Cleanup
pCustomProp->Release();
pCustomProps->Release();
pPropSubject->Release();
pProps->Release();
pDoc->Release();
pDocs->Release();
pWordApp->Release();
// Uninitialize COM for this thread...
CoUninitialize(); return 0;
}
#include <ole2.h>//
// AutoWrap() - Automation helper function...
//
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp,
LPOLESTR ptName, int cArgs...)
{
// Begin variable-argument list...
va_list er;
va_start(er, cArgs); if(!pDisp) {
MessageBox(NULL, "NULL IDispatch passed to AutoWrap()",
"Error", 0x10010);
_exit(0);
} // Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed...
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT,
&dispID);
if(FAILED(hr)) {
sprintf(buf,
"IDispatch::GetIDsOfNames(\"%s\") failed w/err0x%08lx",
szName, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = new VARIANT[cArgs+1]; // Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(er, VARIANT);
}
// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType,
&dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
sprintf(buf,
"IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx",
szName, dispID, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// End variable-argument section...
va_end(er);
delete [] pArgs;
return hr;}int main(int argc, char* argv[])
{
// Initialize COM for this thread...
CoInitialize(NULL); // Get CLSID for Word.Application...
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid);
if(FAILED(hr)) {
::MessageBox(NULL, "CLSIDFromProgID() failed", "Error",
0x10010);
return -1;
} // Start Word and get IDispatch...
IDispatch *pWordApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,
IID_IDispatch, (void **)&pWordApp);
if(FAILED(hr)) {
::MessageBox(NULL, "Word not registered properly",
"Error", 0x10010);
return -2;
} // Make Word visible
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pWordApp, L"Visible", 1,
x);
} // Get Documents collection
IDispatch *pDocs;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pWordApp, L"Documents",
0); pDocs = result.pdispVal;
} // Call Documents.Open() to open C:\Doc1.doc
IDispatch *pDoc;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"C:\\Doc1.doc"); AutoWrap(DISPATCH_METHOD, &result, pDocs, L"Open", 1, x);
pDoc = result.pdispVal;
SysFreeString(x.bstrVal);
} // Get BuiltinDocumentProperties collection
IDispatch *pProps;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc,
L"BuiltinDocumentProperties", 0);
pProps = result.pdispVal;
} // Get "Subject" from BuiltInDocumentProperties.Item("Subject")
IDispatch *pPropSubject;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"Subject");
AutoWrap(DISPATCH_PROPERTYGET, &result, pProps, L"Item", 1, x);
pPropSubject = result.pdispVal;
SysFreeString(x.bstrVal);
} // Get the Value of the Subject property and display it
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pPropSubject, L"Value",
0);
char buf[512];
wcstombs(buf, result.bstrVal, 512);
::MessageBox(NULL, buf, "Subject", 0x10000);
} // Set the Value of the Subject DocumentProperty
{
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"This is my subject");
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pPropSubject, L"Value", 1,
x);
::MessageBox(NULL,
"Subject property changed, examine document.",
"Subject", 0x10000);
SysFreeString(x.bstrVal);
} // Get CustomDocumentProperties collection
IDispatch *pCustomProps;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc,
L"CustomDocumentProperties", 0);
pCustomProps = result.pdispVal;
} // Add a new property named "CurrentYear"
{
VARIANT parm1, parm2, parm3, parm4;
parm1.vt = VT_BSTR;
parm1.bstrVal = SysAllocString(L"CurrentYear");
parm2.vt = VT_BOOL;
parm2.boolVal = false;
parm3.vt = VT_I4;
parm3.lVal = 1; //msoPropertyTypeNumber = 1
parm4.vt = VT_I4;
parm4.lVal = 1999; AutoWrap(DISPATCH_METHOD, NULL, pCustomProps, L"Add", 4, parm4,
parm3, parm2, parm1);
::MessageBox(NULL, "Custom property added, examine document.",
"Custom Property", 0x10000);
SysFreeString(parm1.bstrVal);
} // Get the custom property "CurrentYear" and delete it
IDispatch *pCustomProp;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"CurrentYear");
AutoWrap(DISPATCH_PROPERTYGET, &result, pCustomProps, L"Item",
1, x);
pCustomProp = result.pdispVal;
SysFreeString(x.bstrVal);
AutoWrap(DISPATCH_METHOD, NULL, pCustomProp, L"Delete", 0);
::MessageBox(NULL,
"Custom property removed, examine document.",
"Custom Property", 0x10000);
}
// Close the document without saving changes and quit Word
{
VARIANT x;
x.vt = VT_BOOL;
x.boolVal = false;
AutoWrap(DISPATCH_METHOD, NULL, pDoc, L"Close", 1, x);
AutoWrap(DISPATCH_METHOD, NULL, pWordApp, L"Quit", 0);
} // Cleanup
pCustomProp->Release();
pCustomProps->Release();
pPropSubject->Release();
pProps->Release();
pDoc->Release();
pDocs->Release();
pWordApp->Release();
// Uninitialize COM for this thread...
CoUninitialize(); return 0;
}