不知道为什么,这个DEMO编译出来报错,运行不了,在QDAC群里问了一下也没人响应。

效果如下

主程序代码如下

  1. unit Frm_Main;
  2.  
  3. interface
  4.  
  5. uses
  6. Winapi.Windows,
  7. Winapi.Messages,
  8. System.SysUtils,
  9. System.Variants,
  10. System.Classes,
  11. Vcl.Graphics,
  12. Vcl.Controls,
  13. Vcl.Forms,
  14. Vcl.Dialogs,
  15. Vcl.Menus,
  16. QPlugins,
  17. qplugins_params,
  18. qplugins_formsvc,
  19. qplugins_vcl_formsvc,
  20. qplugins_loader_lib;
  21.  
  22. { 注意使用 MDI 子窗体做为插件,宿主和插件都必需同时引用rtl/vcl运行时包 }
  23.  
  24. type
  25. TForm_Main = class(TForm)
  26. MainMenu1: TMainMenu;
  27. File1: TMenuItem;
  28. procedure FormCreate(Sender: TObject);
  29. procedure File1Click(Sender: TObject);
  30. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  31. private
  32. { Private declarations }
  33. FOpenChildren: array of IQFormService;
  34. procedure DoFormClosed(AForm: IQFormService; var Action: TCloseAction);
  35. procedure DoFormFree(AForm: IQFormService);
  36. public
  37. { Public declarations }
  38. end;
  39.  
  40. var
  41. Form_Main: TForm_Main;
  42.  
  43. implementation
  44.  
  45. {$R *.dfm}
  46.  
  47. procedure TForm_Main.DoFormClosed(AForm: IQFormService; var Action: TCloseAction);
  48. var
  49. I: Integer;
  50. begin
  51. // 方法1:设置Action为caFree,然后由DoFormFree事件来处理清理服务
  52. // Action := caFree;
  53. // 方法2:直接释放引用就可以,优点是不用处理 OnFree 事件了
  54. for I := to High(FOpenChildren) do
  55. begin
  56. if FOpenChildren[I] = AForm then
  57. begin
  58. Delete(FOpenChildren, I, );
  59. Break;
  60. end;
  61. end;
  62. end;
  63.  
  64. procedure TForm_Main.DoFormFree(AForm: IQFormService);
  65. var
  66. I: Integer;
  67. begin
  68. // 直接释放引用就可以
  69. for I := to High(FOpenChildren) do
  70. begin
  71. if FOpenChildren[I] = AForm then
  72. begin
  73. Delete(FOpenChildren, I, );
  74. Break;
  75. end;
  76. end;
  77. end;
  78.  
  79. // 菜单_新建
  80. procedure TForm_Main.File1Click(Sender: TObject);
  81. var
  82. AService: IQFormService;
  83. // 窗体事件
  84. AEvents: TQFormEvents;
  85. begin
  86. if Supports(PluginsManager.ByPath('/Services/Forms/MDI/MDITest'), IQFormService, AService) then
  87. begin
  88. // 设置窗体事件
  89. FillChar(AEvents, SizeOf(AEvents), );
  90. // 替换窗体的关闭和释放事件
  91. AEvents.OnClose := DoFormClosed;
  92. AEvents.OnFree := DoFormFree;
  93. AService.HookEvents(AEvents);
  94. AService.Show;
  95. // FOpenChildren数组长度+1,为了添加一个AService
  96. SetLength(FOpenChildren, Length(FOpenChildren) + );
  97. FOpenChildren[High(FOpenChildren)] := AService;
  98. end;
  99. end;
  100.  
  101. procedure TForm_Main.FormClose(Sender: TObject; var Action: TCloseAction);
  102. var
  103. I: Integer;
  104. AEvents: TQFormEvents;
  105. begin
  106. // 在直接关闭前,要先移除事件关联,否则在服务释放时,回调DoFormFree时会出错
  107. FillChar(AEvents, SizeOf(AEvents), );
  108. // 遍历移除替换的窗体事件
  109. for I := to High(FOpenChildren) do
  110. begin
  111. FOpenChildren[I].HookEvents(AEvents);
  112. end;
  113. // 清空
  114. SetLength(FOpenChildren, );
  115. end;
  116.  
  117. // 创建
  118. procedure TForm_Main.FormCreate(Sender: TObject);
  119. begin
  120. with PluginsManager do
  121. begin
  122. // 加载同目录下dll文件
  123. Loaders.Add(TQDLLLoader.Create(ExtractFilePath(Application.ExeName), '.dll'));
  124. // 启动服务
  125. Start;
  126. end;
  127. end;
  128.  
  129. end.

DLL代码如下

  1. unit Frm_Mdi;
  2.  
  3. interface
  4.  
  5. uses
  6. Winapi.Windows,
  7. Winapi.Messages,
  8. System.SysUtils,
  9. System.Variants,
  10. System.Classes,
  11. Vcl.Graphics,
  12. Vcl.Controls,
  13. Vcl.Forms,
  14. Vcl.Dialogs;
  15.  
  16. type
  17. TForm_Mdi = class(TForm)
  18. private
  19. { Private declarations }
  20. public
  21. { Public declarations }
  22. end;
  23.  
  24. var
  25. Form_Mdi: TForm_Mdi;
  26.  
  27. implementation
  28.  
  29. uses
  30. QPlugins,
  31. qplugins_vcl_formsvc;
  32. {$R *.dfm}
  33.  
  34. initialization
  35.  
  36. // 注册一个单实例服务
  37. RegisterFormService('/Services/Forms/MDI', 'MDITest', TForm_Mdi);
  38.  
  39. finalization
  40.  
  41. // 注销
  42. UnregisterServices('/Services/Forms/MDI', ['MDITest']);
  43.  
  44. end.

