这个DEMO的是一个定义了一个窗体插件接口,把其他窗口注册到这个窗体插件接口中。主程序运行起来,就遍历一下窗体插件接口,把每个窗体内嵌到对话框中
运行效果如下
主窗口代码如下
unit Frm_Main; interface { 本程序演示了如何使用QPlugins来做模块间的松散耦合,使用了Execute来传递,实际上 也可以约定接口直接调用(请参考 MultiInstance 示例) } uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, QPlugins, qplugins_base, qplugins_params, Vcl.StdCtrls, Vcl.ComCtrls; type TForm_Main = class(TForm) PageControl1: TPageControl; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form_Main: TForm_Main; implementation {$R *.dfm} // 创建主窗口 procedure TForm_Main.FormCreate(Sender: TObject); var ARoot: IQServices; I: Integer; ATabSheet: TTabSheet; AParams: IQParams; begin // 通过路径获取指定的服务接口实例 ARoot := PluginsManager.ByPath('Services/Docks') as IQServices; // 如果存在 if Assigned(ARoot) then begin // 创建参数 AParams := TQParams.Create; AParams.Add('Parent', ptUInt64); // 遍历实例 for I := 0 to ARoot.Count - 1 do begin // 每个实例都创建一个内嵌窗体 ATabSheet := TTabSheet.Create(PageControl1); ATabSheet.PageControl := PageControl1; ATabSheet.Caption := ARoot[I].Name; // AParams[0].AsInt64 := IntPtr(ATabSheet); ARoot[I].Execute(AParams, nil); end; end; end; end.
服务单元如下
unit Serv_Dock; interface uses classes, qstring, QPlugins, qplugins_params, qplugins_base, controls; type TDockService = class(TQService) private FControlClass: TControlClass; public function Execute(AParams: IQParams; AResult: IQParams): Boolean; override; stdcall; property ControlClass: TControlClass read FControlClass write FControlClass; end; const // 窗口插件接口 IDockServices: TGUID = '{9DDD6DD9-3053-4EE2-90D5-759267DBB10C}'; // 注册插件窗体 procedure RegisterDock(AClass: TControlClass); implementation { TDockService } // 执行服务并将结果返回到AResult中 function TDockService.Execute(AParams, AResult: IQParams): Boolean; var AParent: TWinControl; AControl: TControl; begin // 第一个参数为父窗口句柄 AParent := Pointer(AParams[0].AsInt64); // 窗体内嵌,并返回真 AControl := ControlClass.Create(AParent); AControl.HostDockSite := AParent; AControl.Visible := True; AControl.Align := alClient; Result := True; end; // 注册插件窗体 procedure RegisterDock(AClass: TControlClass); var AParent: IQServices; AService: TDockService; begin // ById通过服务接口ID获取服务接口实例,唯一的IDockServices AParent := PluginsManager.ById(IDockServices) as IQServices; // 创建TDockService服务 AService := TDockService.Create(NewId, AClass.ClassName); AService.ControlClass := AClass; // 把服务添加到服务接口实例中 AParent.Add(AService); end; procedure RegisterClass; begin // 注册内嵌窗体接口 PluginsManager.Services.Add(TQServices.Create(IDockServices, 'Docks')); end; initialization // 注册 RegisterClass; end.
窗体1
unit Frm_Show1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; type TForm_Show1 = class(TForm) Panel1: TPanel; Memo1: TMemo; Label1: TLabel; private { Private declarations } public { Public declarations } end; var Form_Show1: TForm_Show1; implementation uses Serv_Dock; {$R *.dfm} initialization // ById通过服务接口ID获取IDockServices服务接口实例,并把这个TForm_Show1注册到接口实例中 RegisterDock(TForm_Show1); end.
窗体2
unit Frm_Show2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Imaging.jpeg; type TForm_Show2 = class(TForm) Panel1: TPanel; Label1: TLabel; Image1: TImage; Label2: TLabel; Label3: TLabel; private { Private declarations } public { Public declarations } end; var Form_Show2: TForm_Show2; implementation uses Serv_Dock; {$R *.dfm} initialization // ById通过服务接口ID获取IDockServices服务接口实例,并把这个TForm_Show2注册到接口实例中 RegisterDock(TForm_Show2); end.
来源:https://www.cnblogs.com/tianpan2019/p/11504382.html