VS2008中自定義C++工程模板與修改新建文件默認編碼的辦法

VS2008中自定義C++工程模板與修改新建文件默認編碼的辦法

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

討論新聞組及文件

一、   需求

網上講VS(以下VS均特指VS2008)自定義模板的不少,不過大部分都是講C#或者Web開發的,什麼export template的,都不適合C++工程,由於MS的確是減弱了對C++的支持,(這點沒有人否認吧?)所以在VS中C++總是被遺忘在那個沒有人理睬的角落,所以現在很多人寧願還用着C++與MFC最輝煌的版本VC6.0,哪怕那個版本的C++這麼不符合標準。。。。。既然MS不關心C++使用者,那就只有自己奮發圖強羅,還好再怎麼樣,沒有了VS,我們總還是有VIM+G+++GDB/Emacs的,沒有了MFC我們還有Qt,GTK+的,何況個人用Eclipse在Linux下做Qt程序的感覺也不錯,閒話不說了,看看正題。

自定義工程模板是用途很大的,當你有一個簡單的模板用於開發的時候,沒有VS內部的支持時,你有兩種辦法,其一你將原有整個工程拷貝一份,然後改工程名(在我以前的公司就是這樣乾的),改名不說,要進VSS,還得改工程的GUID(不懂的就算了),其二是新建一個工程,然後一個一個添加文件,假如有自己的目錄結構的時候,還得重新控制目錄結構,工程大時也是異常麻煩,其實這些用上了VS自定義模板,一切都可以很簡單,就像你進行Win32 SDK,MFC開發MS給你的模板一樣。

修改VS中新建文件的默認編碼嘛,純Windows人士請忽略,我是因爲需要在Linux下編輯和查看這些文件纔有此需求。事實上,即使想要在Linux下查看或者編輯這些代碼也可以不做改變,但是我就是想將其全部改成UTF8,不喜歡將Linux下設置一大堆東西,gcc需要加gb2312的選項,vim需要加配置,Eclipse也需要改配置,其他文本編輯工具也需要選定編碼,全部是因爲VS在中文Windows下的默認編碼是gb2312(我用的是英文VS2008,這個可能是跟着操作系統環境走的),雖然也不怪MS。。。。既然VS也支持UTF8,就讓Windows遷就Linux了。。。。還需要遷就的是Linux下的換行與Windows不同,順面一起解決了,雖然大部分時候,在公司,都是用Linux的東西來遷就Windows。修改默認編碼的辦法我在網上找了很久也沒有找到,大部分人都說是直接用Advanced Save Option來選擇保存,那樣多麻煩啊,或者先建立工程以後用find批量改,那樣也不見的簡單啊。。。。。。。。看下面的解決辦法。

 

二、   解決辦法

1.      新建文件

奧祕在Microsoft Visual Studio 9.0/VC/vcprojectitems中(Microsoft Visual Studio 9.0根據你安裝目錄而定)

新建的C++文件,主要是newc++file.cpp這個文件,目前是空的,你將其改成什麼樣,那就是什麼樣,比如,我需要在每個文件的頭部添加一大串的GPL說明,(不是我想,這是FSF規定的),那麼就直接在此文件添加我的文件頭即可,以後用add->add new item->C++ files時,就都會自動帶着文件頭出來了。。。更好用的是,我現在將此文件轉爲UTF8+Unix換行格式,那麼以後新建的文件都是如此了。。。呵呵,此謂之一勞永逸。

新建的頭文件是hfile.h這個文件,如上更改,一勞永逸。事實上,我將上面的文件複製一份,重命名爲hfile.h^^

普通文本文件由於常做Readme用,也改了。是text.txt這個文件。

 

2.      授人以魚不如授人以漁

