【问题标题】:Delphi TForm OnCreate gets called multiple timesDelphi TForm OnCreate 被多次调用
【发布时间】:2012-04-30 02:15:29
【问题描述】:

希望我能体面地解释这个问题!

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

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

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

form 是我的 Delphi 库中的一个全局变量(可能有问题?)。我已经连接了MyFormOnCreate 事件来做一些有趣的事情,比如准备一系列我想要使用的东西。

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

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

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

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

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

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

我能想到的唯一另一件重要的事情是,如果我打印出Sender 的地址,它每次都不同,所以它会以某种方式再次被创建,但我'已经检查过我只调用了 MyForm.Create 一次。

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

【问题讨论】:

  • 这行不通。你有两个 VCL 实例。一个在您的 exe 中,一个在 DLL 中。将其全部静态链接到一个 exe 中。或者使用包。
  • 从放弃 OnCreate 逻辑开始,看看你是否可以让它工作。然后,将逻辑移至发布在 OnShow 处理程序上的 WM_USER 消息处理程序上的新函数。这样用户就可以尽早看到表单,并且可以看到正在发生的设置(没有延迟)。这将允许您将两个部分分开,其中一个错误将更容易识别。
  • 非常感谢大家的帮助!答案类似于@Remy Lebeau 的建议,并在他的回复下方的评论中详细说明。我真的很感谢大家的意见!我有点担心 David Heffernan 在那里的评论——我对所有这些 VCL 东西都是新手,所以如果其他事情变得疯狂,我会确保考虑如何将 VCL 实例保持为一个!

标签: windows delphi dll


【解决方案1】:

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

【讨论】:

  • 这与问题的结果非常接近。我昨晚很晚才发现它(今天早上?)。我用代码实例化了一个对象:my_obj := my_obj.Create 而不是my_obj := TMyClass.Create。愚蠢的错误。不幸的是,它显然是 both 有效的语法,并且在执行时没有导致错误/异常。结果,在对未初始化的变量调用该函数之后,就发生了各种疯狂的事情。切换到正确的语法解决了这个问题。非常感谢您的帮助!
【解决方案2】:

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

【讨论】:

  • 好建议。不幸的是,我检查了 Launch 调用只进行了一次,并且该变量在创建一次后没有设置回 nil
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-27
  • 2021-12-17
  • 1970-01-01
相关资源
最近更新 更多