014.Delphi插件之QPlugins,MDI窗口的更多相关文章

  1. 015.Delphi插件之QPlugins,FMX插件窗口

    内嵌FMX的插件窗口,效果还是很可以的.退出时,会报错,很诡异啊. 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messa ...

  2. 012.Delphi插件之QPlugins,多实例内嵌窗口服务

    这个DEMO中主要是在DLL中建立了一个IDockableControl类,并在DLL的子类中写了具体的实现方法. 在主程序exe中,找到这个服务,然后调用DLL的内嵌方法,把DLL插件窗口内嵌到主程 ...

  3. 013.Delphi插件之QPlugins,模块化代码示例

    这个DEMO的是一个定义了一个窗体插件接口,把其他窗口注册到这个窗体插件接口中.主程序运行起来,就遍历一下窗体插件接口,把每个窗体内嵌到对话框中 运行效果如下 主窗口代码如下 unit Frm_Mai ...

  4. 007.Delphi插件之QPlugins,插件的卸载和重新加载

    效果图如下,可以反复卸载和重新加载.QPlugins这个插件,还没弄明白,摸索着跟着DEMO写 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows ...

  5. 005.Delphi插件之QPlugins,IQNotify通知

    演示的界面如下,拖动滚动条,百分比圆和进度条也是会跟着动的 主程序的代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messages ...

  6. 004.Delphi插件之QPlugins,参数传递

    界面如下 插件框架中大量使用了接口的东西,看的眼花缭乱,很多地方只做了申明,具体的实现是在另外的子类. DLL的代码如下 unit ParamTest; interface uses classes, ...

  7. 003.Delphi插件之QPlugins,菜单插件加强

    相比上一篇的菜单插件,这个在创建和销毁时候,做了增强,同时做了2个菜单对应的窗口 unit MenuSvc; interface uses windows, classes, SysUtils, Gr ...

  8. 001.Delphi插件之QPlugins,一个最简单的插件

    安装QPlugins里面的Demo,复制粘贴着写了一个最简单的插件,看看好不好用 EXE代码如下: unit Main_Frm; interface uses Winapi.Windows, Wina ...

  9. 011.Delphi插件之QPlugins,延时加载服务

    这个DEMO是是把DLL插件的相关信息做成了一个配置文件,主程序加载这个配置文件,从而起到延时加载的作用 主程序代码如下 unit Frm_Main; interface uses Winapi.Wi ...

随机推荐

  1. 杭电2024 C语言合法标识符

    链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2024 开始真的对这题是一点头绪都没有,简直了.然后事实证明是我想多了,这题主要是把概念给弄清楚 ...

  2. mybaits requestMap与requestType,以及对应的注解

    有的时候不喜欢用xml配置文件,但是xml配置文件的开发使用简单,自己经常要用到: 因为代码维护的缘故,有的时候看别人的代码,可能存在大量的mappper文件,也不是你想用注解就用注解的: 下面我还是 ...

  3. Sping IOC容器

    Sping IOC容器 package servlet; import org.springframework.context.ApplicationContext; import org.sprin ...

  4. Linux命令:ifconfig命令

    ifconfig功能:配置网络接口,CentOS7最小化安装不包含此命令,需要安装net-tools包. ifconfig常见的用法: ifconfig :显示所有活动接口的相关信息 ifconfig ...

  5. Android。WebView加载UR请求使用Cookie储存User_Id记录用户是否登陆过

    1.WebView初始化的时候用倒如下代码: if (Build.VERSION.SDK_INT >= 21) { CookieManager.getInstance().setAcceptTh ...

  6. 《容器化.NET应用架构指南》脑图学习笔记(第一部分)

    一.关于这本官方“圣经” 作为.NET程序员,对于微软官方推动的架构示例总是特别关注,从PetShop到MusicStore再到eShopOnContainers,每一次关注,都会了解到业界最新的架构 ...

  7. 从零开始-建站前的准备之django数据库创建的问题

    稍微熟悉了一下django里面对于数据的操作,发现遇见了好多的问题. django对数据的操作是代码式的操作. 一开始在models里面开始为某个表创建参数,像username,password这样的 ...

  8. 记录:一次使用私有LoadBalance provider,工具metallb的故障排除

    使用metallb工具,目的是为私有环境下,不借助GRE或Azure等云商的LB, 通过metallb-system工具IP池给k8s service提供external-ip.但是,由于设置meta ...

  9. IntelliJ IDEA Debug模式启动项目

    导入项目,没有看到debug模式 点击 next  next next next

  10. JS中的原始类型和判断方法

    ECMAScript 中定义了 7 种原始类型: Boolean String Number Null Undefined Symbol(新定义) BigInt(新定义) 注意: 原始类型不包含 Ob ...