005.Delphi插件之QPlugins,IQNotify通知
演示的界面如下,拖动滚动条,百分比圆和进度条也是会跟着动的

主程序的代码如下
unit Frm_Main; interface uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.ComCtrls,
qstring,
QPlugins,
qplugins_base,
qplugins_loader_lib,
qplugins_params,
qplugins_vcl_formsvc,
qplugins_vcl_messages,
qplugins_formsvc,
Vcl.StdCtrls; type
TForm_Main = class(TForm)
TrackBar1: TTrackBar;
Label1: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure TrackBar1Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button3Click(Sender: TObject);
private
{Private declarations}
FChangeNotifyId: Integer;
public
{Public declarations}
end; var
Form_Main: TForm_Main;
FInterfaceList: TInterfaceList; // 保存窗体插件实例指针 implementation uses
Frm_Show;
{$R *.dfm} // 按钮_新建接收窗口
procedure TForm_Main.Button1Click(Sender: TObject);
begin
// 显示窗口
TForm_Show.Create(Application);
end; // 按钮_新建DLL插件窗口
procedure TForm_Main.Button2Click(Sender: TObject);
var
// 窗体服务的接口
AFormService: IQFormService;
begin
// 加载DLL_MutiInstance的DLL插件窗口
if Supports(PluginsManager.ByPath('/Services/Docks/Forms/DLL_MutiInstance'), IQFormService, AFormService) then
begin
// 把这个服务窗口添加到接口列表中
FInterfaceList.Add(AFormService);
// ShowMessage(ServiceSource(AFormService as IQService));
// 显示
AFormService.Show;
end;
end; // 按钮_显示参数
procedure TForm_Main.Button3Click(Sender: TObject);
var
AParams: TQParams;
begin
// 创建参数列表
AParams := TQParams.Create;
// 向参数列表插入一波参数
AParams.Add('Id', );
AParams.Add('Name', '高原');
AParams.Add('IsFemale', false);
AParams.Add('Scale', 75.6);
AParams.Add('Desc', '这是测试'##'高原有很多种');
AParams.Add('Array', NewParams([, 'QDAC', 3.45]));
// 输出
ShowMessage((AParams as IQParams).AsString.Value);
end; procedure TForm_Main.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// 释放
FInterfaceList.Free;
end; // 创建
procedure TForm_Main.FormCreate(Sender: TObject);
var
APath: string;
begin
ReportMemoryLeaksOnShutdown := True;
// 取自己路径
APath := ExtractFilePath(Application.ExeName);
// 加载同目录的DLL
PluginsManager.Loaders.Add(TQDLLLoader.Create(APath, '.dll'));
// 启动服务
PluginsManager.Start;
// 找到名字为'Tracker.Changed'的通知
FChangeNotifyId := (PluginsManager as IQNotifyManager).IdByName('Tracker.Changed');
// 创建接口列表
FInterfaceList := TInterfaceList.Create;
end; // 进度条被拖动事件
procedure TForm_Main.TrackBar1Change(Sender: TObject);
begin
// 触发调用DLL中的插件窗口
// IQNotifyManager.Send 投递一个通知并等待它被处理完成
(PluginsManager as IQNotifyManager).Send(FChangeNotifyId, NewParams([TrackBar1.Position]));
end; end.
unit Frm_Show; interface uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.StdCtrls,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.Samples.Gauges,
QPlugins,
qplugins_base,
qplugins_params; type
// class需要继承IQNotify
TForm_Show = class(TForm, IQNotify)
Gauge1: TGauge;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure CheckBox1Click(Sender: TObject);
private
{Private declarations}
FNotifyId: Integer;
// 在通知发生时,通知响应函数接口。IQNotify接口中定义的函数,子类来实现这个函数
procedure Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean); stdcall;
public
{Public declarations}
end;
{var
Form_Show: TForm_Show;} implementation {$R *.dfm}
{TForm2} procedure TForm_Show.CheckBox1Click(Sender: TObject);
var
AMgr: IQNotifyManager;
begin
AMgr := PluginsManager as IQNotifyManager;
// 注册通知,事件的名称不需要特意注册,IdByName在名称不存在时,会自动注册并生成一个新的ID返回
// 多个不同的 Id 就多次订阅即可
FNotifyId := AMgr.IdByName('Tracker.Changed');
//
if CheckBox1.Checked then
begin
// 订阅一个通知
AMgr.Subscribe(FNotifyId, Self)
end
else
begin
// 取消订阅通知
AMgr.unSubscribe(FNotifyId, Self);
end;
end; procedure TForm_Show.FormClose(Sender: TObject; var Action: TCloseAction);
var
AMgr: IQNotifyManager;
begin
AMgr := PluginsManager as IQNotifyManager;
// 注册通知,事件的名称不需要特意注册,IdByName在名称不存在时,会自动注册并生成一个新的ID返回
// 多个不同的 Id 就多次订阅即可
FNotifyId := AMgr.IdByName('Tracker.Changed');
// 取消订阅通知
AMgr.unSubscribe(FNotifyId, Self);
Action := caFree;
end; procedure TForm_Show.FormCreate(Sender: TObject);
var
AMgr: IQNotifyManager;
begin
// IQNotifyManager通知管理器用于内部维护多个通知和订阅者队列
AMgr := PluginsManager as IQNotifyManager;
// 注册通知,事件的名称不需要特意注册,IdByName在名称不存在时,会自动注册并生成一个新的ID返回
// 多个不同的 Id 就多次订阅即可
// IdByName返回指定名称的通知ID
FNotifyId := AMgr.IdByName('Tracker.Changed');
// 订阅一个通知
AMgr.Subscribe(FNotifyId, Self);
end; // 在通知发生时,通知响应函数接口。IQNotify接口中定义的函数,子类来实现这个函数
procedure TForm_Show.Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean);
begin
// 多个通知关联到同一个对象时,通过AId进行进行区分
if AId = FNotifyId then
begin
// 接到通知,显示窗口
if not Visible then
begin
Show;
end;
// 显示图像百分比
Gauge1.Progress := AParams[].AsInteger;
end;
end; end.
DLL代码如下
unit Frm_Dll; interface uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls,
Vcl.ComCtrls,
QString,
QPlugins,
qplugins_base,
qplugins_vcl_formsvc,
qplugins_params; type
// class需要继承IQNotify
TForm_Dll = class(TForm, IQNotify)
CheckBox1: TCheckBox;
ProgressBar1: TProgressBar;
Label1: TLabel;
Label2: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
private
{Private declarations}
FNotifyId: Integer;
// 在通知发生时,通知响应函数接口。IQNotify接口中定义的函数,子类来实现这个函数
procedure Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean); stdcall;
public
{Public declarations}
end; var
Form_Dll: TForm_Dll; implementation {$R *.dfm} procedure TForm_Dll.CheckBox1Click(Sender: TObject);
var
AMgr: IQNotifyManager;
begin
AMgr := PluginsManager as IQNotifyManager;
// 注册通知,事件的名称不需要特意注册,IdByName在名称不存在时,会自动注册并生成一个新的ID返回
// 多个不同的 Id 就多次订阅即可
FNotifyId := AMgr.IdByName('Tracker.Changed');
if CheckBox1.Checked then
begin
// 订阅一个通知
AMgr.Subscribe(FNotifyId, Self)
end
else
begin
// 取消订阅通知
AMgr.unSubscribe(FNotifyId, Self);
end;
end; // 创建
procedure TForm_Dll.FormCreate(Sender: TObject);
var
AMgr: IQNotifyManager;
begin
Label2.Caption := '实例创建时间:' + FormatDateTime('hh:nn:ss', Now);
AMgr := PluginsManager as IQNotifyManager;
// 注册通知,事件的名称不需要特意注册,IdByName在名称不存在时,会自动注册并生成一个新的ID返回
// 多个不同的 Id 就多次订阅即可
FNotifyId := AMgr.IdByName('Tracker.Changed');
AMgr.Subscribe(FNotifyId, Self);
end; // 销毁
procedure TForm_Dll.FormDestroy(Sender: TObject);
var
AMgr: IQNotifyManager;
begin
AMgr := PluginsManager as IQNotifyManager;
// 注册通知,事件的名称不需要特意注册,IdByName在名称不存在时,会自动注册并生成一个新的ID返回
// 多个不同的 Id 就多次订阅即可
FNotifyId := AMgr.IdByName('Tracker.Changed');
AMgr.unSubscribe(FNotifyId, Self);
end; // 通知实现
procedure TForm_Dll.Notify(const AId: Cardinal; AParams: IQParams; var AFireNext: Boolean);
begin
// 多个通知关联到同一个对象时,通过AId进行进行区分
if AId = FNotifyId then
begin
// 接到通知,显示窗口
if not Visible then
begin
Show;
end;
// 显示图像百分比
ProgressBar1.Position := AParams[].AsInteger;
end;
end; initialization // 注册
//RegisterServices('/Services/Docks/Forms', [TQVCLFormService.Create('DLL_Shared', TForm_Dll.Create(nil), nil)]);
RegisterServices('/Services/Docks/Forms', [TQVCLFormService.Create('DLL_MutiInstance', TForm_Dll)]); finalization // 注销
UnregisterServices('/Services/Docks/Forms', ['DLL_Shared', 'DLL_MutiInstance']); end.
005.Delphi插件之QPlugins,IQNotify通知的更多相关文章
- 012.Delphi插件之QPlugins,多实例内嵌窗口服务
这个DEMO中主要是在DLL中建立了一个IDockableControl类,并在DLL的子类中写了具体的实现方法. 在主程序exe中,找到这个服务,然后调用DLL的内嵌方法,把DLL插件窗口内嵌到主程 ...
- 007.Delphi插件之QPlugins,插件的卸载和重新加载
效果图如下,可以反复卸载和重新加载.QPlugins这个插件,还没弄明白,摸索着跟着DEMO写 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows ...
- 003.Delphi插件之QPlugins,菜单插件加强
相比上一篇的菜单插件,这个在创建和销毁时候,做了增强,同时做了2个菜单对应的窗口 unit MenuSvc; interface uses windows, classes, SysUtils, Gr ...
- 002.Delphi插件之QPlugins,菜单插件
运行之后的效果如下, 图一 图二 主界面代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUt ...
- 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 ...
- 013.Delphi插件之QPlugins,模块化代码示例
这个DEMO的是一个定义了一个窗体插件接口,把其他窗口注册到这个窗体插件接口中.主程序运行起来,就遍历一下窗体插件接口,把每个窗体内嵌到对话框中 运行效果如下 主窗口代码如下 unit Frm_Mai ...
- 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 ...
随机推荐
- python面试题手动总结答案锦集
数据类型 字符串 1.列举python中的基本数据类型 数字:int 布尔值:bool 字符串:str 列表:list 元组:tuple 字典:dict 集合:set 然后我们需要了解一些运算符,应为 ...
- 二十 Struts2的标签库,数据回显(基于值栈)
通用标签库 判断标签:<s:if>.<s:elseif>.<s:else> 循环标签:<s:iterator> 其他常用标签: <s:proper ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 排版:设定小文本
<!DOCTYPE html> <html> <head> <title>菜鸟教程(runoob.com)</title> <meta ...
- 穿越雷区--蓝桥杯--DFS/BFS
题目描述 X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废. 某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短? ...
- spring boot中不能识别RestController
参考:https://blog.csdn.net/qq_16739693/article/details/80271987
- SpringBoot之基础入门-专题一
SpringBoot之基础入门-专题一 一.Spring介绍 1.1.SpringBoot简介 在初次学习Spring整合各个第三方框架构建项目的时候,往往会有一大堆的XML文件的配置,众多的dtd或 ...
- nodejs中this详解
最近在用Nodejs进行APP运维服务管理系统开发时发现,nodejs中的this经常会变,查了下资料后发现this在不同的代码位置中代表不同的涵义,在实际运用过程中可以用var self = thi ...
- error C2664: “FILE *fopen(const char *,const char *)”: 无法将参数 1 从“LPCTSTR”转换为“const char *”
遇到这个问题,请打开本项目的Properties(属性)-------> Configuration Properties(配置属性)-------->General(常规)------- ...
- CDQ分治-陌上花开(附典型错误及原因)
CDQ分治-陌上花开 题目大意 对于给遗传给定的序列: \[ (x,y,z)_1, (x,y,z)_2, (x,y,z)_3, \cdots, (x,y,z)_n \] 求: \[ \sum_{x_i ...
- 图层CALayer的使用
1.图层的意义 当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘制完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示. ...