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 ...
随机推荐
- 数据库先系统与原理第三章笔记:数据库SQL查询语言
SQL概述 SQL发展 SQL特点 SQL查询基本概念 单表查询 投影查询 1.查询指定列: SELECT 列名1,列名2,列名3,.....FROM Table_Name; #查询全部列:SELEC ...
- SSH整合hibernate无法正常自动生成表
检查持久化类的属性和映射文件是否正确配置,比如date格式的属性最容易配置错误
- AT2827 最长上升子序列LIS(nlogn的DP优化)
题意翻译 给定一长度为n的数列,请在不改变原数列顺序的前提下,从中随机的取出一定数量的整数,并使这些整数构成单调上升序列. 输出这类单调上升序列的最大长度. 数据范围:1<=n<=10 ...
- 【转】路由转发过程的IP及MAC地址变化
A-----(B1-B2)-----(C1-C2)-------E 就假设拓扑图是这个样子吧,B1和B2是路由器B上的两个接口,C1和C2是路由器C上的两个接口,A和E是PC,由主机A向主机E发送数据 ...
- 1.WEB安全概述
一.WEB常见的安全性问题简介 XSS(Cross-Site Scripting):跨站脚本攻击漏洞 CSRF(Cross-site request forgery):跨站请求伪造 文件上传漏洞 SQ ...
- 【PAT甲级】1012 The Best Rank (25 分)
题意: 输入两个整数N,M(<=2000),接着分别输入N个学生的ID,C语言成绩,数学成绩和英语成绩. M次询问,每次输入学生ID,如果该ID不存在则输出N/A,存在则输出该学生排名最考前的一 ...
- JSTL中获取URL参数
使用JSTL时,URL会被隐含的对象param包裹起来,使用param.变量名,直接获取值 <body>hello:${param.name}</body> 依据此逻辑,在使用 ...
- Rcnn/Faster Rcnn/Faster Rcnn的理解
基于候选区域的目标检测器 1. 滑动窗口检测器 根据滑动窗口从图像中剪切图像块-->将剪切的图像块warp成固定大小-->cnn网络提取特征-->SVM和regressor进行分类 ...
- 「CSP」第一届提高组考后总结
「CSP」第一届提高组考后总结 问题分析+反思 成绩 心态 考前心态 考时心态 考后心态 方法 心灵鸡汤... 在学习了三年之后,我们信竞迎来了初中最后一次大考,也是第一次 CSPCSPCSP 考试. ...
- PHP中的异常知识
一.绪 首先明确一点:异常和错误不是一回事. 一个异常(Exception)是一个程序执行过程中出现的一个例外或是一个事件,它中断了正常指令的运行,跳转到其他程序模块继续执行. 基本格式: try { ...