zoukankan      html  css  js  c++  java
  • 013.Delphi插件之QPlugins,模块化代码示例

    这个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.
  • 相关阅读:
    ABP文档
    ABP框架没有httpPost,httpget,httpput特性
    使用命令关闭占用80端口的程序
    nginx安装编译详解
    docker端口映射设置
    centos6.3安装nginx
    process有个env属性,env属性就是环境变量,里面可以访问到NODE_ENV;NODE_ENV是在启动nodejs时添加上去的;
    使用nssm在windows服务器上部署nodejs
    对象相等与不相等
    可用的CSS文字两端对齐
  • 原文地址:https://www.cnblogs.com/tianpan2019/p/11504382.html
Copyright © 2011-2022 走看看