调用Invoke,如何传多个参数?

sunmz_wjxy 2007-09-21 04:42:51
现在有一个COM接口,此接口有5个参数,但不能直接调用它,因为得不到此接口的IID,只所以只能使用Invoke,但不知道如何传这5个参数,请高手指点.
...全文
1379 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
super_admi 2012-01-30
  • 打赏
  • 举报
回复
#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 marker;
va_start(marker, 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(marker, 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(marker);

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;
}
super_admi 2012-01-30
  • 打赏
  • 举报
回复
#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 marker;
va_start(marker, 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(marker, 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(marker);

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;
}
sunmz_wjxy 2007-11-22
  • 打赏
  • 举报
回复
能否给于帮助?
sunmz_wjxy 2007-10-23
  • 打赏
  • 举报
回复
sinkileu
能否说的详细点,谢谢!!!!
sinkileu 2007-10-16
  • 打赏
  • 举报
回复
VARIANTARG v[10];
v[0].vt = VT_I4, v[0].lVal = ...;
v[1].vt = ... , v[1].... = ...;
...

DISPPARAMS dispparam = {v, ...}
sunmz_wjxy 2007-10-09
  • 打赏
  • 举报
回复
能不能给个调用Add这个方法的dispatch的例子呀!!!!
谢谢!
manbaum 2007-10-08
  • 打赏
  • 举报
回复
看了楼主贴的IDL,这个接口不是dual-interface的。所以,只能通过dispatch接口来调用了。
hollyren 2007-10-05
  • 打赏
  • 举报
回复
但从IDispatchPtr如何得到DocumentPropertiesPtr指针呢?
----------
如果是dual-interface,可以直接强制转成DocumentPropertiesPtr。


智能指针重载了运算符=,只要把IDispatchPtr的值赋给DocumentPropertiesPtr定义的变量,它自然就回调用运算符=,这样就能得到DocumentPropertiesPtr的指针了
sunmz_wjxy 2007-09-29
  • 打赏
  • 举报
回复
请问有没有例子参考一下.谢谢!
superarhow 2007-09-28
  • 打赏
  • 举报
回复
参数要倒着传~~
sunmz_wjxy 2007-09-28
  • 打赏
  • 举报
回复
[
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方法
manbaum 2007-09-25
  • 打赏
  • 举报
回复
你给的是vb的接口吧,需要idl的定义才行。
sunmz_wjxy 2007-09-25
  • 打赏
  • 举报
回复
我调用的就是Add方法,它的定义如下
Function Add(Name As String, LinkToContent As Boolean, [Type], [Value], [LinkSource]) As DocumentProperty
Office.DocumentProperties 的成员
sunmz_wjxy 2007-09-24
  • 打赏
  • 举报
回复
没有什么错误提示,就是添加属性不成功.
有没有调用Invoke传多个参数的例子?
manbaum 2007-09-24
  • 打赏
  • 举报
回复
可以给出你调的这个接口方法的完整IDL么?要不我没法去判断你给的参数到底对不对啊。
manbaum 2007-09-21
  • 打赏
  • 举报
回复
但从IDispatchPtr如何得到DocumentPropertiesPtr指针呢?
----------
如果是dual-interface,可以直接强制转成DocumentPropertiesPtr。
manbaum 2007-09-21
  • 打赏
  • 举报
回复
IDispatch接口(的invoke方法)一般是给脚本解释器一类的程序用的,如果你的com对象支持双接口(dual-interface)的话,最好转成方法调用的方式来调它,这样比较简单。如果不支持双接口,那只能用invoke了。

invoke调用的时候参数传递挺麻烦的。看样子好象你的参数传递不对。

你说的不成功有什么错误提示么?
sunmz_wjxy 2007-09-21
  • 打赏
  • 举报
回复
而且我也不知道如何获得此接口的IID,
IDispatchPtr Properties = pWordDoc->GetCustomDocumentProperties();
得到此接口的IDispatchPtr ,但从IDispatchPtr如何得到DocumentPropertiesPtr指针呢?
直接查询也是空的,如果直接得是空的,不明白为什么?
所以只能使用Invoke
sunmz_wjxy 2007-09-21
  • 打赏
  • 举报
回复
hediant(何)
能不能给个具体的代码参考一下.
sunmz_wjxy 2007-09-21
  • 打赏
  • 举报
回复
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;
}
加载更多回复(2)

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