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 ...
随机推荐
- 【转】spring IOC和AOP的理解
spring 的优点?1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易实 ...
- C++ 知识零碎搭建
全局变量 局部变量 函数不能嵌套定义 C/C++ 变量在将要被使用时定义即可, 不必一开始就声明所有变量 函数的定义与声明的区别 C++常规类型自动类型转换规则 C语言中十六进制和八进制的格式: 二进 ...
- Selenium+webdriver自动化登陆QQ邮箱并发送邮件
1.关于selenium Selenium的主要功能包括:(1)测试与浏览器的兼容性:测试应用程序能否兼容工作在不同浏览器和操作系统之上.(2)测试系统功能:录制用例自动生成测试脚本,用于回归功能测 ...
- C++ — 后缀表达式转表达式树
2018-07-21 16:57:26 update 建立表达式树的基本思路:方法类似由下而上建立堆的思想,所以时间复杂度为O(n),这样算法就会变得很简单,只用考虑处理需要入栈的节点和栈中的节点即可 ...
- Python 基础之生成器
一.生成器表达式 生成器本质是迭代器,允许自定义逻辑的迭代器迭代器和生成器区别:迭代器本身是系统内置的,重写不了.而生成器是用户自定义的,可以重写迭代逻辑生成器可以用来钟方式创建: (1)生成器 ...
- jeDate日期控件精确到秒
案例下载 链接: https://pan.baidu.com/s/1m7eEW6K6Bt1t-0OjVY_Wxw 密码: xmei <script type="text/javascr ...
- 「快学springboot」16.让swagger帮忙写接口文档
swagger简介 官方的介绍 THE WORLD'S MOST POPULAR API TOOLING Swagger is the world's largest framework of API ...
- I Hate it-HDU1754 点修改+区间最大值
题意: 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感.不管你喜不喜欢, 现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然, ...
- sqlplus 登陆使用
select * from dept; input order by dname; 追加文本命令 del n 删除语句 celar buffer ; 清除缓冲区的命令 conn sys as ...
- c# 事件3
1.什么是事件,使对象或者类具有通知功能的成员.//为了解决字段在外部被滥用,推出了事件 事件的功能能=通知+可选的事件参数(具体的详细信息,包括谁发送了消息,发送的什么消息) 使用:用于对象或者类件 ...