Delphi TForm OnCreate被多次调用

时间:2012-04-30 02:15:29

标签: windows delphi dll

我希望我能够很好地解释这个问题!

我正在尝试将ReWire音频设备实现为Delphi .dll。如果您不知道ReWire是什么,请不要担心。重要的是我的代码编译成.dll,然后我从ReWire系统调用我的.dll来打开显示,检查显示是否打开,然后再关闭它。

当我接到启动电话时,我会执行以下操作:

  if not Assigned(form) then
    form := TMyForm.Create(nil);
  form.Show;

其中form是我的Delphi库中的全局变量(可能有问题吗?)。我已经联系了MyForm的{​​{1}}事件来做一些有趣的事情,比如准备一系列我想要使用的东西。

到目前为止一切都很好。我的表单中有一个小按钮,可以打开OnCreate。我发现只要该对话框关闭,TOpenDialog事件就会以我的形式再次触发!

我检查过OnCreate没有被调用,所以我不知道为什么再次调用OnDestroy

不幸的是我不确定哪些信息是相关的,但这是第一次调用堆栈(首次设置表单时):

First call stack

正如预期的那样,ReWire正在调用我的.dll来启动Panel应用程序,所以我创建了我的表单。太棒了,事情看起来不错。

然后在我的表单中,我打开一个小对话框,选择一个文件,然后进行一些操作。在左侧字段中,再次调用OnCreate,这是时间的调用堆栈:

Second call stack

这是一个疯狂的电话派对! Reaper(在底部)是我用来测试我的应用程序的ReWire主机,但我不知道堆栈跟踪内部发生了什么,因为它不是我的代码。突然间,当我认为事件不应该被调用时,因为OnCreate甚至没有被调用。

我能想到的另一个重要的事情是,如果我打印出OnDestroy的地址,每次都是不同,所以它会以某种方式再次获得Created或者其他东西,但是我已经检查过我只调用了MyForm.Create一次。

关于这种事情如何发生的任何想法?

2 个答案:

答案 0 :(得分:4)

在第一个堆栈跟踪中,OnCreate调用之前是对TCustomForm.Create()的调用,这是正确的行为。在第二个堆栈跟踪中,OnCreate调用之前会调用TObject.Create(),这是不正确的行为。这导致我认为按钮OnClick事件处理程序中的某些内容要么构造一个具有错误VMT的对象,要么通常会损坏内存并导致错误跳转到恰好被您的{占用的代码{1}}课程。无论哪种方式,请仔细检查TForm错误的逻辑。

答案 1 :(得分:1)

检查(任何)将表单变量设置为nil的位置。可能是它被设置为nil而没有释放它所指向的表单,因此下次调用启动代码时它会创建另一个表单实例。