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 ...
随机推荐
- LXML解析html代码和文件
from lxml import etree text = """ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...
- GO测试
测试 Go拥有一个轻量级的测试框架,它由 go test 命令和 testing 包构成. 你可以通过创建一个名字以 _test.go 结尾的,包含名为 TestXXX 且签名为 func (t *t ...
- 吴裕雄--天生自然ORACLE数据库学习笔记:表分区与索引分区
create table ware_retail_part --创建一个描述商品零售的数据表 ( id integer primary key,--销售编号 retail_date date,--销售 ...
- pwn之ret2libc
0×01 利用思路 ret2libc 这种攻击方式主要是针对 动态链接(Dynamic linking) 编译的程序,因为正常情况下是无法在程序中找到像 system() .execve() 这种系统 ...
- sparkRDD:第3节 RDD常用的算子操作
4. RDD编程API 4.1 RDD的算子分类 Transformation(转换):根据数据集创建一个新的数据集,计算后返回一个新RDD:例如:一个rdd进行map操作后生了一个新的rd ...
- Codeforces Round #588 (Div. 2)D(思维,多重集)
#define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;long long a[7007],b[700 ...
- Vuex踩坑--数据刷新时丢失
近期做项目的过程中,使用vuex保存页面公共数据,测试无网情况后又接通网络的情况下,页面进行重新加载.遇到一个小bug——发现在苹果手机IOS系统下,页面刷新重新加载后页面中通过vuex存储并显示的数 ...
- cookie注入
通常我们的开发人员在开发过程中会特别注意到防止恶意用户进行恶意的注入操作,因此会对传入的参数进行适当的过滤,但是很多时候,由于个人对安全技术了解的不同,有些开发人员只会对get,post这种方式提交的 ...
- java 获取(格式化)日期格式
// 参考: https://www.cnblogs.com/blog5277/p/6407463.htmlpublic class DateTest { // 支持时分秒 private stati ...
- _CrtIsValidHeapPointer(pUserData)
程序遇到如题的运行时报错,参考下面这段文字,采取将自定义类的对象定义改为new方式生成后问题解决. !!Expression: _CrtIsValidHeapPointer(pUserData) vo ...