013.Delphi插件之QPlugins,模块化代码示例

狂风中的少年 提交于 2019-12-22 08:39:25

这个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.

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!