当前位置: 首页 > news >正文

【Delphi】中通过索引动态定位并创建对应窗体类实例

        

        在Delphi的开发中,经常会遇到创建很多相同的类或者相似的类的实例,期望通过索引动态的定位这些实例。  

       例如: delphi 中,有几个类似窗体,例如TTest_Form1,TTest_Form2,TTest_Form3,TTest_Form4等,期望通过索引能够找到对应的类,并创建实例,例如知道索引是3,那么就会用TTest_Form3.create创建对象实例。      

一、使用类引用数组(Class of TForm 或者具体类的类引用)

  • 步骤:

    1. 定义一个类型别名,表示窗体类的类引用。对于具体窗体可以使用通用的 TTest_Form 的子类型,或直接使用 class of TForm
    2. 将各个窗体类的类型放入一个数组,数组下标与你希望的“索引”对应。
    3. 根据索引取出类引用,然后调用 Create 构造对象(通常需要传入所有权所有者,如 Owner)。
    4. 可选:统一初始化、显示、释放等流程。
  • 代码示例(假设窗体都继承自 TForm,且构造参数为 Owner: TComponent):

type// 窗体类的通用类引用类型TFormClass = class of TForm;// 如果你确实只有 TTest_Form1..TTest_Form4 这几个// 也可以直接用 TFormClass,数组中存放它们的类引用
// 在某个单位的实现部分,或者一个工厂单元里
const// 注意下标从 0 开始,或者按你需要的起始下标调整// 将 1: TTest_Form1, 2: TTest_Form2, ...
varFormClasses: array of TFormClass;idx: Integer;NewForm: TForm;
begin// 初始化类引用数组(只需在程序启动阶段或需要时设置一次)SetLength(FormClasses, 4);FormClasses[0] := TTest_Form1;FormClasses[1] := TTest_Form2;FormClasses[2] := TTest_Form3;FormClasses[3] := TTest_Form4;// 假设索引为 3,想创建 TTest_Form3 的实例idx := 3 - 1; // 根据你使用的索引起始,若你希望索引直接对应数组下标,则不需要 -1if (idx >= 0) and (idx < Length(FormClasses)) and Assigned(FormClasses[idx]) thenbeginNewForm := FormClasses[idx].Create(Application); // 根据你的Owner 调整tryNewForm.Show; // 或者 ShowModal、BringToFront 等exceptNewForm.Free;raise;end;endelseraise Exception.Create('Invalid form index');
end;
  • 注意事项:
    • 管理 Owner:通常传 Application 或特定父窗体。若直接创建非可视窗体,确保正确管理生命周期。
    • 异常处理:创建失败时要释放资源,避免内存泄漏。
    • 界面释放:根据窗体的用途,选择 FreeFreeAndNil,以及是否需要在显示后再释放(如模态对话框在返回后自行释放,需自行管理)。

二、使用工厂函数表(更灵活、便于扩展)

  • 定义一个工厂函数类型,返回 TForm,并把各窗体的工厂函数放入数组。
  • 优点:若窗体需要自定义初始化参数,可以在工厂函数中完成。
typeTFormFactory = function: TForm of object;function CreateTestForm1: TForm;
beginResult := TTest_Form1.Create(Application);// 额外初始化
end;function CreateTestForm2: TForm;
beginResult := TTest_Form2.Create(Application);
end;// 依此类推
varFormFactories: array of TFormFactory;idx: Integer;FormObj: TForm;
beginSetLength(FormFactories, 4);FormFactories[0] := @CreateTestForm1;FormFactories[1] := @CreateTestForm2;// ...idx := 3 - 1;if (idx >= 0) and (idx < Length(FormFactories)) and Assigned(FormFactories[idx]) thenbeginFormObj := FormFactories[idx]();tryFormObj.Show;exceptFormObj.Free;raise;end;endelseraise Exception.Create('Invalid form index');
end;

