[QPlugins] 使用 QPlugins 的通知机制

首先,我们要知道 QPlugins 的通知机制使用了订阅发布模式。一个通知或叫主题有两个重要的属性:

  • 名称(Name)
    名称是通知类型的名字,必需在整个插件系统中保证唯一,同名的被认为是一个类型的通知。当跨进程通信时,是靠名称而不是 ID 来唯一区分通知。
  • 编号(ID)
    一个进程唯一的编号(为什么是进程唯一,这个问题好高难,所以不知道如何回答),这个ID是一个整数,从0开始,在你调用 IdByName 获取 ID 时生成,这个 ID 无论注册多少次,都会返回同一个值。但是,这个值不跨进程,所以不能用于在网络或多进程间广播通知。

好了,既然是订阅发布模式,那么,我们就只需要在对通知感兴趣的地方,调用订阅的接口来订阅通知。我们分成两个部分来说这下事。

1、订阅者需要实现 IQNotify 接口,下面是一个简单的例子:

type
   TMyHandler=class(IQNotify)
     procedure Notify(const AId: Cardinal; AParams: IQParams;
      var AFireNext: Boolean); stdcall;
   end;

这里有三个参数,咱们来简单解释一下:

  • AId:订阅者收到的通知编号
  • AParams : 订阅者收到的通知附加的参数信息,具体内容由通知的发布者决定
  • AFireNext:是否允许通知管理器发送通知给下一个订阅者

然后你创建一个 TMyHandler 的实例,用来接收通知,大概意思是:

var
  AMgr:IQNotifyManager;
begin
AMgr:=PluginsManager as IQNotifyManager;
FNotifyId:=AMgr.IdByName('通知名称');
AMgr.Subscribe(FNotifyId,TMyHandler.Create);
...

如果是 DLL 或 BPL 中的插件,你需要在模块卸载时,调用 IQNotifyManager.Unsubscribe 来取消订阅,否则可能会出 AV 错误。这里就不在缀述。

2、发布者

好吧,我承认发布者最不负责任,它不需要处理通知发布后的结果,它只是负责发通知。同样的,第一步,通过 IdByName 来获取指定的通知 ID,然后只需要调用 IQNotifyManager.Send 或 Post 方法来发布通知,二者的区别就象 SendMessage 和 PostMessage 一样。

(PluginsManager as IQNotifyManager).Send(FNotifyId,通知的参数);

OK,发布者不需要任何清理工具,因为发布完就没它什么事了。我们看一个例子的执行效果:

notify

分享到: