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 ...
随机推荐
- JS闭包(3)
在将内部函数作为函数的返回值的时候,由于闭包的存在会携带上内部函数所使用的外部函数的变量,如果这些变量很多或者很大,那么在使用完返回的内部函数后最好将其置为null以便释放闭包中的携带变量,一面造成内 ...
- 【剑指Offer面试编程题】题目1362:左旋转字符串--九度OJ
题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=&qu ...
- 如何编写README.md
一.标题写法 1.在文本下方加上 =,文本变为大标题 2.在文本下方加上-,文本变为中标题 3.单独向输入 = ,则需要空一行 标题的另一种写法: # 一级标题 ## 二级标题 ### 三级标题 ## ...
- Java1.7已经舍弃substr了
网上一堆在写substring和substr区别的文章,都是过时的. 起码在官方6.0的api文档中已经找不到了,只有substring()
- SPI接口的FLASH
SPI flash W25Qxx: W25Q系列的spiflash.每页(Page)256B,每16个page为一个sector(扇区=4KB),每16个扇区为一个block(块=64KB) W25Q ...
- 搭建python虚拟环境virtualenv
virtualenv 是一个创建隔离Python环境的工具,创建虚拟环境运行,达到节省本地运行空间的目的. 安装vitualenv # pip install virtualenv 创建一个虚拟环境( ...
- PAT A 1020 Tree Traversals
给出一棵二叉树的后序遍历序列和中序遍历序列,求这棵二叉树的层序遍历序列 #include<iostream> #include<cstring> #include<que ...
- SRS源码——调用FFmpeg参数问题
在SRS的Ingest功能中,会调用本地FFmpeg进行拉流转码, 调用的核心代码在srs_app_ffmpeg.cpp 的 SrsFFMPEG::start() 中: // memory leak ...
- 【读书圈】win7 定时发送OA邮件
因为win7任务计划本身xls邮件调用有问题,会显示只读权限 我用vbs脚本替代了它的邮件功能!(我现在对vbs的CDO概念也没大弄清,还不知道需不需要外网,等我找台别的内网机器试试) (另外我试验了 ...
- Xcode Edit Schemes
关于本文:有关“Xcode Edit Schemes”的设置,还是有很大的学问的.由于时间关系,我一点一点的补充. 1.在开发的时候,至少将Run的Build Configuration设置为Debu ...