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