VS2008中自定义C++工程模板与修改新建文件默认编码的办法

出处:http://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 至此,捶胸顿足,奋发自强,吐血三升,乃作此文,以兹纪念。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值