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

运行效果如下

主窗口代码如下

unit Frm_Main;

interface

{
本程序演示了如何使用QPlugins来做模块间的松散耦合,使用了Execute来传递,实际上
也可以约定接口直接调用(请参考 MultiInstance 示例)
}
uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
QPlugins,
qplugins_base,
qplugins_params,
Vcl.StdCtrls,
Vcl.ComCtrls; type
TForm_Main = class(TForm)
PageControl1: TPageControl;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; var
Form_Main: TForm_Main; implementation {$R *.dfm} // 创建主窗口
procedure TForm_Main.FormCreate(Sender: TObject);
var
ARoot: IQServices;
I: Integer;
ATabSheet: TTabSheet;
AParams: IQParams;
begin
// 通过路径获取指定的服务接口实例
ARoot := PluginsManager.ByPath('Services/Docks') as IQServices;
// 如果存在
if Assigned(ARoot) then
begin
// 创建参数
AParams := TQParams.Create;
AParams.Add('Parent', ptUInt64);
// 遍历实例
for I := to ARoot.Count - do
begin
// 每个实例都创建一个内嵌窗体
ATabSheet := TTabSheet.Create(PageControl1);
ATabSheet.PageControl := PageControl1;
ATabSheet.Caption := ARoot[I].Name;
//
AParams[].AsInt64 := IntPtr(ATabSheet);
ARoot[I].Execute(AParams, nil);
end;
end;
end; end.

服务单元如下

unit Serv_Dock;

interface

uses
classes,
qstring,
QPlugins,
qplugins_params,
qplugins_base,
controls; type
TDockService = class(TQService)
private
FControlClass: TControlClass;
public
function Execute(AParams: IQParams; AResult: IQParams): Boolean; override; stdcall;
property ControlClass: TControlClass read FControlClass write FControlClass;
end; const
// 窗口插件接口
IDockServices: TGUID = '{9DDD6DD9-3053-4EE2-90D5-759267DBB10C}'; // 注册插件窗体
procedure RegisterDock(AClass: TControlClass); implementation { TDockService } // 执行服务并将结果返回到AResult中
function TDockService.Execute(AParams, AResult: IQParams): Boolean;
var
AParent: TWinControl;
AControl: TControl;
begin
// 第一个参数为父窗口句柄
AParent := Pointer(AParams[].AsInt64);
// 窗体内嵌,并返回真
AControl := ControlClass.Create(AParent);
AControl.HostDockSite := AParent;
AControl.Visible := True;
AControl.Align := alClient;
Result := True;
end; // 注册插件窗体
procedure RegisterDock(AClass: TControlClass);
var
AParent: IQServices;
AService: TDockService;
begin
// ById通过服务接口ID获取服务接口实例,唯一的IDockServices
AParent := PluginsManager.ById(IDockServices) as IQServices;
// 创建TDockService服务
AService := TDockService.Create(NewId, AClass.ClassName);
AService.ControlClass := AClass;
// 把服务添加到服务接口实例中
AParent.Add(AService);
end; procedure RegisterClass;
begin
// 注册内嵌窗体接口
PluginsManager.Services.Add(TQServices.Create(IDockServices, 'Docks'));
end; initialization // 注册
RegisterClass; end.

窗体1

unit Frm_Show1;

interface

uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls,
Vcl.ExtCtrls; type
TForm_Show1 = class(TForm)
Panel1: TPanel;
Memo1: TMemo;
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
end; var
Form_Show1: TForm_Show1; implementation uses
Serv_Dock;
{$R *.dfm} initialization // ById通过服务接口ID获取IDockServices服务接口实例,并把这个TForm_Show1注册到接口实例中
RegisterDock(TForm_Show1); end.

窗体2

unit Frm_Show2;

interface

uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls,
Vcl.ExtCtrls,
Vcl.Imaging.jpeg; type
TForm_Show2 = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Image1: TImage;
Label2: TLabel;
Label3: TLabel;
private
{ Private declarations }
public
{ Public declarations }
end; var
Form_Show2: TForm_Show2; implementation uses
Serv_Dock;
{$R *.dfm} initialization // ById通过服务接口ID获取IDockServices服务接口实例,并把这个TForm_Show2注册到接口实例中
RegisterDock(TForm_Show2); end.

013.Delphi插件之QPlugins,模块化代码示例的更多相关文章

  1. 基于RabbltMQ延迟插件实现延迟队列代码示例

    上一篇文章写了docker安装RabbitMQ及延迟插件的安装,这篇的话是基于RabbitMQ延迟插件实现延迟队列的示例 那么废话不多说 直接上代码!! 首先创建延迟队列配置类 DelayedQueu ...

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

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

  3. 014.Delphi插件之QPlugins,MDI窗口

    不知道为什么,这个DEMO编译出来报错,运行不了,在QDAC群里问了一下也没人响应. 效果如下 主程序代码如下 unit Frm_Main; interface uses Winapi.Windows ...

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

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

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

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

  6. 010.Delphi插件之QPlugins,遍历服务接口

    这个DEMO注意是用来看一个DLL所拥有的全部服务接口 演示效果如下 代码如下: unit Frm_Main; interface uses Winapi.Windows, Winapi.Messag ...

  7. 009.Delphi插件之QPlugins,服务的热插拔

    这个DEMO用来演示服务的替换,用起来总是怪怪的感觉,效果图如下 代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messages, ...

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

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

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

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

随机推荐

  1. Redis常用命令操作

    字符串类型: * 存储:set key value * 获取:get key * 无值返回nil * 删除:del key 哈希类型 hash: * 存储:hset key field value * ...

  2. SQL SERVER2005自动备份 2012.3.29

    要想在 SQL2005上进行数据库的自动备份必须把sql server的SQL Server Agent服务开启,否则是无法进行自动备份的 启动完成之后,用户可以直接在“管理”下面的“维护计划”选项来 ...

  3. PTA的Python练习题(十一)

    从 第4章-3 猴子吃桃问题 继续 1. a=eval(input()) def count(n): b=1 for i in range(n-1): b=(b+1)*2 return b print ...

  4. Windows下ARP协议的工作原理简介

       ARP协议(Address Resolve Protocol,地址解析协议)工作在TCP/IP协议的第二层-数据链路层,用于将IP地址转换为网络接口的硬件地址(媒体访问控制地址,即MAC地址). ...

  5. Java8使用Stream优雅地处理集合

    说明 集合和数组是我们经常会用到的数据结构,在jdk1.8之前,集合和数组的处理并不是很便捷.但是到了JDK1.8之后,使用Stream处理集合会使代码变得更加的简洁明了.作为一名开发者,其实很有必要 ...

  6. vue-cli 初始化项目时开发环境中的跨域问题

    最近刚刚完成自己的毕业设计(基于Vue的信息资讯展示与管理平台),于是想整理一下过程遇到的一些问题. 项目基于Vue开发,使用 Vue-cli 初始化项目文件目录时默认占用8080端口,而我又想使用 ...

  7. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表单:表单帮助文本

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. python的线性代数

    估计线性模型中的系数:a=np.linalg.lstsq(x,b),有b=a*x 求方阵的逆矩阵np.linalg.inv(A) 求广义逆矩阵:np.linalg.pinv(A) 求矩阵的行列式:np ...

  9. Linux命令:cp命令

    cp命令作用:拷贝文件和目录 一.格式 cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION].. ...

  10. Android问题:ScrollView默认位置不是最顶部最全解决方案

    描述: Scrollview里面嵌套了一个listview ,这是开发中最寻常的一种布局,遇到的问题是:在这个Scrollview页面默认的起始位置不是最顶部,而是listview的底部. 原因: 在 ...