013.Delphi插件之QPlugins,模块化代码示例
2024-09-03 15:56:50
这个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.
最新文章
- 让 ASP.NET vNext 在 Mac OS 中飞呀飞。。。
- java 24 - 2 GUI之监听机制和适配器改进窗口关闭
- FFT 模板
- web页面的回流,认识与避免
- Android之XML序列化和解析
- js刷新页面和跳转
- Java [Leetcode 67]Add Binary
- [引]LINQ to XML 类概述
- 转:Gulp使用指南
- 《FPGA零基础入门到精通视频教程》-第002计数器(Modelsim前仿真)
- Flask构建微电影(一)
- 【bzoj1758】[Wc2010]重建计划
- SQL Server数据库的备份和还
- Mac安装minikube
- Clion 常用快捷键
- 第二章 构建布局良好的windows程序
- AutoMapper之投影
- 关于网站开发中div标签中设置宽度后其中文本溢出的原因和解决方法
- LINUX中关于SIGNAL的定义
- Nuget出现错误怎么办?
热门文章
- vs2010 c++中内嵌汇编代码
- 如何编写README.md
- 【原】linux设置网络延迟/丢包操作
- LeetCode 876. Middle of the Linked List(获得链表中心结点)
- 2月送书福利:ASP.NET Core开发实战
- 阿里分布式开放消息服务(ONS)原理与实践——笔记整理
- 利用django打造自己的工作流平台(二):疫情统计系统
- 「NOIP2017」逛公园
- 洛谷 P6046 [CTSC2000]快乐的蜜月
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 按钮:制作一个小按钮