.Net开发笔记(十七) 应用程序扩展

在不少场合,咱们须要在已有软件程序上增长一些新的功能,几乎全部缘由是由于原有软件功能不能知足咱们的须要,咱们平时作的插件就属于这种状况,最多见的是VS IDE的插件开发,网上老外写的一篇关于插件开发的文章,很详细(网址)。若是咱们要给一个已有软件扩展新的功能,通常咱们必须知道原有软件提供给二次开发人员的接口,也就是说,若是原有软件在设计的时候,压根儿就没有考虑到后续可能存在的二次开发,也不提供任何接口,那么一般状况下,是很难在它的基础上扩展出新功能的(除非是原有软件开发者)。html

还有一种能够扩展已有程序功能的方式,网址,利用windows消息、windows hook技术,理论上能够给任何一个桌面应用程序扩展出新功能,而不须要任何接口,可是,这种方式颇有局限性,扩展出来的功能几乎停留在操做系统级别上,好比UI外观样式等,并不能真正的去与已有软件程序进行交互。老外这篇文章其实重点是在讲Windows hooks和Windows Message。windows

这篇文章不是讲怎么去开发VS插件,更不是谈哪一个具体软件好比CAD、PROE的二次开发,我只是想将看似复杂的东西简单化地解释一下,看看“给已有软件扩展新功能”究竟是怎么回事。以插件为例:框架

首先,宿主程序和插件之间必定要有交互的,否则的话,插件是不会知道何时该干什么事情;其次,宿主程序必定会传递某些数据信息给插件,不然你叫插件拿什么原材料干活?最后,宿主程序必定是要有所准备的,什么叫有所准备?也就是说,在开发宿主程序的时候,必定要为之后的功能扩展留有接口,全部插件必须遵照这个接口给出的规范,知道应该在何时跟插件通信,了解插件的任何一个行为将会致使什么样的结果,而且做出相应的反应。综上所述,给已有程序扩展新功能,关键仍是在这个“已有程序”身上,若是一个程序出生的时候就没想着未来别人要给本身增长功能,那你不用再想着去给它扩展功能了。也就是我文章刚开始说到的,并非你能够在任何一个程序基础上扩展新功能。ide

图1工具

如上图所示,宿主程序与插件之间经过某一协议进行通讯,这个跟上一篇最后讲到的“框架和客户端代码之间的关系”很类似,你能够把宿主程序看作是框架,而插件则是客户端代码(参见上一篇文章图6)。spa

图2操作系统

如上图,在宿主程序中应该提早设计好该在何时与插件通讯,以及给它传递对应数据信息,接着返回交互结果。宿主程序应该考虑全部与插件交互的地方和时间,然而插件不必定到处都会有所反应,也就是说,一个宿主程序设计好100个与插件交互的地方(插件最多能够在这100个地方大作文章),可是你开发一个插件时,根据具体须要,彻底能够只响应其中的某几个。插件

图3设计

文章后面我附上一个简单的画图Demo,实现简单的画板、保存(默承认以保存JPG图片格式和PIC可编辑格式)等功能,而后本身又作了一个插件,插件主要新增了如下功能:code

  • 增长一个“关于”菜单,点击弹出关于对话框;
  • 已有画板程序只能绘制圆形和正方形,增长了一个三角形图形;
  • 将画图保存成JPG格式时,在图片上添加水印;
  • 增长一种全新的文件格式(newpic格式),能够将画图保存为newpic格式的文件,这个有点相似photoshop的ico插件,安装后,PS能够将图片保存为ico格式。

整个项目源码分为如下三个部分:

  1. PluginDemo:宿主程序,在它的基础上扩展新的功能;
  2. PluginHelper:扩展功能时必须遵照的规范(接口),随宿主程序一块儿开发,一般就是咱们常说的“二次开发包”,理论上应该还有二次开发说明文档之类的东西;
  3. Plugin:我本身开发的一个插件。

正常状况下,1和2由已有软件开发商提供,3由二次开发人员开发。

下面主要说明一下PluginHelper中的两个接口,其他的源码诸位能够本身下下来看看。

IPlugin接口:

 1     /// <summary>
 2     /// 插件接口 全部插件必须实现该接口
 3     /// </summary>
 4     public interface IPlugin
 5     {
 6         void ApplicationLoaded(PluginApplication pluginApplication); //应用加载后
 7         void FileSavingAsJPG(Bitmap bitmap,string filepath); //文件保存为JPG
 8         void FileSavingAsPIC(PluginApplication pluginApplication); //文件保存为PIC
 9         void BeforeSave(Dictionary<string,SaveFileHandler> extensions); //保存文件以前
10         void BeforeOpen(Dictionary<string,OpenFileHandler> extensions); //打开文件以前
11         void ApplicationExiting(); //应用退出时
12 }
View Code

如接口代码所示,在固定时候固定地方,宿主程序都会调用对应方法与插件通讯。

IObject接口:

 1    /// <summary>
 2     /// 图形接口 全部的图形都必须实现该接口
 3     /// </summary>
 4     public interface IObject
 5     {
 6         int X
 7         {
 8             get;
 9             set;
10         }
11         int Y
12         {
13             get;
14             set;
15         }
16         void Draw(Graphics g);
17 }
View Code

全部新扩展图形都必须实现该接口。

若是想要开发本身的插件,只须要知道二次开发包(PluginHelper.dll),定义一个类实现IPlugin接口就行。

图4

最后上几张效果图,没插件以前的宿主程序:

图5

安装插件后的宿主程序:

图6

如上图所示,安装插件后,菜单多了“关于”菜单项,工具栏多了“三角形”按钮,能够保存另一种“newpic”格式的文件,另外,在保存为JPG格式图片时,已有软件保存图片为:

图7

安装插件后,保存为JPG格式文件以下:

图8

如上图,安装插件后,保存的JPG图有水印。

下载源码:http://files.cnblogs.com/xiaozhi_5638/PluginDemo.rar

将开发的插件放在宿主程序的plugins目录下,重启宿主程序就能够。但愿对各位有帮助!

相关文章
相关标签/搜索