zoukankan      html  css  js  c++  java
  • 014.Delphi插件之QPlugins,MDI窗口

    不知道为什么,这个DEMO编译出来报错,运行不了,在QDAC群里问了一下也没人响应。

    效果如下

    主程序代码如下

    unit Frm_Main;
    
    interface
    
    uses
      Winapi.Windows,
      Winapi.Messages,
      System.SysUtils,
      System.Variants,
      System.Classes,
      Vcl.Graphics,
      Vcl.Controls,
      Vcl.Forms,
      Vcl.Dialogs,
      Vcl.Menus,
      QPlugins,
      qplugins_params,
      qplugins_formsvc,
      qplugins_vcl_formsvc,
      qplugins_loader_lib;
    
    { 注意使用 MDI 子窗体做为插件,宿主和插件都必需同时引用rtl/vcl运行时包 }
    
    type
      TForm_Main = class(TForm)
        MainMenu1: TMainMenu;
        File1: TMenuItem;
        procedure FormCreate(Sender: TObject);
        procedure File1Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
      private
        { Private declarations }
        FOpenChildren: array of IQFormService;
        procedure DoFormClosed(AForm: IQFormService; var Action: TCloseAction);
        procedure DoFormFree(AForm: IQFormService);
      public
        { Public declarations }
      end;
    
    var
      Form_Main: TForm_Main;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm_Main.DoFormClosed(AForm: IQFormService; var Action: TCloseAction);
    var
      I: Integer;
    begin
      // 方法1:设置Action为caFree,然后由DoFormFree事件来处理清理服务
      // Action := caFree;
      // 方法2:直接释放引用就可以,优点是不用处理 OnFree 事件了
      for I := 0 to High(FOpenChildren) do
      begin
        if FOpenChildren[I] = AForm then
        begin
          Delete(FOpenChildren, I, 1);
          Break;
        end;
      end;
    end;
    
    procedure TForm_Main.DoFormFree(AForm: IQFormService);
    var
      I: Integer;
    begin
      // 直接释放引用就可以
      for I := 0 to High(FOpenChildren) do
      begin
        if FOpenChildren[I] = AForm then
        begin
          Delete(FOpenChildren, I, 1);
          Break;
        end;
      end;
    end;
    
    // 菜单_新建
    procedure TForm_Main.File1Click(Sender: TObject);
    var
      AService: IQFormService;
      // 窗体事件
      AEvents: TQFormEvents;
    begin
      if Supports(PluginsManager.ByPath('/Services/Forms/MDI/MDITest'), IQFormService, AService) then
      begin
        // 设置窗体事件
        FillChar(AEvents, SizeOf(AEvents), 0);
        // 替换窗体的关闭和释放事件
        AEvents.OnClose := DoFormClosed;
        AEvents.OnFree := DoFormFree;
        AService.HookEvents(AEvents);
        AService.Show;
        // FOpenChildren数组长度+1,为了添加一个AService
        SetLength(FOpenChildren, Length(FOpenChildren) + 1);
        FOpenChildren[High(FOpenChildren)] := AService;
      end;
    end;
    
    procedure TForm_Main.FormClose(Sender: TObject; var Action: TCloseAction);
    var
      I: Integer;
      AEvents: TQFormEvents;
    begin
      // 在直接关闭前,要先移除事件关联,否则在服务释放时,回调DoFormFree时会出错
      FillChar(AEvents, SizeOf(AEvents), 0);
      // 遍历移除替换的窗体事件
      for I := 0 to High(FOpenChildren) do
      begin
        FOpenChildren[I].HookEvents(AEvents);
      end;
      // 清空
      SetLength(FOpenChildren, 0);
    end;
    
    // 创建
    procedure TForm_Main.FormCreate(Sender: TObject);
    begin
      with PluginsManager do
      begin
        // 加载同目录下dll文件
        Loaders.Add(TQDLLLoader.Create(ExtractFilePath(Application.ExeName), '.dll'));
        // 启动服务
        Start;
      end;
    end;
    
    end.

    DLL代码如下

    unit Frm_Mdi;
    
    
    interface
    
    uses
      Winapi.Windows,
      Winapi.Messages,
      System.SysUtils,
      System.Variants,
      System.Classes,
      Vcl.Graphics,
      Vcl.Controls,
      Vcl.Forms,
      Vcl.Dialogs;
    
    type
      TForm_Mdi = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form_Mdi: TForm_Mdi;
    
    implementation
    
    uses
      QPlugins,
      qplugins_vcl_formsvc;
    {$R *.dfm}
    
    initialization
    
    // 注册一个单实例服务
    RegisterFormService('/Services/Forms/MDI', 'MDITest', TForm_Mdi);
    
    finalization
    
    // 注销
    UnregisterServices('/Services/Forms/MDI', ['MDITest']);
    
    end.
  • 相关阅读:
    SpringMVC概述
    Spring 声明式事务
    Spring_AOP切面编程
    Spring DI依赖注入
    Spring IOC控制反转
    Spring解耦和耦合
    Spring概述
    HTTP协议常见状态码
    TCP/IP协议的认识
    设计模式-工厂模式(factory)
  • 原文地址:https://www.cnblogs.com/tianpan2019/p/11504574.html
Copyright © 2011-2022 走看看