在运行时创建ActiveX组件会导致访问冲突

时间:2013-05-11 15:28:28

标签: delphi activex

我有一块硬件,使用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类中的错误?也许,有一种方法可以像应用程序那样欺骗和创建TMG17Motor类的对象,如果我通过在设计时删除窗体上的控件来避免使用Create(Self)?

P.S。我希望能够动态创建控件的原因是我想将硬件处理的代码移动到工作线程。

1 个答案:

答案 0 :(得分:5)

我努力下载该软件并查看问题所在。 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;

示例截图: enter image description here 您在问题中声明要将代码移动到工作线程,但这是一个可视控件,因此无法实现。尝试联系Thorlabs,看看他们是否有其他方法可以达到你想要的效果......

编辑

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