delphi – 通过OLE调用Word CentimetersToPoints时出现未指定的错误

delphi – 通过OLE调用Word CentimetersToPoints时出现未指定的错误,第1张

概述在Delphi(XE)中执行时,以下代码在CentimetersToPoint调用上因OLE 800040005“未指定错误而失败,类似的VBS或VBA版本通过 var w : OleVariant;w := CreateOleObject('Word.Application');w.Visible := true;Writeln(w.CentimetersToPoints(2.0)); 在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 = truemsgBox 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可能使这个问题重复.所以,我投票结束.

总结

以上是内存溢出为你收集整理的delphi – 通过OLE调用Word CentimetersToPoints时出现未指定的错误全部内容,希望文章能够帮你解决delphi – 通过OLE调用Word CentimetersToPoints时出现未指定的错误所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1237518.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存