【问题标题】:Creating an ActiveX component at run-time leads to Access Violation在运行时创建 ActiveX 组件会导致访问冲突
【发布时间】:2013-05-11 15:28:28
【问题描述】:

我有一个使用 Delphi 中的 ActiveX 组件处理的硬件。如果我在设计期间将该组件放在表单上,​​一切正常。但是,如果我在运行时使用 Creat(Self) 动态创建它,则进一步执行方法会导致 mfc100.dll 中的访问冲突。代码很简单:

uses
  Windows, Messages, ...
  OleCtrls, MG17MotorLib_TLB; // <-- The latter is the hardware driver

type
  TForm1 = class(TForm)
    motorX: TMG17Motor;
    ...
  end;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  motorX := TMG17Motor.Create(Self);
  motorX.HWSerialNum := 94835472;
  motorX.StartCtrl; // <--- This causes AV in mfc100.dll
end;

TMG17Motor 类是 TOleControl 的后代,由硬件生产商提供。

我在动态创建 ActiveX 对象时犯了一个错误,还是看起来像是 TMG17Motor 类中的错误?也许,如果我通过在设计时删除表单上的控件来避免使用 Create(Self),是否有一种方法可以欺骗并以与应用程序相同的方式创建 TMG17Motor 类的对象?

附:我希望能够动态创建控件的原因是我想将用于硬件处理的代码移至工作线程。

【问题讨论】:

  • 控件有可能/很可能有一些依赖关系(例如,它希望有一个父属性集或类似的东西)。如果您有目标控件的源代码或符号,那么在调试器中查看具体触发 AV 的内容应该很简单。
  • 我会和供应商谈谈。 thorlabs.com/newgrouppage9.cfm?objectgroup_id=2419 另外,尝试转储 DFM 并将所有属性设置为与您在 DFM 中看到的完全相同。
  • @EricLaw:谢谢你的想法!我没有考虑依赖关系。将尝试朝那个方向看。
  • @Warren P:是的,我已经通知了 Thorlabs 这个问题。还没有回应。
  • 任何控件的设计时和运行时实例化之间最显着的区别之一是运行时创建绕过流系统,这意味着不会调用Loaded 方法。如果您有源代码,请检查您的 ActiveX 组件是否覆盖了 Loaded 方法。如果有,在创建组件之后和设置任何其他属性之前调用它可能会有所帮助。

标签: delphi activex


【解决方案1】:

我努力下载了软件,看看有什么问题。 看来 TMG17Motor 是一个视觉控制。所以你的问题来自你的组件没有父窗口。

修复很简单:

procedure TForm1.FormCreate(Sender: TObject);
begin
  motorX := TMG17Motor.Create(Self);
  motorX.Parent := Self; // <--- you need this!
  // set other properties...
  motorX.HWSerialNum := 94835472;
  motorX.Align := alclient;
  motorX.StartCtrl;
end;

示例截图: 您在问题中声明要将代码移动到工作线程,但这是一个可视控件,因此不可能。尝试联系 Thorlabs,看看他们是否有其他方法可以实现您的目标......

编辑

正如 David 在 cmets 中建议的那样,您可以尝试使用非 VCL 窗口和工作线程。 由于这是一个 ActiveX 对象,请确保在工作线程的 Execute 方法中调用 CoInitialize(nil)/CoUninitialize。

【讨论】:

  • +1 干得好。移动到工作线程应该没问题。在非 VCL 窗口中作为父对象。
  • @whosrdaddy:非常感谢!一个意想不到的解决方案,因为上面的行也发送了父级。
  • @David Heffernan:感谢您提供有关非 VCL 窗口的提示!我确信必须有一个解决方法!
  • 好的,我已经使用answer of Remy Lebeau 在工作线程内创建了一个 WinAPI 不可见窗口,并在该窗口内创建了 ActiveX 控件。我的工作线程在没有任何明显原因的情况下终止,直到我看到关于 CoInitialize(nil)/CoUninitialize 的最后一条评论。现在一切正常!谢谢!
猜你喜欢
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 2021-09-18
  • 2012-05-15
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多