【问题标题】:ActiveX controls with old Delphi versions带有旧 Delphi 版本的 ActiveX 控件
【发布时间】:2011-01-31 14:30:01
【问题描述】:

我正在测试一个基于已注册 .ocx 的非可视 ActiveX 控件 我使用提供的向导将其导入 Delphi。

然后,我简单地将生成的组件放在一个新的 VCL 应用程序的主窗体上。

在旧的 Delphi 版本(D5 和 D2007)下,当我启动应用程序时,这会引发 AV 在组件初始化期间。

使用Delphi 2009:没问题,应用程序启动顺利。

我的问题是:

在最近的 Delphi 版本中是否有已知的 ActiveX 管理增强功能? 能解释一下这个区别吗?

我是否可以怀疑 ActiveX 控件中的错误,或者我是否可以考虑 问题来自旧的 Delphi 版本?

我需要在 D2007 中使用这个组件(如果测试正常)。 你认为是否可以通过修改D2007生成的.tlb文件来纠正D2007下的AV问题(例如尝试使用D2009生成的)

PS:ActiveX 控件没有命名,因为我的问题是关于 Delphi 和 ActiveX 的一般问题,而不是关于特定 ActiveX 控件的问题。

编辑:
对于 D2007,在 Application.CreateForm(TForm1, Form1);
期间出现错误(访问冲突) 更具体地说,当创建 Olecontrol 时:

procedure TOleControl.CreateInstance;
var
  ClassFactory2: IClassFactory2;
  LicKeyStr: WideString;

  procedure LicenseCheck(Status: HResult; const Ident: string);
  begin
    if Status = CLASS_E_NOTLICENSED then
      raise EOleError.CreateFmt(Ident, [ClassName]);
    OleCheck(Status);
  end;

begin
  if not (csDesigning in ComponentState) and
    (FControlData^.LicenseKey <> nil) then
  begin
    // ON THE LINE BELOW : the call of CoGetClassObject raise an AV
    OleCheck(CoGetClassObject(FControlData^.ClassID, CLSCTX_INPROC_SERVER or
      CLSCTX_LOCAL_SERVER, nil, IClassFactory2, ClassFactory2));
    LicKeyStr := PWideChar(FControlData^.LicenseKey);
    LicenseCheck(ClassFactory2.CreateInstanceLic(nil, nil, IOleObject,
      LicKeyStr, FOleObject), SInvalidLicense);
  end else
    LicenseCheck(CoCreateInstance(FControlData^.ClassID, nil,
      CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, IOleObject,
      FOleObject), SNotLicensed);
end;

【问题讨论】:

  • 如果您告诉我们错误可能会有所帮助...
  • @Mef : OK 更多关于错误的信息。奇怪的是,与 D2009 TOleControl.CreateInstance(在 OleCtrls.pas 中)是完全相同的函数,但 CoGetClassObject 的调用不会引发 AV。

标签: delphi activex


【解决方案1】:

据我所知,Delphi 2009 中的 ActiveX/TLB 导入有重大改进(与 Unicode 支持有关)——这或许可以解释这一点。

根据我的个人经验,Delphi 7 和 Delphi 2007 多次无法导入一些 Windows 7 类型库(各种新界面与新任务栏一起工作),但 Delphi 2009 完全没有任何问题。

至于在早期版本中使用 Delphi 2009 生成的文件 - 请注意 Unicode 问题。另外,如果缺陷出现在 RTL 中也无济于事...尝试在 Delphi 2009 中制作一个包装器 ActiveX 并在 Delphi 2007 中使用它 - 这应该可以。

【讨论】:

  • 感谢您对体验的反馈。我用 D2009 的包装器构建尝试了你的想法,但得到了相同的 AV。我会考虑将我的项目转移到 D2009... 因为这似乎是拥有良好 ActiveX 处理能力的唯一方法。
  • 我也接受您的回答,因为这清楚地表明我的问题来自以前的 Delphi 版本中的错误/不完整的 ActiveX/tlb 管理。
【解决方案2】:

很抱歉在战斗结束后这么晚才介入(事实上是 5 年之后),但我在这个确切的问题上浪费了太多时间,以至于我想我应该分享我所看到的和所做的解决它: 2 台机器(win7 64 / win 8.1)相同的 delphi 7(相同的版本相同的构建),相同的 activeX(命名为 MapX),具有相同的 .lic 文件,其中包含由 59 个字符组成的密钥:

uQnZi2sFw22L0-MRa8pYX-1E2P8065-5N5M3459-3C934220-04969-6562

相同的导入产生 2 个略有不同的 TLB。

一个工作:(在win 8.1上)在程序TMap.InitControlData中包含这个:

const
  CLicenseKey: array[0..61] of Word = ( $0075, $0051, $006E, $005A, $0069, $0032, $0073, $0046, $0077, $0032, $0032
    , $004C, $0030, $002D, $004D, $0052, $0061, $0038, $0070, $0059, $0058
    , $002D, $0031, $0045, $0032, $0050, $0038, $0030, $0036, $0035, $002D
    , $0035, $004E, $0035, $004D, $0033, $0034, $0035, $0039, $002D, $0033
    , $0043, $0039, $0033, $0034, $0032, $0032, $0050, $0030, $002D, $004D
    , $0030, $0034, $0039, $0036, $0039, $002D, $0036, $0035, $0036, $0032
    , $0000);

转换为 61 个字符的键

uQnZi2sFw22L0-MRa8pYX-1E2P8065-5N5M3459-3C93422P0-M04969-6562

不起作用的 TLB(win 7 64)包含以下内容:

const
  CLicenseKey: array[0..2] of Word = ( $0050, $004D, $0000);

转换为 2 个字符的键

PM

用另一个替换一个 const 并重新编译组件解决了我的问题。我真的不知道发生了什么。我只知道 Import/TLB 生成了一个可以手动更正的错误 .pas 文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-09
    • 2012-07-19
    • 2013-02-08
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多