演示的界面如下,拖动滚动条,百分比圆和进度条也是会跟着动的

主程序的代码如下

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通知的更多相关文章

  1. 012.Delphi插件之QPlugins,多实例内嵌窗口服务

    这个DEMO中主要是在DLL中建立了一个IDockableControl类,并在DLL的子类中写了具体的实现方法. 在主程序exe中,找到这个服务,然后调用DLL的内嵌方法,把DLL插件窗口内嵌到主程 ...

  2. 007.Delphi插件之QPlugins,插件的卸载和重新加载

    效果图如下,可以反复卸载和重新加载.QPlugins这个插件,还没弄明白,摸索着跟着DEMO写 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows ...

  3. 003.Delphi插件之QPlugins,菜单插件加强

    相比上一篇的菜单插件,这个在创建和销毁时候,做了增强,同时做了2个菜单对应的窗口 unit MenuSvc; interface uses windows, classes, SysUtils, Gr ...

  4. 002.Delphi插件之QPlugins,菜单插件

    运行之后的效果如下, 图一 图二 主界面代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUt ...

  5. 015.Delphi插件之QPlugins,FMX插件窗口

    内嵌FMX的插件窗口,效果还是很可以的.退出时,会报错,很诡异啊. 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messa ...

  6. 014.Delphi插件之QPlugins,MDI窗口

    不知道为什么,这个DEMO编译出来报错,运行不了,在QDAC群里问了一下也没人响应. 效果如下 主程序代码如下 unit Frm_Main; interface uses Winapi.Windows ...

  7. 013.Delphi插件之QPlugins,模块化代码示例

    这个DEMO的是一个定义了一个窗体插件接口,把其他窗口注册到这个窗体插件接口中.主程序运行起来,就遍历一下窗体插件接口,把每个窗体内嵌到对话框中 运行效果如下 主窗口代码如下 unit Frm_Mai ...

  8. 011.Delphi插件之QPlugins,延时加载服务

    这个DEMO是是把DLL插件的相关信息做成了一个配置文件,主程序加载这个配置文件,从而起到延时加载的作用 主程序代码如下 unit Frm_Main; interface uses Winapi.Wi ...

  9. 010.Delphi插件之QPlugins,遍历服务接口

    这个DEMO注意是用来看一个DLL所拥有的全部服务接口 演示效果如下 代码如下: unit Frm_Main; interface uses Winapi.Windows, Winapi.Messag ...

随机推荐

  1. 笔记-AJAX

    笔记-AJAX 1.      简介 Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML AJAX 是一种用于创建快速动态网页的技术 ...

  2. JAVA高级编程数据源datasource

    原文链接 数据源 通过jdbc连接数据库,多建立几条连接放在数据源里面.可以设置数据源的最大连接数,同时活跃的连接数,最少空闲的连接数,能够同时接收处理的连接数等等. dbcp数据源 需要的jar包: ...

  3. git push的时候报错: Out of memory, malloc failed (tried to allocate 82037333 bytes)

    原因:上传的文件过大,这里我上传的文件有10G+所以报了上面的错误 解决方法:依次运行:git config --global pack.threads 1 git,git config --glob ...

  4. C++结构体struct与C语⾔结构体和C++引⽤&与传值的区别

    写再最前面:摘录于柳神的笔记: (1)定义好结构体 stu 之后,使⽤这个结构体类型的时候,C语⾔需要写关键字 struct ,⽽C++⾥⾯可以省 略不写: (2)这个引⽤符号 & 要和C语⾔ ...

  5. Linux内核5.4正式将华为EROFS超级文件系统合入主线

    导读 近期,Linux内核5.4系列宣布全面可用,添加了许多新功能,更强的安全性和更新的驱动程序,以提供更好的硬件支持.Linux内核5.4增加对微软exFAT文件系统的支持,另外还支持内核锁定功能, ...

  6. IP地址规划

    IP地址(Internet Protocol Address),缩写为IP Adress,是一种在Internet上的给主机统一编址的地址格式,也称为网络协议(IP协议)地址.它为互联网上的每一个网络 ...

  7. Linux引导过程!(重点)

    1.开机自检:服务器开机后,将根据主板BIOS (基本输入系统),中的设置对CPU .内存.显卡.键盘等设备进行初步检测,并初始化部分硬件. 2.MBR 引导:当从本机硬盘中启动系统时,首先根据硬盘中 ...

  8. Linux centosVMware 自动化运维Ansible介绍、Ansible安装、远程执行命令、拷贝文件或者目录、远程执行脚本、管理任务计划、安装rpm包/管理服务、 playbook的使用、 playbook中的循环、 playbook中的条件判断、 playbook中的handlers、playbook实战-nginx安装、管理配置文件

    一.Ansible介绍 不需要安装客户端,通过sshd去通信 基于模块工作,模块可以由任何语言开发 不仅支持命令行使用模块,也支持编写yaml格式的playbook,易于编写和阅读 安装十分简单,ce ...

  9. git 常用命令记录 -- 快捷&备忘

    1.安装 略2.git拉取远程分支 git config user.name git config user.email git config --global user.name xxxx git ...

  10. C/C++网络编程2——socket函数

    本节主要介绍创建套接字的socket函数. #include <sys/socket.h> int socket(int domain, int type, int protocol); ...