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)哦,謝謝。插件

相關文章
相關標籤/搜索