4

我有一块硬件使用 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 类的对象?

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

4

1 回答 1

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;

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

编辑

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

于 2013-05-12T07:35:18.207 回答