三、使用 RTTI 动态创建

  • 如果你的窗体命名规则严格(如 TTest_Form1, TTest_Form2,...),也可以利用 RTTI 根据名称动态创建。
  • 但这会涉及到运行时类型信息和字符串拼接,容易出错且效率低。

示例(简化,实际使用需引入 RTTI 单元):

usesRtti, TypInfo;function CreateFormByIndex(Index: Integer; Owner: TComponent): TForm;
varCtx: TRttiContext;Typ: TRttiType;TypeName: string;FormInstance: TValue;
begin// 根据索引映射到类名,如 3 -> 'TTest_Form3'TypeName := Format('TTest_Form%d', [Index]);Typ := Ctx.FindType(TypeName);if Typ = nil thenraise Exception.Create('Unknown form type: ' + TypeName);if not (Typ is TRttiInstanceType) thenraise Exception.Create(TypeName + ' is not a class type');// 创建实例:需要知道构造参数,此处假设有无参构造且 Owner 通过参数传入// 由于 RTTI 创建无参构造较复杂,通常不推荐直接用 RTTI 动态创建窗体Result := nil; // 更复杂实现略
end;

总结与推荐

  • 最稳妥、简单且可维护的方式,是将窗体类引用放入一个数组(方法 A),或用工厂函数表(方法 B),按索引选择创建。这样编译期明确、性能好、容易调试。
  • 如果未来窗体数量极大且经常新增,方法 B(工厂函数表)会更易扩展,因为你只需添加一个新的工厂函数并更新数组。
  • 在使用时,注意:同一位置的索引应与数组下标或你的业务逻辑严格对应,若要从 1 开始索引,记得做相应的偏移处理。

http://www.dtcms.com/a/351026.html

相关文章:

  • CMake构建学习笔记20-iconv库的构建
  • MATLAB在生态环境数据处理与分析中的应用,生态系统模型构建与数值模拟等
  • 简述滚珠丝杆升降机的结构和原理
  • CSS 结构伪类选择器
  • 【BUG排查】调试瑞萨RH850F1KMS1时候随机出现进入到unused_isr
  • 一款基于 .NET 开源、功能强大的 Windows 搜索工具
  • GD32VW553-IOT开发板测评 搭建环境到电灯(QA分享)
  • 使用提供的 YAML 文件在 Conda 中创建环境
  • Conda的配置
  • 实时平台Flink热更新技术——实现不停机升级!
  • Caddy + CoreDNS 深度解析:从功能架构到性能优化实践(上)
  • webrtc音频QOS方法一.1(NetEQ之音频网络延时DelayManager计算补充)
  • 设计模式学习笔记-----抽象策略模式
  • 【Ansible】Ansible部署K8s集群--准备环境--配置网络
  • 主流的 AI Agent 开发框架
  • 论文阅读(四)| 软件运行时配置研究综述
  • 游戏玩家批量多开挂机如何选择:云手机还是模拟器
  • LabVIEW 场效应晶体管仿真实验平台
  • 工业自动化系统架构-(多动子磁悬浮生产流水线 规划调度执行与协调)
  • 从下载到运行:MySQL 详细安装配置完整教程
  • 【Vue3】Cesium实现卫星及无人机轨迹跟踪
  • 大模型入门实战 | 基于 YOLO 数据集微调 Qwen2.5-VL-3B-Instruct 的目标检测任务
  • 数字IC前端设计——DC综合篇(生成filelist.f)
  • ADB 安装教程:如何在 Windows、 Linux 上安装 Android Debug Bridge
  • Java数据结构速成【1】
  • 项目设计文档——爬虫项目(爬取天气预报)
  • Qt——界面美化 QSS
  • 无人机三维路径规划首选算法:RRT_
  • 基于大模型的智能占卜系统实战-Qwen-VL、RAG、FastAPI
  • 【算法--链表题1】2. 两数相加:通俗详解