我无法使用IDispatch.Invoke
调用具有浮点参数和浮点结果的函数。
这是一个最小的复制:
#include <atlbase.h> #include <comutil.h> int main(int argc, char* argv[]) { CoInitialize(NULL); CComPtr<IDispatch> wordapp; if (SUCCEEDED(wordapp.CoCreateInstance(L"Word.Application", NULL, CLSCTX_LOCAL_SERVER))) { CComVariant result; CComVariant centimeters((float)2.0); CComVariant retval = wordapp.Invoke1(L"CentimetersToPoints", ¢imeters, &result); } return 0; }
我正在使用ATL CComPtr
使事情更清洁。 但是这是IDispatch.Invoke
的一个非常宽松的包装。
当我运行这个,调用Invoke1
失败并返回E_FAIL
。
我怀疑这个问题与使用浮点参数和/或返回值有关。 如果我调用一个不使用这些值的函数,调用将成功:
CComVariant retval = wordapp.Invoke0(L"ProductCode", &result);
我注意到,如果我从VBS或从PowerShell调用函数,它会成功。 我假设他们都使用迟来的IDispatch
,所以这将表明,我正在尝试是至less有可能的。
那么,如何使用IDispatch
来调用这个函数呢?
那么,这是一个头痛的人。 这个“方法”的文档是非常误导性的,这不是一个方法。 它的行为更像一个索引属性,需要DISPATCH_METHOD | DISPATCH_PROPERTYGET标志。 CComPtr不支持,你需要手动旋转。 此代码工作:
CComVariant result; CComVariant centimeters((float)2.0); DISPID dispid; LPOLESTR name = L"CentimetersToPoints"; HRESULT hr = wordapp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); assert(SUCCEEDED(hr)); DISPPARAMS dispparams = { ¢imeters, NULL, 1, 0}; hr = wordapp->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD | DISPATCH_PROPERTYGET, &dispparams, &result, nullptr, nullptr); assert(SUCCEEDED(hr));