Windows Live Writer插件开发经验
生活随笔
收集整理的這篇文章主要介紹了
Windows Live Writer插件开发经验
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Windows Live Writer插件開發(fā)經(jīng)驗(yàn)
2011年04月02日
經(jīng)常寫博客的朋友也許經(jīng)常使用Windows Live Writer,尤其對(duì)于有些程序員來說,時(shí)常輾轉(zhuǎn)于CSDN、Windows Live、cnBlogs等眾多社區(qū),使用WLW對(duì)博客進(jìn)行管理和更新會(huì)方便很多。我最近在寫一些技術(shù)類博客文章的時(shí)候,時(shí)常需要插入代碼,目前也有許多第三方的代碼格式化插件,如"Insert Code"、"Code Snippet"等,這些插件能讓代碼插入后輸出的HTML中產(chǎn)生語(yǔ)法高亮、行號(hào)、隔行陰影等特效,但是與CSDN本身的"插入代碼"功能相比,這些插件輸出的內(nèi)容中會(huì)包含大量的樣式,當(dāng)代碼量較大時(shí),會(huì)造成文章大小急劇地膨脹。
如果要解決內(nèi)聯(lián)樣式造成的HTML膨脹問題,可以采用CSS+JavaScript的解決方案,如著名的的"Syntax Highlighter"項(xiàng)目,但是這需要博客系統(tǒng)和平臺(tái)的支持,Wordpress與CSDN都是采用Syntax Hightlighter。因此,我在研究了幾個(gè)WLW的插件和Syntax Hightlighter的接口后,決定自己開發(fā)一個(gè)利用CSDN本身的"插入代碼"功能的插件。 微軟已經(jīng)在其MSDN上發(fā)布了Windows Live Writer的SDK,其中關(guān)于插件編寫的部分可以參看:Windows Live Writer Plugin API和這篇博客http://www.cnblogs.com/yaoshiyou/archive/2009/11/2 8/1612746.html。
WLW的插件可以分為三類: 發(fā)布通知插件:這類插件主要用于在博客文章發(fā)布前后調(diào)用,可以用來對(duì)內(nèi)容的XHTML進(jìn)行檢查或者在某些條件下取消發(fā)布。
內(nèi)容插件:這類插件用于讓用戶插入某種形式的內(nèi)容,并對(duì)內(nèi)容進(jìn)行格式化處理,例如某些插件可以讓用戶選擇插入本地的一張圖片,然后生成縮略圖上傳并最終返回鏈接地址。
頁(yè)眉頁(yè)腳插件:這類插件主要用于自動(dòng)在發(fā)布文章首尾添加一些內(nèi)容,如簽名、鏈接等等。
本次需求就是開發(fā)第二類插件,讓用戶輸入源程序代碼,生成符合CSDN樣式的HTML文本。 WLW的插件開發(fā)的大致步驟如下: 創(chuàng)建一個(gè)新的.Net類庫(kù)項(xiàng)目(framework 1.1以上)。
在解決方案資源管理器中右鍵單擊該項(xiàng)目,選擇"添加引用",然后選擇"瀏覽"的選項(xiàng),導(dǎo)入對(duì)WindowsLive.Writer.Api.dll的引用,此文件位于Window Live Writer執(zhí)行文件所在文件夾下,如:C:\Program Files\Windows Live\Writer\。
創(chuàng)建一個(gè)類,繼承自WindowsLive.Writer.Api.ContentSource(如果創(chuàng)建其他類型插件,可能繼承自其他類,可以參看文檔)。
對(duì)這個(gè)類應(yīng)用WindowsLive.Writer.Api.WriterPluginAttribute屬性,以指明插件的名稱、圖標(biāo)及唯一ID等信息。
ContentSource有3個(gè)虛方法:CreateContent()、CreateContentFromLiveClipboard()、CreateContentFromUrl(),根據(jù)源內(nèi)容的輸入方式的不同,后續(xù)的步驟有一定的不同:
對(duì)話框輸入:如果希望點(diǎn)擊插件后,彈出一個(gè)對(duì)話框來讓用戶輸入內(nèi)容;這時(shí)需要為這個(gè)類應(yīng)用WindowsLive.Writer.Api.InsertableContentSourceAttr ibute屬性,然后重載
剪切板輸入:這種模式是先將內(nèi)容復(fù)制到剪切板中(準(zhǔn)確的說應(yīng)該是Live Clipboard,微軟為Web開發(fā)一種數(shù)據(jù)交換技術(shù),采用XML描述),然后點(diǎn)擊插件,插件則直接讀取剪切板中的內(nèi)容作為自己的源;這時(shí)需要為這個(gè)類應(yīng)用WindowsLive.Writer.Api.LiveClipboardContentSourceAttribute屬性,然后重載CreateContentFromLiveClipboard()方法。
URL輸入:根據(jù)WindowsLiveWriterApplication.BlogThisLink中的URL或者粘貼或拖入到編輯器中的URL作為數(shù)據(jù)源輸入;這時(shí)需要為這個(gè)類應(yīng)用WindowsLive.Writer.UrlContentSourceAttribute屬性,然后重載CreateContentFromUrl()方法。
當(dāng)然,有時(shí)候插件可能不需要任何輸入源,只需當(dāng)點(diǎn)擊插件按鈕后輸出信息即可(如個(gè)人簽名、當(dāng)前日期等),則可以以上任選一種方法,在重載函數(shù)中忽略輸入的內(nèi)容即可。
重載方法后,編譯成dll,然后將其放置到Window Live Writer安裝目錄下的Plugins目錄下,重啟WLW,即可以看見新的插件了,也可以在項(xiàng)目的生成后事件添加如下語(yǔ)句,自動(dòng)復(fù)制到插件目錄下進(jìn)行調(diào)試: XCOPY /D /Y /R "$(TargetPath)" "C:\Program Files\Windows Live\Writer\Plugins\",調(diào)試時(shí)只能先啟動(dòng)WLW,然后手動(dòng)附加到進(jìn)程。 為了詳解以上步驟中的幾個(gè)難點(diǎn),下面我列出一個(gè)最簡(jiǎn)單的插件示例。 1:Imports WindowsLive.Writer.Api 2:Imports System.Windows.Forms 3:Imports System.Text 4: 5: Windows Live Writer Plugin for CSDN", _ 8: ImagePath:="blog.bmp", _ 9: PublisherUrl:="http://blog.csdn.net/icefireelf")> _ 10: _ 11:PublicClass PluginAdapter 12:Inherits ContentSource 13:PublicOverridesFunction CreateContent(ByVal dialogOwner As IWin32Window, ByRef content AsString) As System.Windows.Forms.DialogResult 14:Dim ret = MessageBox.Show("是否插入一條問候?", "問候語(yǔ)插件", MessageBoxButtons.OKCancel) 15:If (ret = DialogResult.OK) Then 16: content = "hello" 17:EndIf 18:Return ret 19:EndFunction 20:End Class
WriterPlugin有2個(gè)必填屬性: Id:即上面代碼中的構(gòu)造的第一個(gè)參數(shù),此參數(shù)用于唯一標(biāo)識(shí)一個(gè)插件,必須用GUID,使用項(xiàng)目屬性中程序集的GUID即可。
Name:即上面代碼中的構(gòu)造的第二個(gè)參數(shù),此參數(shù)即WLW的插件欄中顯示的名稱,建議不要太長(zhǎng)。
此外還有幾個(gè)可選屬性: Description:字符串屬性,此參數(shù)即WLW的插件詳細(xì)信息中顯示的內(nèi)容,簡(jiǎn)單描述插件功能。
ImagePath: 圖標(biāo)路徑,此參數(shù)決定WLW參見欄名稱前的圖標(biāo),如果不填則沒有圖標(biāo)。圖標(biāo)須采用16*16的位圖或PNG圖,且必須作為嵌入的資源(將圖標(biāo)添加到工程中,在解決方案資源管理器中右鍵點(diǎn)擊圖標(biāo),選擇"屬性",然后將屬性框中的"生成操作"設(shè)為"嵌入的資源"即可)。注意:如果圖標(biāo)放置在工程目錄下,則直接填圖標(biāo)名稱即可;如果放置在工程目錄的子級(jí)目錄下時(shí),使用"."作為目錄分隔符,例如:將圖標(biāo)放置在工程目錄下的image\目錄中,圖標(biāo)路徑應(yīng)寫為"image.blog.bmp",而非"image\blog.bmp"。
PublisherUrl:發(fā)表者的URL,如果設(shè)置了此屬性,在WLW的插件信息中點(diǎn)擊詳細(xì)信息的文字鏈接時(shí),會(huì)打開此URL。
HasEditableOptions: 詳細(xì)信息里面是否有"選項(xiàng)"按鈕(如下圖所示),此參數(shù)默認(rèn)為False,即不帶"選項(xiàng)"按鈕,當(dāng)其設(shè)置為True時(shí),則必須為本類重載EditOptions()方法,在該方法中,可以啟動(dòng)一個(gè)用于配置插件的窗體,獲取參數(shù),然后保存在配置文件或本類對(duì)象的成員中,共后續(xù)訪問使用。
此屬性本用于定義插件在WLW的"Insert"菜單和"Insert"快捷面板的名稱,但新版的WLW已經(jīng)去除了插入菜單與側(cè)邊欄,因此應(yīng)用此屬性只是為了保持向前兼容。 由上面的代碼可以看出,每個(gè)內(nèi)容插件都對(duì)應(yīng)一個(gè)ContentSource派生類的對(duì)象。那么這個(gè)對(duì)象是如何維護(hù)的呢?對(duì)于每個(gè)Writer的進(jìn)程而言,所有ContentSource實(shí)例都是單例的,即當(dāng)插件對(duì)象創(chuàng)建后,以后每次點(diǎn)擊插件,使用的都是同一個(gè)對(duì)象。所以,如果該對(duì)象擁有任何實(shí)例成員,則其在整個(gè)進(jìn)程的上下文中都是有效的,可以用來存儲(chǔ)一些關(guān)于插件的全局參數(shù)(例如Options屬性)。
ContentSource類繼承自WriterPlugin類,因此也繼承了WriterPlugin.Options屬性與WriterPlugin.Initialize()方法。 WriterPlugin.Options是一個(gè)鍵值對(duì)集合對(duì)象,一般用于保存與查詢插件的參數(shù)記錄(如最后一次的配置)。
WriterPlugin.Initialize()方法在本對(duì)象初始化時(shí)調(diào)用,可以在子類中可以重載此方法,添加自己的初始化行為,但一定不要忘記住在重載方法中調(diào)用基類的Initialize()實(shí)現(xiàn)。
ContentContent方法是本插件的入口,在樣例代碼中,我們實(shí)現(xiàn)了一個(gè)小功能:每次點(diǎn)擊插件,彈出一個(gè)對(duì)話框,詢問用戶是否插入問候語(yǔ),如果用戶點(diǎn)擊確認(rèn),則輸出"hello"的字符串,否則不輸出。此接口的形式如下: public virtual DialogResult CreateContent( IWin32Window dialogOwner, ref string content ); 本方法有兩個(gè)參數(shù): dialogOwner:對(duì)話框的擁有者。
content:從ref可以看出這個(gè)參數(shù)是做為輸出用,即最后輸出編輯區(qū)的內(nèi)容。
如果輸出了內(nèi)容,則返回DialogResult.OK,否則,返回DialogResult.Cancel。 注意:前面提到過,由于ContentSource對(duì)象是單例的,所以在實(shí)現(xiàn)本方法,不應(yīng)該使用任何實(shí)例成員來保存臨時(shí)變量,應(yīng)做到可重入。 Syntax Highlight支持與兩種元素,下面為兩個(gè)例子: 由上可以看出,與的name屬性必須為"code" ,而class屬性里可以指定代碼的語(yǔ)言類型,是否顯示行號(hào)、是否顯示控制條、是否折疊、其實(shí)行號(hào)等屬性,具體如下: 語(yǔ)言項(xiàng) 目前支持的語(yǔ)言項(xiàng)有cpp、c-sharp、css、java、javascript、vb、sql、ruby、delphi、python、php、xhtml
nogutter 如果添加此屬性,將不顯示行號(hào)。
nocontrols 如果添加此屬性,將不會(huì)在代碼塊頂部顯示控制器(包含折疊、打印、復(fù)制等命令)。
collapse 如果添加此屬性,將默認(rèn)折疊代碼。
firstline[value] 如果添加此屬性,行號(hào)從value開始計(jì)數(shù),默認(rèn)值是 1。
showcolumns 如果添加此屬性,將在第一行顯示列號(hào)。
其中代碼內(nèi)容需要用HtmlEncode進(jìn)行編碼,替換掉''等escape符號(hào)。如果查看過CSDN的"插入代碼"輸出的HTML源碼,可以發(fā)現(xiàn)其采用的就是方案,而且到目前為止還存在bug,因?yàn)槠錄]有對(duì)插入c++代碼進(jìn)行Html編碼,所以當(dāng)代碼中有掉''時(shí),會(huì)導(dǎo)致插入代碼錯(cuò)誤。 在了解了Syntax Highlighter的輸出格式后,就可以設(shè)置ContentSource的輸出方式了,我的設(shè)計(jì)是當(dāng)點(diǎn)擊插件后,彈出以下對(duì)話框:
在其中選擇好語(yǔ)言種類和各類配置后,在文本框中輸入代碼,點(diǎn)擊插入后,就按照Syntax Highlighter的格式輸出HTML文本,核心代碼如下: 1:Imports WindowsLive.Writer.Api 2:Imports System.Windows.Forms 3:Imports System.Text 4: 5: Windows Live Writer Plugin for CSDN", _ 8: ImagePath:="blog.bmp", _ 9: PublisherUrl:="http://blog.csdn.net/icefireelf")> _ 10: _ 11:PublicClass PluginAdapter 12:Inherits ContentSource 13: 14:PrivateSub SaveSettings(ByVal cf As CodeForm) 15: Options.SetBoolean("CSDN_EnableFolding", cf.EnableFolding) 16: Options.SetBoolean("CSDN_EnableLineNum", cf.EnableLineNum) 17: Options.SetBoolean("CSDN_EnableToolBar", cf.EnableToolBar) 18: Options.SetInt("CSDN_SelectedIndex", cf.SelectedIndex) 19:EndSub 20: 21:PrivateSub LoadSettings(ByVal cf As CodeForm) 22: cf.EnableFolding = Options.GetBoolean("CSDN_EnableFolding", False) 23: cf.EnableLineNum = Options.GetBoolean("CSDN_EnableLineNum", True) 24: cf.EnableToolBar = Options.GetBoolean("CSDN_EnableToolBar", True) 25:Dim index AsInteger = Options.GetInt("CSDN_SelectedIndex", -1) 26:If (index >= 0) Then 27: cf.SelectedIndex = index 28:EndIf 29:EndSub 30: 31:PublicFunction HtmlEncode(ByVal content AsString) AsString 32:Dim ret AsString = HtmlServices.HtmlEncode(content) 33:Return ret 34:EndFunction 35: 36:PublicOverridesFunction CreateContent(ByVal dialogOwner As IWin32Window, ByRef content AsString) As System.Windows.Forms.DialogResult 37:Try 38: Using cf AsNew CodeForm 39: LoadSettings(cf) 40:If (cf.ShowDialog(dialogOwner) = DialogResult.No OrElseString.IsNullOrEmpty(cf.GetCode)) Then 41:Return DialogResult.No 42:EndIf 43: SaveSettings(cf) 44: content = " 1) Then 54: content &= ":firstline[" & first.ToString & "]" 55:EndIf 56:EndIf 57: 58:If (Not cf.EnableToolBar) Then 59: content &= ":nocontrols" 60:EndIf 61: content &= """>" & HtmlEncode(cf.GetCode()) & "" 62:Return DialogResult.OK 63:End Using 64:Catch ex As Exception 65: MessageBox.Show(ex.Message) 66:Return DialogResult.No 67:EndTry 68:EndFunction 69:End Class
通過代碼可以看出,我選擇了用標(biāo)簽,而沒有采用CSDN的方案,這是因?yàn)閃indows Live Writer目前存在一個(gè)Bug:會(huì)在編輯模式下自動(dòng)將中的回車都刪除,這就會(huì)導(dǎo)致所有代碼被縮成一行(在CSDN網(wǎng)頁(yè)上寫好的代碼用WLW下載下來后千萬不要上傳,因?yàn)樗鼤?huì)修改的格式)。
目前此工程的所有源代碼已經(jīng)上傳至 http://download.csdn.net/source/3156349 ,有興趣的朋友可以下載參考,或者直接編譯后將生成的dll放入WLW的插件目錄直接使用。
2011年04月02日
經(jīng)常寫博客的朋友也許經(jīng)常使用Windows Live Writer,尤其對(duì)于有些程序員來說,時(shí)常輾轉(zhuǎn)于CSDN、Windows Live、cnBlogs等眾多社區(qū),使用WLW對(duì)博客進(jìn)行管理和更新會(huì)方便很多。我最近在寫一些技術(shù)類博客文章的時(shí)候,時(shí)常需要插入代碼,目前也有許多第三方的代碼格式化插件,如"Insert Code"、"Code Snippet"等,這些插件能讓代碼插入后輸出的HTML中產(chǎn)生語(yǔ)法高亮、行號(hào)、隔行陰影等特效,但是與CSDN本身的"插入代碼"功能相比,這些插件輸出的內(nèi)容中會(huì)包含大量的樣式,當(dāng)代碼量較大時(shí),會(huì)造成文章大小急劇地膨脹。
如果要解決內(nèi)聯(lián)樣式造成的HTML膨脹問題,可以采用CSS+JavaScript的解決方案,如著名的的"Syntax Highlighter"項(xiàng)目,但是這需要博客系統(tǒng)和平臺(tái)的支持,Wordpress與CSDN都是采用Syntax Hightlighter。因此,我在研究了幾個(gè)WLW的插件和Syntax Hightlighter的接口后,決定自己開發(fā)一個(gè)利用CSDN本身的"插入代碼"功能的插件。 微軟已經(jīng)在其MSDN上發(fā)布了Windows Live Writer的SDK,其中關(guān)于插件編寫的部分可以參看:Windows Live Writer Plugin API和這篇博客http://www.cnblogs.com/yaoshiyou/archive/2009/11/2 8/1612746.html。
WLW的插件可以分為三類: 發(fā)布通知插件:這類插件主要用于在博客文章發(fā)布前后調(diào)用,可以用來對(duì)內(nèi)容的XHTML進(jìn)行檢查或者在某些條件下取消發(fā)布。
內(nèi)容插件:這類插件用于讓用戶插入某種形式的內(nèi)容,并對(duì)內(nèi)容進(jìn)行格式化處理,例如某些插件可以讓用戶選擇插入本地的一張圖片,然后生成縮略圖上傳并最終返回鏈接地址。
頁(yè)眉頁(yè)腳插件:這類插件主要用于自動(dòng)在發(fā)布文章首尾添加一些內(nèi)容,如簽名、鏈接等等。
本次需求就是開發(fā)第二類插件,讓用戶輸入源程序代碼,生成符合CSDN樣式的HTML文本。 WLW的插件開發(fā)的大致步驟如下: 創(chuàng)建一個(gè)新的.Net類庫(kù)項(xiàng)目(framework 1.1以上)。
在解決方案資源管理器中右鍵單擊該項(xiàng)目,選擇"添加引用",然后選擇"瀏覽"的選項(xiàng),導(dǎo)入對(duì)WindowsLive.Writer.Api.dll的引用,此文件位于Window Live Writer執(zhí)行文件所在文件夾下,如:C:\Program Files\Windows Live\Writer\。
創(chuàng)建一個(gè)類,繼承自WindowsLive.Writer.Api.ContentSource(如果創(chuàng)建其他類型插件,可能繼承自其他類,可以參看文檔)。
對(duì)這個(gè)類應(yīng)用WindowsLive.Writer.Api.WriterPluginAttribute屬性,以指明插件的名稱、圖標(biāo)及唯一ID等信息。
ContentSource有3個(gè)虛方法:CreateContent()、CreateContentFromLiveClipboard()、CreateContentFromUrl(),根據(jù)源內(nèi)容的輸入方式的不同,后續(xù)的步驟有一定的不同:
對(duì)話框輸入:如果希望點(diǎn)擊插件后,彈出一個(gè)對(duì)話框來讓用戶輸入內(nèi)容;這時(shí)需要為這個(gè)類應(yīng)用WindowsLive.Writer.Api.InsertableContentSourceAttr ibute屬性,然后重載
剪切板輸入:這種模式是先將內(nèi)容復(fù)制到剪切板中(準(zhǔn)確的說應(yīng)該是Live Clipboard,微軟為Web開發(fā)一種數(shù)據(jù)交換技術(shù),采用XML描述),然后點(diǎn)擊插件,插件則直接讀取剪切板中的內(nèi)容作為自己的源;這時(shí)需要為這個(gè)類應(yīng)用WindowsLive.Writer.Api.LiveClipboardContentSourceAttribute屬性,然后重載CreateContentFromLiveClipboard()方法。
URL輸入:根據(jù)WindowsLiveWriterApplication.BlogThisLink中的URL或者粘貼或拖入到編輯器中的URL作為數(shù)據(jù)源輸入;這時(shí)需要為這個(gè)類應(yīng)用WindowsLive.Writer.UrlContentSourceAttribute屬性,然后重載CreateContentFromUrl()方法。
當(dāng)然,有時(shí)候插件可能不需要任何輸入源,只需當(dāng)點(diǎn)擊插件按鈕后輸出信息即可(如個(gè)人簽名、當(dāng)前日期等),則可以以上任選一種方法,在重載函數(shù)中忽略輸入的內(nèi)容即可。
重載方法后,編譯成dll,然后將其放置到Window Live Writer安裝目錄下的Plugins目錄下,重啟WLW,即可以看見新的插件了,也可以在項(xiàng)目的生成后事件添加如下語(yǔ)句,自動(dòng)復(fù)制到插件目錄下進(jìn)行調(diào)試: XCOPY /D /Y /R "$(TargetPath)" "C:\Program Files\Windows Live\Writer\Plugins\",調(diào)試時(shí)只能先啟動(dòng)WLW,然后手動(dòng)附加到進(jìn)程。 為了詳解以上步驟中的幾個(gè)難點(diǎn),下面我列出一個(gè)最簡(jiǎn)單的插件示例。 1:Imports WindowsLive.Writer.Api 2:Imports System.Windows.Forms 3:Imports System.Text 4: 5: Windows Live Writer Plugin for CSDN", _ 8: ImagePath:="blog.bmp", _ 9: PublisherUrl:="http://blog.csdn.net/icefireelf")> _ 10: _ 11:PublicClass PluginAdapter 12:Inherits ContentSource 13:PublicOverridesFunction CreateContent(ByVal dialogOwner As IWin32Window, ByRef content AsString) As System.Windows.Forms.DialogResult 14:Dim ret = MessageBox.Show("是否插入一條問候?", "問候語(yǔ)插件", MessageBoxButtons.OKCancel) 15:If (ret = DialogResult.OK) Then 16: content = "hello" 17:EndIf 18:Return ret 19:EndFunction 20:End Class
WriterPlugin有2個(gè)必填屬性: Id:即上面代碼中的構(gòu)造的第一個(gè)參數(shù),此參數(shù)用于唯一標(biāo)識(shí)一個(gè)插件,必須用GUID,使用項(xiàng)目屬性中程序集的GUID即可。
Name:即上面代碼中的構(gòu)造的第二個(gè)參數(shù),此參數(shù)即WLW的插件欄中顯示的名稱,建議不要太長(zhǎng)。
此外還有幾個(gè)可選屬性: Description:字符串屬性,此參數(shù)即WLW的插件詳細(xì)信息中顯示的內(nèi)容,簡(jiǎn)單描述插件功能。
ImagePath: 圖標(biāo)路徑,此參數(shù)決定WLW參見欄名稱前的圖標(biāo),如果不填則沒有圖標(biāo)。圖標(biāo)須采用16*16的位圖或PNG圖,且必須作為嵌入的資源(將圖標(biāo)添加到工程中,在解決方案資源管理器中右鍵點(diǎn)擊圖標(biāo),選擇"屬性",然后將屬性框中的"生成操作"設(shè)為"嵌入的資源"即可)。注意:如果圖標(biāo)放置在工程目錄下,則直接填圖標(biāo)名稱即可;如果放置在工程目錄的子級(jí)目錄下時(shí),使用"."作為目錄分隔符,例如:將圖標(biāo)放置在工程目錄下的image\目錄中,圖標(biāo)路徑應(yīng)寫為"image.blog.bmp",而非"image\blog.bmp"。
PublisherUrl:發(fā)表者的URL,如果設(shè)置了此屬性,在WLW的插件信息中點(diǎn)擊詳細(xì)信息的文字鏈接時(shí),會(huì)打開此URL。
HasEditableOptions: 詳細(xì)信息里面是否有"選項(xiàng)"按鈕(如下圖所示),此參數(shù)默認(rèn)為False,即不帶"選項(xiàng)"按鈕,當(dāng)其設(shè)置為True時(shí),則必須為本類重載EditOptions()方法,在該方法中,可以啟動(dòng)一個(gè)用于配置插件的窗體,獲取參數(shù),然后保存在配置文件或本類對(duì)象的成員中,共后續(xù)訪問使用。
此屬性本用于定義插件在WLW的"Insert"菜單和"Insert"快捷面板的名稱,但新版的WLW已經(jīng)去除了插入菜單與側(cè)邊欄,因此應(yīng)用此屬性只是為了保持向前兼容。 由上面的代碼可以看出,每個(gè)內(nèi)容插件都對(duì)應(yīng)一個(gè)ContentSource派生類的對(duì)象。那么這個(gè)對(duì)象是如何維護(hù)的呢?對(duì)于每個(gè)Writer的進(jìn)程而言,所有ContentSource實(shí)例都是單例的,即當(dāng)插件對(duì)象創(chuàng)建后,以后每次點(diǎn)擊插件,使用的都是同一個(gè)對(duì)象。所以,如果該對(duì)象擁有任何實(shí)例成員,則其在整個(gè)進(jìn)程的上下文中都是有效的,可以用來存儲(chǔ)一些關(guān)于插件的全局參數(shù)(例如Options屬性)。
ContentSource類繼承自WriterPlugin類,因此也繼承了WriterPlugin.Options屬性與WriterPlugin.Initialize()方法。 WriterPlugin.Options是一個(gè)鍵值對(duì)集合對(duì)象,一般用于保存與查詢插件的參數(shù)記錄(如最后一次的配置)。
WriterPlugin.Initialize()方法在本對(duì)象初始化時(shí)調(diào)用,可以在子類中可以重載此方法,添加自己的初始化行為,但一定不要忘記住在重載方法中調(diào)用基類的Initialize()實(shí)現(xiàn)。
ContentContent方法是本插件的入口,在樣例代碼中,我們實(shí)現(xiàn)了一個(gè)小功能:每次點(diǎn)擊插件,彈出一個(gè)對(duì)話框,詢問用戶是否插入問候語(yǔ),如果用戶點(diǎn)擊確認(rèn),則輸出"hello"的字符串,否則不輸出。此接口的形式如下: public virtual DialogResult CreateContent( IWin32Window dialogOwner, ref string content ); 本方法有兩個(gè)參數(shù): dialogOwner:對(duì)話框的擁有者。
content:從ref可以看出這個(gè)參數(shù)是做為輸出用,即最后輸出編輯區(qū)的內(nèi)容。
如果輸出了內(nèi)容,則返回DialogResult.OK,否則,返回DialogResult.Cancel。 注意:前面提到過,由于ContentSource對(duì)象是單例的,所以在實(shí)現(xiàn)本方法,不應(yīng)該使用任何實(shí)例成員來保存臨時(shí)變量,應(yīng)做到可重入。 Syntax Highlight支持與兩種元素,下面為兩個(gè)例子: 由上可以看出,與的name屬性必須為"code" ,而class屬性里可以指定代碼的語(yǔ)言類型,是否顯示行號(hào)、是否顯示控制條、是否折疊、其實(shí)行號(hào)等屬性,具體如下: 語(yǔ)言項(xiàng) 目前支持的語(yǔ)言項(xiàng)有cpp、c-sharp、css、java、javascript、vb、sql、ruby、delphi、python、php、xhtml
nogutter 如果添加此屬性,將不顯示行號(hào)。
nocontrols 如果添加此屬性,將不會(huì)在代碼塊頂部顯示控制器(包含折疊、打印、復(fù)制等命令)。
collapse 如果添加此屬性,將默認(rèn)折疊代碼。
firstline[value] 如果添加此屬性,行號(hào)從value開始計(jì)數(shù),默認(rèn)值是 1。
showcolumns 如果添加此屬性,將在第一行顯示列號(hào)。
其中代碼內(nèi)容需要用HtmlEncode進(jìn)行編碼,替換掉''等escape符號(hào)。如果查看過CSDN的"插入代碼"輸出的HTML源碼,可以發(fā)現(xiàn)其采用的就是方案,而且到目前為止還存在bug,因?yàn)槠錄]有對(duì)插入c++代碼進(jìn)行Html編碼,所以當(dāng)代碼中有掉''時(shí),會(huì)導(dǎo)致插入代碼錯(cuò)誤。 在了解了Syntax Highlighter的輸出格式后,就可以設(shè)置ContentSource的輸出方式了,我的設(shè)計(jì)是當(dāng)點(diǎn)擊插件后,彈出以下對(duì)話框:
在其中選擇好語(yǔ)言種類和各類配置后,在文本框中輸入代碼,點(diǎn)擊插入后,就按照Syntax Highlighter的格式輸出HTML文本,核心代碼如下: 1:Imports WindowsLive.Writer.Api 2:Imports System.Windows.Forms 3:Imports System.Text 4: 5: Windows Live Writer Plugin for CSDN", _ 8: ImagePath:="blog.bmp", _ 9: PublisherUrl:="http://blog.csdn.net/icefireelf")> _ 10: _ 11:PublicClass PluginAdapter 12:Inherits ContentSource 13: 14:PrivateSub SaveSettings(ByVal cf As CodeForm) 15: Options.SetBoolean("CSDN_EnableFolding", cf.EnableFolding) 16: Options.SetBoolean("CSDN_EnableLineNum", cf.EnableLineNum) 17: Options.SetBoolean("CSDN_EnableToolBar", cf.EnableToolBar) 18: Options.SetInt("CSDN_SelectedIndex", cf.SelectedIndex) 19:EndSub 20: 21:PrivateSub LoadSettings(ByVal cf As CodeForm) 22: cf.EnableFolding = Options.GetBoolean("CSDN_EnableFolding", False) 23: cf.EnableLineNum = Options.GetBoolean("CSDN_EnableLineNum", True) 24: cf.EnableToolBar = Options.GetBoolean("CSDN_EnableToolBar", True) 25:Dim index AsInteger = Options.GetInt("CSDN_SelectedIndex", -1) 26:If (index >= 0) Then 27: cf.SelectedIndex = index 28:EndIf 29:EndSub 30: 31:PublicFunction HtmlEncode(ByVal content AsString) AsString 32:Dim ret AsString = HtmlServices.HtmlEncode(content) 33:Return ret 34:EndFunction 35: 36:PublicOverridesFunction CreateContent(ByVal dialogOwner As IWin32Window, ByRef content AsString) As System.Windows.Forms.DialogResult 37:Try 38: Using cf AsNew CodeForm 39: LoadSettings(cf) 40:If (cf.ShowDialog(dialogOwner) = DialogResult.No OrElseString.IsNullOrEmpty(cf.GetCode)) Then 41:Return DialogResult.No 42:EndIf 43: SaveSettings(cf) 44: content = " 1) Then 54: content &= ":firstline[" & first.ToString & "]" 55:EndIf 56:EndIf 57: 58:If (Not cf.EnableToolBar) Then 59: content &= ":nocontrols" 60:EndIf 61: content &= """>" & HtmlEncode(cf.GetCode()) & "" 62:Return DialogResult.OK 63:End Using 64:Catch ex As Exception 65: MessageBox.Show(ex.Message) 66:Return DialogResult.No 67:EndTry 68:EndFunction 69:End Class
通過代碼可以看出,我選擇了用標(biāo)簽,而沒有采用CSDN的方案,這是因?yàn)閃indows Live Writer目前存在一個(gè)Bug:會(huì)在編輯模式下自動(dòng)將中的回車都刪除,這就會(huì)導(dǎo)致所有代碼被縮成一行(在CSDN網(wǎng)頁(yè)上寫好的代碼用WLW下載下來后千萬不要上傳,因?yàn)樗鼤?huì)修改的格式)。
目前此工程的所有源代碼已經(jīng)上傳至 http://download.csdn.net/source/3156349 ,有興趣的朋友可以下載參考,或者直接編譯后將生成的dll放入WLW的插件目錄直接使用。
總結(jié)
以上是生活随笔為你收集整理的Windows Live Writer插件开发经验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 操作 csv 编码问题,繁
- 下一篇: java信息管理系统总结_java实现科