You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi打开MDI子窗体触发Access Violation错误的解决咨询

问题分析与解决方案

你的代码核心错误有两个:

  1. Assigned(TSubjectForm)是错误用法——Assigned用于检查指针/对象实例是否有效,而TSubjectForm是类类型,不是实例指针,直接传入会触发内存访问错误;
  2. 变量Frm声明后未初始化,else分支直接访问会导致非法内存操作。

下面提供两种可靠的实现方式,避免重复打开MDI子窗体:


方法1:遍历已打开的MDI子窗体查找实例

通过遍历主窗体的MDIChildren集合,判断是否存在目标类型的子窗体实例,无需额外定义全局变量:

uses SubjectUnit;

procedure TMainForm.SubjectClick(Sender: TObject);
var
  i: Integer;
  Frm: TSubjectForm;
begin
  // 初始化Frm为nil,避免未定义内存访问
  Frm := nil;
  // 遍历所有已打开的MDI子窗体
  for i := 0 to MDIChildrenCount - 1 do
  begin
    if MDIChildren[i] is TSubjectForm then
    begin
      Frm := TSubjectForm(MDIChildren[i]);
      Break;
    end;
  end;

  if not Assigned(Frm) then
  begin
    // 不存在则创建新窗体
    Frm := TSubjectForm.Create(Self);
    Frm.Show;
  end
  else
  begin
    // 存在则激活并最大化
    Frm.BringToFront;
    Frm.WindowState := TWindowState.wsMaximized;
  end;
end;

方法2:用类变量保存窗体实例(更高效)

在子窗体单元中定义全局变量存储实例,避免遍历开销:

1. 修改SubjectUnit单元

unit SubjectUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TSubjectForm = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  SubjectForm: TSubjectForm; // 全局变量存储窗体实例

implementation

{$R *.dfm}

procedure TSubjectForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  SubjectForm := nil; // 窗体释放后清空变量,保证下次判断准确
end;

end.

2. 主窗体调用代码

uses SubjectUnit;

procedure TMainForm.SubjectClick(Sender: TObject);
begin
  if not Assigned(SubjectForm) then
  begin
    SubjectForm := TSubjectForm.Create(Self);
    SubjectForm.Show;
  end
  else
  begin
    SubjectForm.BringToFront;
    SubjectForm.WindowState := TWindowState.wsMaximized;
  end;
end;

内容的提问来源于stack exchange,提问作者Ivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:42:53