我當然不是一個一個文件試出來的,也不是猜出來的,授人以魚不如授人以漁,這裏告訴大家怎麼去自己摸索。上述三個文件有個共同特點,那就是可以通過右鍵add->new item,那麼我首先查看的就是new item了,這裏,我的Visual C++下的下面有UI,Code,Data,Resource,Web,Utility,Property Sheets7個選項,與Microsoft Visual Studio 9.0/VC/vcprojectitems下面的7個目錄及目錄名一一對應,很明顯了,這些選項由此7個目錄中的內容控制的,首先看Code目錄,一個code.vsdir的文件,打開一看

 ../NewC++File.cpp|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1075|10|#1076|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|9031|4096|#1077

../HFile.h|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1078|15|#1079|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|9030|4096|#1080

../IDLFile.idl|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1084|20|#1085|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|9035|4096|#1086

../DEFFile.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1087|35|#1088|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|9036|4096|#1089

../addmc++componentclass.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1236|85|#1237|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|9563|4096|#1238

../installer.vsz|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|#1245|85|#1246|{1B027A40-8F43-11D0-8D11-00A0C91BC942}|9564|4096|#1247

咋一看,亂碼?2進制文件?的確像,再仔細看看,前面的一部分,那不就是菜單中有的Items項?一一對應的。再仔細看,發現其實前面的字符串都是一個目錄,指向父目錄下的各個文件,其中前面兩個就是.. /NewC++File.cpp,.. /HFile.h兩個文件,那就是上一節中我發現的兩個文件,對應新添加的C++文件和頭文件。vsdir後面的東西是更詳細的說明,長串的{}是GUID,#xxx是通過ID來表示資源。但是這裏我們不去詳細瞭解了,想要詳細瞭解的參看MSDN這裏,同理,文本文件在Utility目錄下的VCUtilityItems.vsdir制定的,我就不多說了。

 

3.      自定義工程模板

新建工程中有個Custom Wizard選項,我將其命名爲Win32OpenGLWizard。建立以後是一個完整的Wizard工程,天哪,一看,真複雜,我僅僅想建立一個簡單的C++工程嘛,至於這樣複雜嗎?很顯然,MS設計VS的自定義模板的時候就是給其他軟件開發商用的,根本沒有考慮過個人使用-_-!因爲其中包含了HTML,CSS,JS….並不是每個人都是做網頁的**。。。。作爲用C++的我們,就知道想辦法摸索摸索羅,符合我們的要求就好。要將引導框設計的多麼完美我個人是沒有什麼希望了。所以建立Win32OpenGLWizard工程時,用戶的UI選擇就不需要了吧,直接通過名字就好。

首先利用剛纔新建的Wizard去建立一個工程,(會出現在New Project的Wizard下,實際的文件放在 我的文檔/Visual Studio 2008/Wizards中)發現我們主要關注的是Template Files下的兩個文件,那就是生成後工程會包含的文件。嘗試一下。

在template Files下添加main.cpp,修改Readme.txt,刪除sample.txt,實際操作時請將文件添加到/Templates/1033目錄下面去,並且手動修改Templates.inf添加進main.cpp。新建工程後果然可行。

 

4.      修改自定義工程模板

有個問題是Readme.txt在Source File目錄下,而main.cpp跑到Source Files外面去了。作爲半個完美主義者,雖然工程已經能編譯通過,但是還是有點不爽,我希望進一步改進,那麼下一步看看Source Files是哪裏規定的羅,在default.js中可以看到

function AddFilters(proj)

{

       try

       {

              // Add the folders to your project

              var strSrcFilter = wizard.FindSymbol('SOURCE_FILTER');

              var group = proj.Object.AddFilter('Source Files');

              group.Filter = strSrcFilter;

       }

       catch(e)

       {

              throw e;

       }

}

此函數,已經明白一半了,此函數不就是尋找匹配的過濾文字,然後將其加入Source Files中去嘛。^^就看SOURCE_FILTER是什麼symbo了

這裏分兩種情況:

無wizard UI

假如沒有添加Wizards UI可以在添加的wizard工程下看到一個vsz文件,我這裏如下:

VSWIZARD 7.0

Wizard=VsWizard.VsWizardEngine.9.0

 

Param="WIZARD_NAME = Win32OpenGL"

Param="ABSOLUTE_PATH = D:/MyDocument/Visual Studio 2008/WizardTemplate/Win32OpenGL/Win32OpenGL"

Param="FALLBACK_LCID = 1033"

Param="WIZARD_UI = FALSE"

Param="SOURCE_FILTER = txt"

 

這就是一個簡單的類INI文件,詳細信息可以參考MSDN這裏。我們關心的自然是SOURCE_FILTER參數,改成cpp,竟然沒有效果,不知道其他人怎麼樣,我這裏沒有效果的原因不明。但是雖然不知道此js 的wizard.FindSymbol的實現方法,但是我們還是可以用暴力解決!呵呵,將上述js函數改成如下形式:

 function AddFilters(proj)

{

       try

       {

              // Add the folders to your project

              //var strSrcFilter = wizard.FindSymbol('SOURCE_FILTER');

              var strSrcFilter = 'cpp';

              var group = proj.Object.AddFilter('Source Files');

              group.Filter = strSrcFilter;

       }

       catch(e)

       {

              throw e;

       }

}

就好了。我得意的笑啊,我得意的笑^^對於MS奇怪的失靈,有的時候暴力也是必須的。

 

有wizard UI

假如添加了UI,MS就要考慮你在wizard UI中改變此Symbo的可能了,會在HTML/1033/default.htm這個UI管理文件下看到

<SYMBOL NAME='SOURCE_FILTER' TYPE=text VALUE='txt'></SYMBOL>

改之

<SYMBOL NAME='SOURCE_FILTER' TYPE=cpp VALUE='cpp'></SYMBOL>

有效。

再次創建工程,cpp文件已經在Source Files中了,ReadMe.txt也死出去了,以後再需要頭文件什麼的也一樣處理就好了。

 

5.      接近完美

好了嗎?已經很好了,但是作爲3/4個完美主義者,我還有有點想改的地方,那就是我平時建工程,很簡單的工程主文件與工程名一直,這樣萬一哪天想全部拷貝到一起管理也方便,但是按上述方式文件將全部是main.cpp,解決之,電腦上沒有咋程序員解決不了的事情。

看上述js腳本,如下函數:

function GetTargetName(strName, strProjectName)

{

       try

       {

              // TODO: set the name of the rendered file based on the template filename

              var strTarget = strName;

 

              if (strName == 'readme.txt')

                     strTarget = 'ReadMe.txt';

 

              if (strName == 'sample.txt')

                     strTarget = 'Sample.txt';

 

              return strTarget;

       }

       catch(e)

       {

              throw e;

       }

}

 

再看看它的使用,就知道此處就是我們需要修改的地方,實際上MS已經考慮了這樣的情況了,我們不需要暴力^^改成如下內容:

function GetTargetName(strName, strProjectName)

{

       try

       {

              // TODO: set the name of the rendered file based on the template filename

              var strTarget = strName;

 

              if (strName == 'readme.txt')

                     strTarget = 'ReadMe.txt';

 

              if (strName == 'main.cpp')

                     strTarget = strProjectName + ".cpp";

 

              return strTarget;

       }

       catch(e)

       {

              throw e;

       }

}

測試,OK!

 

三、   後記

所有的說明,版權信息都在,文件內容,編碼,換行符都搞定了,文件名也符合我的要求了,接近完美,鑑定完畢!

此過程發狂的得不到MSDN滿篇.Net的幫助,又難領悟廣大C#網民的旁敲側擊,獨自在VS的漆黑中摸索,逢JS大山則開路,逢HTML大石則劈之,屢次撞壁,失敗數回,嘆MS之棄cpper至此,捶胸頓足,奮發自強,吐血三升,乃作此文,以茲紀念。

 轉自:http://blog.csdn.net/vagrxie/article/details/4665035

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章