delphi – 通过OLE调用Word CentimetersToPoints时出现未指定的
在Delphi(XE)中执行时,以下代码在CentimetersToPoint调用上因OLE 800040005“未指定”错误而失败,类似的VBS或VBA版本通过
var w : OleVariant; w := CreateOleObject('Word.Application'); w.Visible := true; Writeln(w.CentimetersToPoints(2.0)); FWIW类型库给出 / [id(0x00000173),helpcontext(0x09700173)] // single CentimetersToPoints([in] single Centimeters); 默认情况下,Delphi只将浮动值传递为Double,因此我尝试直接调用IDispatch.Invoke并将参数作为VT_R4传递,但没有更好的结果. 编辑:VB版本工作(保存为.vbs) set w = CreateObject("Word.Application") w.Visible = true msgbox w.CentimetersToPoints(2.0) 什么可能出错的其他建议? 解决方法
我最初怀疑问题是函数期望Single和Delphi将你的float转换为其他东西.当我在调试器中跟踪它时,我发现传递给Invoke的变体是VType的varCurrency,货币值是2.如何发生这种情况我不确定!
正如我发现的那样,回答这个question,将单个精度浮点数变成一个变量是非常棘手的.我最初怀疑你可以使用我在那里提出的解决方案来解决你的问题. function VarFromSingle(const Value: Single): Variant; begin VarClear(Result); TVarData(Result).VSingle := Value; TVarData(Result).VType := varSingle; end; .... w := CreateOleObject('Word.Application'); w.Visible := true; Writeln(w.CentimetersToPoints(VarFromSingle(2.0))); 但是,由于我还不了解的原因,这也以同样的方式失败了. 像你一样,我尝试使用IDispatch.Invoke调用该函数.这就是我想出的: program SO16279098; {$APPTYPE CONSOLE} uses SysUtils,Variants,Windows,ComObj,ActiveX; function VarFromSingle(const Value: Single): Variant; begin VarClear(Result); TVarData(Result).VSingle := Value; TVarData(Result).VType := varSingle; end; var WordApp: Variant; param: Variant; retval: HRESULT; disp: IDispatch; Params: TDispParams; result: Variant; begin try CoInitialize(nil); WordApp := CreateOleObject('Word.Application'); disp := IDispatch(WordApp); param := VarFromSingle(2.0); Params := Default(TDispParams); Params.cArgs := 1; Params.rgvarg := @param; retval := disp.Invoke( 371,//CentimetersToPoints GUID_NULL,LOCALE_USER_DEFAULT,DISPATCH_METHOD,Params,@Result,nil,nil ); // retval = E_FAIL Params := Default(TDispParams); retval := disp.Invoke( 404,//ProductCode GUID_NULL,nil ); // retval = S_OK except on E: Exception do Writeln(E.ClassName,': ',E.Message); end; Readln; end. 我无法以这种方式调用CentimetersToPoints,但可以调用ProductCode函数. 要添加到您的成功/失败指标集合中,当我使用PowerShell调用CentimetersToPoints函数时,我获得了成功.当我使用Python的win32com.client调用时,我得到了E_FAIL. 显然我们缺少一些特殊的魔法成分.似乎所有MS工具都知道这种魔力. 我得出结论,使用Delphi中实现的变体分派调用CentimetersToPoints是不可能的.无论魔法是什么,它都不知道魔法. 显然可以在IDispatch上调用Invoke并成功.我们可以说,因为其他环境设法这样做.所以,我不知道的是失踪的魔法是什么. 如果你可以使用早期绑定的COM,那么你可以回避这个问题: Writeln((IDispatch(w) as WordApplication).CentimetersToPoints(2.0)); 好的,在0700的help中,我有一些Delphi代码可以调用这个函数: program SO16279098; {$APPTYPE CONSOLE} uses SysUtils,DISPATCH_METHOD or DISPATCH_PROPERTYGET,nil ); Writeln(Result); except on E: Exception do Writeln(E.ClassName,E.Message); end; Readln; end. 由于未知原因,您需要包括DISPATCH_PROPERTYGET以及DISPATCH_METHOD. question that I asked可能使这个问题重复.所以,我投票结束. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |