001.Delphi插件之QPlugins,一个最简单的插件
安装QPlugins里面的Demo,复制粘贴着写了一个最简单的插件,看看好不好用
EXE代码如下:
unit Main_Frm; interface uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
qplugins_vcl_formsvc,
qplugins_loader_lib,
qstring,
qplugins_base,
QPlugins,
qplugins_params,
qplugins_vcl_messages,
qplugins_formsvc,
Vcl.Dialogs,
Vcl.StdCtrls,
Vcl.ComCtrls; type
TMain_Form = class(TForm)
GroupBox1: TGroupBox;
PageControl1: TPageControl;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{Private declarations}
procedure DoPageDoubleClick(ASender: TObject);
procedure DockPage(AFormService: IQFormService; AHoldNeeded: Boolean = False);
procedure DoDockChildFree(AForm: IQFormService);
public
{Public declarations}
end; var
Main_Form: TMain_Form; implementation {$R *.dfm} type
// Page控件页面双击事件
THackedPageControl = class(TPageControl)
public
property OnDblClick;
end; // 程序关闭时,释放所有标签
procedure TMain_Form.DoDockChildFree(AForm: IQFormService);
var
I: Integer;
begin
for I := to PageControl1.PageCount - do
begin
// 如果标签tag储存的是一个对话框
if PageControl1.Pages[I].Tag = IntPtr(AForm) then
begin
// 释放
AForm.UnhookEvents;
FreeObject(PageControl1.Pages[I]);
Break;
end;
end;
end; // 双击Page标签事件
procedure TMain_Form.DoPageDoubleClick(ASender: TObject);
var
AService: IQFormService;
begin
// 双击关闭当前窗体
if PageControl1.PageCount > then
begin
// 当前页面
AService := IQFormService(PageControl1.ActivePage.Tag);
// 关闭并移除到服务关联事件的监听
AService.Close;
AService.UnhookEvents;
// 释放
FreeObject(PageControl1.ActivePage);
if PageControl1.PageCount > then
PageControl1.ActivePageIndex := ;
end;
end; // 创建
procedure TMain_Form.FormCreate(Sender: TObject);
var
APath: string;
begin
// 查看内存泄露
// ReportMemoryLeaksOnShutdown := True;
// 路径
APath := ExtractFilePath(Application.ExeName);
// 加载DLL
PluginsManager.Loaders.Add(TQDLLLoader.Create(APath, '.dll'));
// 加载BPL
PluginsManager.Loaders.Add(TQBPLLoader.Create(APath, '.bpl'));
// 启动所有的加载器加载支持的插件
PluginsManager.Start;
PageControl1.ControlStyle := PageControl1.ControlStyle + [csClickEvents, csDoubleClicks];
// 替换Page控件页面双击事件,用于双击页签关闭某一页
THackedPageControl(PageControl1).OnDblClick := DoPageDoubleClick;
end; // 销毁
procedure TMain_Form.FormDestroy(Sender: TObject);
var
I: Integer;
AFormService: IQFormService;
begin
// 循环释放窗口
for I := to PageControl1.PageCount - do
begin
// IQFormService为窗体服务的接口
AFormService := IQFormService(PageControl1.Pages[I].Tag);
// 移除到服务关联事件的监听
AFormService.UnhookEvents;
end;
end; // 嵌入窗体
procedure TMain_Form.DockPage(AFormService: IQFormService; AHoldNeeded: Boolean);
var
APage: TTabSheet;
AEvents: TQFormEvents;
begin
// 创建页签
APage := TTabSheet.Create(PageControl1);
APage.PageControl := PageControl1;
// 设置页签名
APage.Caption := (AFormService as IQService).Name;
// 储存AFormService
APage.Tag := IntPtr(AFormService);
// 嵌入窗体到父窗口的特定的位置
AFormService.DockTo(APage.Handle, TFormAlign());
FillChar(AEvents, SizeOf(AEvents), );
// 窗口释放事件
AEvents.OnFree := DoDockChildFree;
// 挂接服务关联的窗口事件
AFormService.HookEvents(AEvents);
// 创建 TQInterfaceHolder
if AHoldNeeded then
begin
HoldByComponent(APage, AFormService);
end;
end; // 创建实例
procedure TMain_Form.Button1Click(Sender: TObject);
var
I: Integer;
AParent: IQServices;
AFormService: IQFormService;
begin
// Supports函数返回对象是否支持指定的接口
if Supports(PluginsManager.ByPath('/Services/Docks/Forms'), IQServices, AParent) then
begin
for I := to AParent.Count - do
begin
if Supports(AParent[I], IQFormService, AFormService) then
begin
if not AFormService.IsMultiInstance then
begin
// 嵌入窗体
DockPage(AFormService);
end;
end;
end;
// 激活窗口
if PageControl1.PageCount > then
begin
PageControl1.ActivePageIndex := ;
end;
end;
// 创建的是单实例的,所以不应重复创建
Button1.Enabled := False;
end; end.
DLL代码如下:
unit Frm_Dll; interface uses
Winapi.Windows,
Winapi.Messages,
System.SysUtils,
System.Variants,
System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs,
Vcl.StdCtrls; type
TForm_Dll = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; var
Form_Dll: TForm_Dll; implementation {$R *.dfm} uses
qstring,
QPlugins,
qplugins_vcl_formsvc; // 释放自己
procedure TForm_Dll.Button1Click(Sender: TObject);
begin
FreeObject(Self);
end; initialization // 注册一个单实例服务
RegisterFormService('/Services/Docks/Forms', 'DLL_Static', TForm_Dll, False); finalization // 取消一组服务的注册
UnregisterServices('/Services/Docks/Forms', ['DLL_Static']); end.
初步感受了一下,插件用着还可以。
不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意金额给作者(微信号:382477247)哦,谢谢。
001.Delphi插件之QPlugins,一个最简单的插件的更多相关文章
- WordPress插件制作教程(二): 编写一个简单的插件
上一篇说到了如何创建一个插件,我想大家看了之后一定会有所收获,这一篇简单给大家写一个插件样例,让大家有一个基本的印象.这个插件的样例就是当你激活这个插件后会在你的每篇文章中插入一段自己定义好的内容,比 ...
- JQuery自定义插件详解之Banner图滚动插件
前 言 JRedu JQuery是什么相信已经不需要详细介绍了.作为时下最火的JS库之一,JQuery将其"Write Less,Do More!"的口号发挥的极致.而帮助J ...
- Android 插件化开发(四):插件化实现方案
在经过上面铺垫后,我们可以尝试整体实现一下插件化了.这里我们先介绍一下最简单的实现插件化的方案. 一.最简单的插件化实现方案 最简单的插件化实现方案,对四大组件都是适用的,技术面涉及如下: 1). 合 ...
- 【ASP.NET 插件】zyUpload的HTML5上传插件
个人能力有限,只能网上找图片批量上传插件,看到一个还不错的插件zyUpload ,可以用来上传文件,但没有.NET 版本,特修改了下用以批量上传图片,效果图如下: update:2016年3月8日 有 ...
- 原生 JS实现一个简单分页插件
最近做的一个 PC端的需求,这个需求中有一个小点,页面底部有一块列表区域,这个列表的数据量比较大,需要进行分页控制,切换页码的时候,发送一个 ajax请求,在页面无刷新的情况下,实现列表数据的刷新,所 ...
- 007.Delphi插件之QPlugins,插件的卸载和重新加载
效果图如下,可以反复卸载和重新加载.QPlugins这个插件,还没弄明白,摸索着跟着DEMO写 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows ...
- OBS插件学习入门:一个非常简单的、调节音量的filter
一个非常简单的.调节音量的filter,非线性调节: #include <obs-module.h> #include <math.h> struct volume_data ...
- 对Raphael画图标的一个jquery简单封装
公司要做一个项目的demo,要求地图上可以插红旗,所以就用到了Raphael. 因为是个demo,所以地图就用了一张图片,效果如下: 所以为了更好的封装一下这个功能,就写了一个简单的插件:jquery ...
- [原]发布一个jQuery提示框插件,Github开源附主站,jquery.tooltips.js
一个简单精致的jQuery带箭头提示框插件 插件写好快一年了,和一个 弹出框插件(点击查看) 一起写的,一直没有整理出来,昨天得功夫整理并放到了github上,源码和网站均可在线看或下载. CSS中的 ...
随机推荐
- python 基础文件操作
实时刷新到硬盘里 f= open('hh','w',encoding='utf8') f.write('gyftyftft') f.write('hghgh\njkkjk') f.flush()#实时 ...
- Spring Cloud常用注解
@SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.security.servlet.SecurityAu ...
- windows下安装subversion
前言: 最近在写windows版本下svn hooks(钩子) post-commit的实现.所以会需要在windows下安装相应的subversion.经过一番查询后,决定使用VisualSVN ...
- nacos作为配置中心兼容xml配置文件
最近公司想要用配置中心,因为公司用的有传统的spring项目,有springboot项目,为了兼容都能够采用配置中心,做了一些尝试,经过比较还是倾向于使用nacos,传统dubbo采用spring方式 ...
- How to recover if NMC cound not connect
Some times we suddently find that the NMC can not login,. You would see the sybase database error if ...
- PHP开发者该知道的5个Composer小技巧
Composer 是新一代的PHP依赖管理工具.本文介绍使用Composer的五个小技巧,希望能给你的PHP开发带来方便. 1. 仅更新单个库 只想更新某个特定的库,不想更新它的所有依赖,很简单 co ...
- Steam游戏《Zengeon(神明在上)》修改器制作-[先使用CE写,之后有时间的话改用C#](2020年寒假小目标06)
日期:2020.01.30 博客期:138 星期四 [温馨提示]: 只是想要修改器的网友,可以直接点击此链接下载: 只是想拿CT文件的网友,可以直接点击此链接下载: 没有博客园账号的网友,可以将页面下 ...
- python之字符串,列表,字典,元组,集合内置方法总结
目录 数字类型的内置方法 整型/浮点型 字符串类型的内置方法 列表的内置方法 字典的内置方法 元组的内置方法 集合类型内置方法 布尔类型 数据类型总结 数字类型的内置方法 整型/浮点型 加 + 减 - ...
- PaperReading20200222
CanChen ggchen@mail.ustc.edu.cn VS-GAE Motivation: With the publication of NAS101, researchers can ...
- CSS去掉背景颜色
background-color:transparent;