不知道为什么,这个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窗口的更多相关文章

  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. win10的guard占内存过高

    转自:https://zhidao.baidu.com/question/1180883495203481459.html win10的guard占内存过高,

  2. 开启Linux服务器vnc远程服务详细步骤

    1.安装rpm包 ,如果没有这个包,请提前下载好,然后输入命令安装   yum localinstall  /usr/local/tigervnc-server-1.1.0-24.el6.x86_64 ...

  3. idea 构建maven web项目

    参考:https://blog.csdn.net/czc9309/article/details/80304074 idea Tomcat 部署 war和war exploded的区别 参考:  ht ...

  4. 计算xx年xx月xx日是星期几

    代码: #include <iostream> #include <string> #include <vector> using namespace std; i ...

  5. 更新Android Studio,提示后直接点更新即可。gradle 两种更新方法,我用的第二种:手动添加gradle

    直接更新即可. 更新完毕后,随即会让你更新gradle,但是会一直更新一直更新...... 解决方法: 第一种方法: 手动下载Android Studio 对应的 gradle版本,然后设置一下即可. ...

  6. matlab练习程序(龙格库塔法)

    非刚性常微分方程的数值解法通常会用四阶龙格库塔算法,其matlab函数对应ode45. 对于dy/dx = f(x,y),y(0)=y0. 其四阶龙格库塔公式如下: 对于通常计算,四阶已经够用,四阶以 ...

  7. Java程序基本优化

    1.尽量指定类的final修饰符,因为带有final修饰符的类是不可派生的. 2.尽量重用对象. 3.尽量使用局部变量. 4.不要重复初始化变量. 5.在Java+Oracle的应用系统开发中,Jav ...

  8. ubuntu用命令行打开vscode

    1.打开终端 2.输入code即可

  9. IdentityServer4专题之二:OpenID介绍

    1.基于概念 OpenId是一个以用户为中心的数字身份识别框架,它具有开放.分散.自由等特性.OpenId的创建是基于这样一个概念:我们可以通过URI(或者URL网址)来识别一个网站.同样,我们也可以 ...

  10. 开源Web测试工具介绍

    HtmlUnitHtmlUnit 是 JUnit 的扩展测试框架之一.HtmlUnit 将返回文档模拟成 HTML,这样您便可以直接处理这些文档了.HtmlUnit 使用例如 table.form 等 ...