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中的 ...
随机推荐
- day4-2数组及方法
数组: Js数组 可以存放任意数据类型的数据 如果索引大于数组的长度,数组自动增加到该索引值加1的长度 var arr = ["terry","larry",& ...
- npm安装包时的几种模式
本文原文地址:https://www.limitcode.com/detail/59a15b1a69e95702e0780249.html 回顾 npm install 命令 最近在写Node程序的时 ...
- ALSA 有关文档
Alsa项目的官方网址:http://www.alsa-project.org/ Alsa LIB API Reference:http://www.alsa-project.org/alsa-doc ...
- Primecoin服务端更新--操作流程
Primecoin服务端更新流程: 一.下载更新文件primecoin_x.y.z_xx.zip到/servers目录下:这里是把:版本primecoin0161alpha1更新到:版本primec ...
- Java 代码中如何调用 第三方Api
在代码中调用第三方API 获取数据 package com.example.demo.utils; import com.alibaba.fastjson.JSONObject; import lom ...
- 「JSOI2010」满汉全席
前言 由于蒟蒻才刚开始学 \(\text{2-SAT}\),所以题解中有的地方可能不够精炼,望多包涵! 题目描述 题目意思很简单,标准的\(\text{2-SAT}\)问题模型.那么我们就先来介绍一下 ...
- Django 学习 之ORM聚合查询分组查询与F查询与Q查询
一.聚合查询和分组查询 1.聚合查询aggregate 关于数据表的数据请见上一篇:Django 学习 之ORM多表操作(点我) aggregate(*args, **kwargs),只对一个组进行聚 ...
- synchronized和volatile关键字
synchronized 同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synch ...
- python 网络爬虫(二)
一.编写第一个网络爬虫 为了抓取网站,我们需要下载含有感兴趣的网页,该过程一般被称为爬取(crawling).爬取一个网站有多种方法,而选择哪种方法更加合适,则取决于目标网站的结构. 首先探讨如何安全 ...
- node指针