014.Delphi插件之QPlugins,MDI窗口

匿名 (未验证) 提交于 2019-12-03 00:02:01

不知道为什么,这个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.

 

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