.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目錄下,重啓宿主程序就能夠。但願對各位有幫助!

相關文章
相關標籤/搜索