013.Delphi插件之QPlugins,模块化代码示例
这个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,模块化代码示例的更多相关文章
- 基于RabbltMQ延迟插件实现延迟队列代码示例
上一篇文章写了docker安装RabbitMQ及延迟插件的安装,这篇的话是基于RabbitMQ延迟插件实现延迟队列的示例 那么废话不多说 直接上代码!! 首先创建延迟队列配置类 DelayedQueu ...
- 015.Delphi插件之QPlugins,FMX插件窗口
内嵌FMX的插件窗口,效果还是很可以的.退出时,会报错,很诡异啊. 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messa ...
- 014.Delphi插件之QPlugins,MDI窗口
不知道为什么,这个DEMO编译出来报错,运行不了,在QDAC群里问了一下也没人响应. 效果如下 主程序代码如下 unit Frm_Main; interface uses Winapi.Windows ...
- 012.Delphi插件之QPlugins,多实例内嵌窗口服务
这个DEMO中主要是在DLL中建立了一个IDockableControl类,并在DLL的子类中写了具体的实现方法. 在主程序exe中,找到这个服务,然后调用DLL的内嵌方法,把DLL插件窗口内嵌到主程 ...
- 011.Delphi插件之QPlugins,延时加载服务
这个DEMO是是把DLL插件的相关信息做成了一个配置文件,主程序加载这个配置文件,从而起到延时加载的作用 主程序代码如下 unit Frm_Main; interface uses Winapi.Wi ...
- 010.Delphi插件之QPlugins,遍历服务接口
这个DEMO注意是用来看一个DLL所拥有的全部服务接口 演示效果如下 代码如下: unit Frm_Main; interface uses Winapi.Windows, Winapi.Messag ...
- 009.Delphi插件之QPlugins,服务的热插拔
这个DEMO用来演示服务的替换,用起来总是怪怪的感觉,效果图如下 代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messages, ...
- 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 ...
随机推荐
- Redis常用命令操作
字符串类型: * 存储:set key value * 获取:get key * 无值返回nil * 删除:del key 哈希类型 hash: * 存储:hset key field value * ...
- SQL SERVER2005自动备份 2012.3.29
要想在 SQL2005上进行数据库的自动备份必须把sql server的SQL Server Agent服务开启,否则是无法进行自动备份的 启动完成之后,用户可以直接在“管理”下面的“维护计划”选项来 ...
- 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 ...
- Windows下ARP协议的工作原理简介
ARP协议(Address Resolve Protocol,地址解析协议)工作在TCP/IP协议的第二层-数据链路层,用于将IP地址转换为网络接口的硬件地址(媒体访问控制地址,即MAC地址). ...
- Java8使用Stream优雅地处理集合
说明 集合和数组是我们经常会用到的数据结构,在jdk1.8之前,集合和数组的处理并不是很便捷.但是到了JDK1.8之后,使用Stream处理集合会使代码变得更加的简洁明了.作为一名开发者,其实很有必要 ...
- vue-cli 初始化项目时开发环境中的跨域问题
最近刚刚完成自己的毕业设计(基于Vue的信息资讯展示与管理平台),于是想整理一下过程遇到的一些问题. 项目基于Vue开发,使用 Vue-cli 初始化项目文件目录时默认占用8080端口,而我又想使用 ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表单:表单帮助文本
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- python的线性代数
估计线性模型中的系数:a=np.linalg.lstsq(x,b),有b=a*x 求方阵的逆矩阵np.linalg.inv(A) 求广义逆矩阵:np.linalg.pinv(A) 求矩阵的行列式:np ...
- Linux命令:cp命令
cp命令作用:拷贝文件和目录 一.格式 cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION].. ...
- Android问题:ScrollView默认位置不是最顶部最全解决方案
描述: Scrollview里面嵌套了一个listview ,这是开发中最寻常的一种布局,遇到的问题是:在这个Scrollview页面默认的起始位置不是最顶部,而是listview的底部. 原因: 在 ...