014.Delphi插件之QPlugins,MDI窗口
不知道为什么,这个DEMO编译出来报错,运行不了,在QDAC群里问了一下也没人响应。
效果如下

主程序代码如下
unit Frm_Main; interface uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.Menus,
QPlugins,
qplugins_params,
qplugins_formsvc,
qplugins_vcl_formsvc,
qplugins_loader_lib; { 注意使用 MDI 子窗体做为插件,宿主和插件都必需同时引用rtl/vcl运行时包 } type
TForm_Main = class(TForm)
MainMenu1: TMainMenu;
File1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure File1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
FOpenChildren: array of IQFormService;
procedure DoFormClosed(AForm: IQFormService; var Action: TCloseAction);
procedure DoFormFree(AForm: IQFormService);
public
{ Public declarations }
end; var
Form_Main: TForm_Main; implementation {$R *.dfm} procedure TForm_Main.DoFormClosed(AForm: IQFormService; var Action: TCloseAction);
var
I: Integer;
begin
// 方法1:设置Action为caFree,然后由DoFormFree事件来处理清理服务
// Action := caFree;
// 方法2:直接释放引用就可以,优点是不用处理 OnFree 事件了
for I := to High(FOpenChildren) do
begin
if FOpenChildren[I] = AForm then
begin
Delete(FOpenChildren, I, );
Break;
end;
end;
end; procedure TForm_Main.DoFormFree(AForm: IQFormService);
var
I: Integer;
begin
// 直接释放引用就可以
for I := to High(FOpenChildren) do
begin
if FOpenChildren[I] = AForm then
begin
Delete(FOpenChildren, I, );
Break;
end;
end;
end; // 菜单_新建
procedure TForm_Main.File1Click(Sender: TObject);
var
AService: IQFormService;
// 窗体事件
AEvents: TQFormEvents;
begin
if Supports(PluginsManager.ByPath('/Services/Forms/MDI/MDITest'), IQFormService, AService) then
begin
// 设置窗体事件
FillChar(AEvents, SizeOf(AEvents), );
// 替换窗体的关闭和释放事件
AEvents.OnClose := DoFormClosed;
AEvents.OnFree := DoFormFree;
AService.HookEvents(AEvents);
AService.Show;
// FOpenChildren数组长度+1,为了添加一个AService
SetLength(FOpenChildren, Length(FOpenChildren) + );
FOpenChildren[High(FOpenChildren)] := AService;
end;
end; procedure TForm_Main.FormClose(Sender: TObject; var Action: TCloseAction);
var
I: Integer;
AEvents: TQFormEvents;
begin
// 在直接关闭前,要先移除事件关联,否则在服务释放时,回调DoFormFree时会出错
FillChar(AEvents, SizeOf(AEvents), );
// 遍历移除替换的窗体事件
for I := to High(FOpenChildren) do
begin
FOpenChildren[I].HookEvents(AEvents);
end;
// 清空
SetLength(FOpenChildren, );
end; // 创建
procedure TForm_Main.FormCreate(Sender: TObject);
begin
with PluginsManager do
begin
// 加载同目录下dll文件
Loaders.Add(TQDLLLoader.Create(ExtractFilePath(Application.ExeName), '.dll'));
// 启动服务
Start;
end;
end; end.
DLL代码如下
unit Frm_Mdi; interface uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs; type
TForm_Mdi = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end; var
Form_Mdi: TForm_Mdi; implementation uses
QPlugins,
qplugins_vcl_formsvc;
{$R *.dfm} initialization // 注册一个单实例服务
RegisterFormService('/Services/Forms/MDI', 'MDITest', TForm_Mdi); finalization // 注销
UnregisterServices('/Services/Forms/MDI', ['MDITest']); end.
014.Delphi插件之QPlugins,MDI窗口的更多相关文章
- 015.Delphi插件之QPlugins,FMX插件窗口
内嵌FMX的插件窗口,效果还是很可以的.退出时,会报错,很诡异啊. 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messa ...
- 012.Delphi插件之QPlugins,多实例内嵌窗口服务
这个DEMO中主要是在DLL中建立了一个IDockableControl类,并在DLL的子类中写了具体的实现方法. 在主程序exe中,找到这个服务,然后调用DLL的内嵌方法,把DLL插件窗口内嵌到主程 ...
- 013.Delphi插件之QPlugins,模块化代码示例
这个DEMO的是一个定义了一个窗体插件接口,把其他窗口注册到这个窗体插件接口中.主程序运行起来,就遍历一下窗体插件接口,把每个窗体内嵌到对话框中 运行效果如下 主窗口代码如下 unit Frm_Mai ...
- 007.Delphi插件之QPlugins,插件的卸载和重新加载
效果图如下,可以反复卸载和重新加载.QPlugins这个插件,还没弄明白,摸索着跟着DEMO写 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows ...
- 005.Delphi插件之QPlugins,IQNotify通知
演示的界面如下,拖动滚动条,百分比圆和进度条也是会跟着动的 主程序的代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messages ...
- 004.Delphi插件之QPlugins,参数传递
界面如下 插件框架中大量使用了接口的东西,看的眼花缭乱,很多地方只做了申明,具体的实现是在另外的子类. DLL的代码如下 unit ParamTest; interface uses classes, ...
- 003.Delphi插件之QPlugins,菜单插件加强
相比上一篇的菜单插件,这个在创建和销毁时候,做了增强,同时做了2个菜单对应的窗口 unit MenuSvc; interface uses windows, classes, SysUtils, Gr ...
- 001.Delphi插件之QPlugins,一个最简单的插件
安装QPlugins里面的Demo,复制粘贴着写了一个最简单的插件,看看好不好用 EXE代码如下: unit Main_Frm; interface uses Winapi.Windows, Wina ...
- 011.Delphi插件之QPlugins,延时加载服务
这个DEMO是是把DLL插件的相关信息做成了一个配置文件,主程序加载这个配置文件,从而起到延时加载的作用 主程序代码如下 unit Frm_Main; interface uses Winapi.Wi ...
随机推荐
- GO常量/枚举
常量中的数据类型只可以是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: const identifier [type] = value 你可以省略类型说明符 [type],因为编 ...
- 吴裕雄--天生自然ORACLE数据库学习笔记:管理表空间和数据文件
col tablespace_name for a10 col file_name for a50 col bytes ,, select tablespace_name,file_name,byte ...
- 使用jquery select2实现下拉框搜索功能
由于公司后台系统下拉框数据量太多了,用户操作起来要不方便所以增加了下拉框里面一个搜索功能 1从官网下载jquery select2 下来 地址https://select2.github.io/ 2: ...
- for循环语句及批量创建用户!
1.for 语句结构for 变量名 in 取值列表do命令序列done ================================================================ ...
- JVM虚拟机内存溢出垃圾收集及类加载机制总结
1.Java内存区域与内存溢出异常 虚拟机栈:为虚拟机执行Java方法服务 本地方法栈:为虚拟机使用到的native方法服务. Java堆:是Java虚拟机所管理的内存中最大的一块,被所有线程共享的一 ...
- Day11 - L - 邂逅明下 HDU - 2897
当日遇到月,于是有了明.当我遇到了你,便成了侣.那天,日月相会,我见到了你.而且,大地失去了光辉,你我是否成侣?这注定是个凄美的故事.(以上是废话)小t和所有世俗的人们一样,期待那百年难遇的日食.驻足 ...
- C语言笔记 14_标准库&assert&ctype&errno&float&limits
C 标准库 <assert.h> 简介 C 标准库的 assert.h头文件提供了一个名为 assert 的宏,它可用于验证程序做出的假设,并在假设为假时输出诊断消息. 已定义的宏 ass ...
- python语言入门
1.python语言是一种高级的脚本语言,诞生于1991年. 2.python是目前主流的编程语言,具有超高的人气,是因为它是目前大数据与人工智能的语言基础,应用范围非常广泛. 3.python语言是 ...
- 2_05_MSSQL课程_查询_where,group by,having的区别以及内连接、案例练习
SQL查询顺序 select distinct/top ..._ (5) 投影 from_(1)找到表 where_ (2)过滤掉我们不需要的数据 group by_ (3)分组操作 h ...
- windows驱动开发-设备扩展
设备对象Device_Object记录通用设备信息,另外一些信息记录在设备扩展里,设备扩展由程序员自己定义,由程序员指定内容和大小,由I/O管理器创建,并保存在非分页内存中. 驱动程序中,尽量避免使用 ...