Delphi 触摸动态窗体时发生访问冲突?

Delphi 触摸动态窗体时发生访问冲突?,delphi,dynamic,Delphi,Dynamic,我正在动态创建一个窗体,但是关闭它的例程位于主窗体的单元中,因为它与主窗体(TSkype)上的控件关联。事件已SkypeAsyncSearchUsersFinished。当SkypeAsyncSearchUsersFinished例程完成时,我尝试将我的动态表单的ModalResult设置为mrOk。但是,这会产生访问冲突 这是搜索完成时激发的代码: if SIDList.Count = 0 then begin frmSearcher.tmrFadeOut.Enabled

我正在动态创建一个窗体,但是关闭它的例程位于主窗体的单元中,因为它与主窗体(TSkype)上的控件关联。事件已SkypeAsyncSearchUsersFinished。当SkypeAsyncSearchUsersFinished例程完成时,我尝试将我的动态表单的ModalResult设置为mrOk。但是,这会产生访问冲突

这是搜索完成时激发的代码:

   if SIDList.Count = 0 then
   begin
     frmSearcher.tmrFadeOut.Enabled := True;
   end;
我试着调试它,并在frmsarcher.tmrFadeOut上设置了一个断点。。。我走到下一行(例程结束),这时AV出现

tmrFadeOutTimer事件执行ModalResult:=mrOk

以下是我创建动态表单的方式:

Function ShowSearcher():Boolean;
Var
   dlg : TfrmSearcher;
Begin
  Result := False;
  dlg := TfrmSearcher.Create(Forms.Application);


  dlg.tmrFadeIn.Enabled := True;


    if dlg.ShowModal = mrOk then
         Begin
         // Do nothing here

         End;

  Result := True;
  dlg.Release;

End;
,我确信计时器只启用一次。:)

,我确信表单是“活动的”。)

实际上,如果我删除tmrFadeOut.Enabled代码,一切正常,但表单不会关闭。正在执行frmsarcher.ModalResult:=mrOk也会生成AV

如果您需要更多信息,我将添加它。:)


非常感谢!:)

由于您正在手动创建TfrmSearcher表单,请删除IDE生成的变量frmSearcher,修复您将遇到的编译错误,一切正常


您获得AV是因为frmSearcher为零。

由于您正在手动创建TfrmSearcher表单,请删除IDE生成的变量frmSearcher,修复您将获得的编译错误,您会没事的


获得AV是因为frmSearcher为零。

您正在将新的
TfrmSearcher
对象实例分配给本地
dlg
变量,其他方法无法访问该变量。您的其他例程正在尝试使用未赋值的
frmsarcher
变量访问该对话框。

您正在将新的
TfrmSearcher
对象实例赋值给其他方法无法访问的本地
dlg
变量。您的其他例程正在尝试使用未赋值的
frmsarcher
变量访问该对话框。

我之所以添加此变量作为答案,是因为我想格式化代码。这不是试图回答这个问题,我可能会在适当的时候删除,特别是如果我得到很多反对票(同行压力)

我想展示的是如何创建、显示和销毁表单。你是这样做的:

procedure ShowMyForm;
var
  Form: TMyForm;
begin
  Form := TMyForm.Create(nil);
  try
    Form.ShowModal;
  finally
    Form.Free;
  end;
end;
在代码中:

  • 无需将所有者传递给构造函数,因为您正在确定表单的生命周期
  • 函数的返回变量是无意义的,因为您总是返回
    True
    。唯一的故障模式是通过异常,但该函数没有返回值
  • 不要在你做的地方调用
    Release
    ,你想要的是普通的
    免费的
    。处理消息时调用
    Release
    ,希望在处理完队列中当前的任何消息后,表单立即消失

  • 我添加这个作为答案,因为我想格式化代码。这不是试图回答这个问题,我可能会在适当的时候删除,特别是如果我得到很多反对票(同行压力)

    我想展示的是如何创建、显示和销毁表单。你是这样做的:

    procedure ShowMyForm;
    var
      Form: TMyForm;
    begin
      Form := TMyForm.Create(nil);
      try
        Form.ShowModal;
      finally
        Form.Free;
      end;
    end;
    
    在代码中:

  • 无需将所有者传递给构造函数,因为您正在确定表单的生命周期
  • 函数的返回变量是无意义的,因为您总是返回
    True
    。唯一的故障模式是通过异常,但该函数没有返回值
  • 不要在你做的地方调用
    Release
    ,你想要的是普通的
    免费的
    。处理消息时调用
    Release
    ,希望在处理完队列中当前的任何消息后,表单立即消失

  • 你能把错误信息的确切文本发出去吗?这可能会有所帮助。类似于frmsarcher.tmrFadeOut.Enabled的代码:=True
    dlg.tmrFadeIn.Enabled:=True
    表示在
    TfrmSearcher
    之外,您了解该表单的内部结构。您不应该:在
    TfrmSearcher
    上创建一个属性或一组方法来封装
    TfrmSearcher
    @Mason的内部工作-这是一种访问冲突。错误代码取决于我是启用计时器还是设置ModalResult.:)@杰伦:是的,现在当你提到它的时候你能把错误信息的确切文本发出去吗?这可能会有所帮助。类似于frmsarcher.tmrFadeOut.Enabled的代码:=True
    dlg.tmrFadeIn.Enabled:=True
    表示在
    TfrmSearcher
    之外,您了解该表单的内部结构。您不应该:在
    TfrmSearcher
    上创建一个属性或一组方法来封装
    TfrmSearcher
    @Mason的内部工作-这是一种访问冲突。错误代码取决于我是启用计时器还是设置ModalResult.:)@杰伦:是的,现在当你提到它的时候即使这不是答案,我还是+1它,因为它对我是有帮助的。谢谢你,大卫!我之所以使用我发布的代码,是因为我通常在从表单传递和返回数据时使用该模板,比如在添加内容时。所以,当我来回传递一些数据(我需要知道模态结果是否为mrOk)时,我应该按照我的方式来做,但是当我只想显示一个表单时,我使用你的。对吗?@Jeff的分数是1和3,同样适用于你所说的情况。如果您需要从表单返回信息,例如用户是否单击了“确定”或“取消”,则在需要时将该信息传递回。通常认为,保留从未使用过的变量是一个坏主意。以后修改代码时很容易陷入陷阱,这也会使