001.Delphi插件之QPlugins,一个最简单的插件

安装QPlugins里面的Demo,复制粘贴着写了一个最简单的插件,看看好很差用api

EXE代码以下:微信

unit Main_Frm; interface

uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, qplugins_vcl_formsvc, qplugins_loader_lib, qstring, qplugins_base, QPlugins, qplugins_params, qplugins_vcl_messages, qplugins_formsvc, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls; type TMain_Form = class(TForm) GroupBox1: TGroupBox; PageControl1: TPageControl; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private
    {Private declarations}
    procedure DoPageDoubleClick(ASender: TObject); procedure DockPage(AFormService: IQFormService; AHoldNeeded: Boolean = False); procedure DoDockChildFree(AForm: IQFormService); public
    {Public declarations}
  end; var Main_Form: TMain_Form; implementation

{$R *.dfm}


type
  // Page控件页面双击事件
  THackedPageControl = class(TPageControl) public
    property OnDblClick; end; // 程序关闭时,释放全部标签
procedure TMain_Form.DoDockChildFree(AForm: IQFormService); var I: Integer; begin
  for I := 0 to PageControl1.PageCount - 1 do
  begin
    // 若是标签tag储存的是一个对话框
    if PageControl1.Pages[I].Tag = IntPtr(AForm) then
    begin
      // 释放
 AForm.UnhookEvents; FreeObject(PageControl1.Pages[I]); Break; end; end; end; // 双击Page标签事件
procedure TMain_Form.DoPageDoubleClick(ASender: TObject); var AService: IQFormService; begin
  // 双击关闭当前窗体
  if PageControl1.PageCount > 0 then
  begin
    // 当前页面
    AService := IQFormService(PageControl1.ActivePage.Tag); // 关闭并移除到服务关联事件的监听
 AService.Close; AService.UnhookEvents; // 释放
 FreeObject(PageControl1.ActivePage); if PageControl1.PageCount > 0 then PageControl1.ActivePageIndex := 0; end; end; // 建立
procedure TMain_Form.FormCreate(Sender: TObject); var APath: string; begin
  // 查看内存泄露
  // ReportMemoryLeaksOnShutdown := True;
  // 路径
  APath := ExtractFilePath(Application.ExeName); // 加载DLL
  PluginsManager.Loaders.Add(TQDLLLoader.Create(APath, '.dll')); // 加载BPL
  PluginsManager.Loaders.Add(TQBPLLoader.Create(APath, '.bpl')); // 启动全部的加载器加载支持的插件
 PluginsManager.Start; PageControl1.ControlStyle := PageControl1.ControlStyle + [csClickEvents, csDoubleClicks]; // 替换Page控件页面双击事件,用于双击页签关闭某一页
  THackedPageControl(PageControl1).OnDblClick := DoPageDoubleClick; end; // 销毁
procedure TMain_Form.FormDestroy(Sender: TObject); var I: Integer; AFormService: IQFormService; begin
  // 循环释放窗口
  for I := 0 to PageControl1.PageCount - 1 do
  begin
    // IQFormService为窗体服务的接口
    AFormService := IQFormService(PageControl1.Pages[I].Tag); // 移除到服务关联事件的监听
 AFormService.UnhookEvents; end; end; // 嵌入窗体
procedure TMain_Form.DockPage(AFormService: IQFormService; AHoldNeeded: Boolean); var APage: TTabSheet; AEvents: TQFormEvents; begin
  // 建立页签
  APage := TTabSheet.Create(PageControl1); APage.PageControl := PageControl1; // 设置页签名
  APage.Caption := (AFormService as IQService).Name; // 储存AFormService
  APage.Tag := IntPtr(AFormService); // 嵌入窗体到父窗口的特定的位置
  AFormService.DockTo(APage.Handle, TFormAlign(1)); FillChar(AEvents, SizeOf(AEvents), 0); // 窗口释放事件
  AEvents.OnFree := DoDockChildFree; // 挂接服务关联的窗口事件
 AFormService.HookEvents(AEvents); // 建立 TQInterfaceHolder
  if AHoldNeeded then
  begin HoldByComponent(APage, AFormService); end; end; // 建立实例
procedure TMain_Form.Button1Click(Sender: TObject); var I: Integer; AParent: IQServices; AFormService: IQFormService; begin
  // Supports函数返回对象是否支持指定的接口
  if Supports(PluginsManager.ByPath('/Services/Docks/Forms'), IQServices, AParent) then
  begin
    for I := 0 to AParent.Count - 1 do
    begin
      if Supports(AParent[I], IQFormService, AFormService) then
      begin
        if not AFormService.IsMultiInstance then
        begin
          // 嵌入窗体
 DockPage(AFormService); end; end; end; // 激活窗口
    if PageControl1.PageCount > 0 then
    begin PageControl1.ActivePageIndex := 0; end; end; // 建立的是单实例的,因此不该重复建立
  Button1.Enabled := False; 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; type TForm_Dll = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private
    { Private declarations }
  public
    { Public declarations }
  end; var Form_Dll: TForm_Dll; implementation

{$R *.dfm}

uses qstring, QPlugins, qplugins_vcl_formsvc; // 释放本身
procedure TForm_Dll.Button1Click(Sender: TObject); begin FreeObject(Self); end; initialization

// 注册一个单实例服务
  RegisterFormService('/Services/Docks/Forms', 'DLL_Static', TForm_Dll, False); finalization

// 取消一组服务的注册
  UnregisterServices('/Services/Docks/Forms', ['DLL_Static']); end.

初步感觉了一下,插件用着还能够。spa

 

不忘初心,若是您认为这篇文章有价值,认同做者的付出,能够微信二维码打赏任意金额给做者(微信号:382477247)哦,谢谢。插件

相关文章
相关标签/搜索