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

主程序的代码如下

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. hbase单机版安装

    hbase单机版安装 1.      hbase单机版安装 HBase的安装也有三种模式:单机模式.伪分布模式和完全分布式模式. hbase依赖于Hadoop和Zookeeper. 这里安装的是单机版 ...

  2. 二十一 Struts的数据校验两种方式:手动编码和xml校验

    数据的校验: 一.前台校验:JS校验 JS的校验不是必须的,JS可以被绕行,可以提升用户体验 二.后台校验:编码校验 必须的校验 三.校验的方式: 手动编码(不建议使用) 配置文件(支持) 手动编码的 ...

  3. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 排版:强调

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. HashMap源码__resize

    final Node<K,V>[] resize() { //创建一个Node数组用于存放table中的元素, Node<K,V>[] oldTab = table; //获取 ...

  5. tensorflow文本分类实战——卷积神经网络CNN

    首先说明使用的工具和环境:python3.6.8   tensorflow1.14.0   centos7.0(最好用Ubuntu) 关于环境的搭建只做简单说明,我这边是使用pip搭建了python的 ...

  6. bash脚本编程

    一.bash中的变量 变量类型: 本地变量:只对当前shell进程有效,对其子shell以及其它shell都无效;   定义变量:[set]Var_name="value" 变量赋 ...

  7. Atcoder Beginner Contest 139E(模拟,思维)

    #define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;int n;int a[1007][1007] ...

  8. ch3 盒模型、定位

    标准盒模型.怪异盒模型 外边距叠加 当两个或者争夺垂直外边距相遇时,他们将形成一个外边距,这个外边距的高度等于两个发生叠加的外边距的高度中的较大者. 当一个元素出现在另一个元素上面时,第一个元素的底外 ...

  9. redis服务器性能优化

    1.系统内存OOM优化 vm.overcommit_memory Redis会占用非常大内存,所以通常需要关闭系统的OOM,方法为将“/proc/sys/vm/overcommit_memory”的值 ...

  10. 「CF1023F」Mobile Phone Network

    「CF1023F」Mobile Phone Network 传送门 直接钦定那 \(k\) 条边在最小生成树中,然后把最小生成树树剖一下. 每条其它边的效果就是把该边端点路径上的边的权对该边边权取 \ ...