这一章我们介绍使用javascript脚本设置项目模板属性,关于visual c++ IDE中利用模板创建项目的内部机制在本章尾的外文文章中已有详细介绍,所以这里我们只是简述一下。
函数介绍
当我们使用模板新建工程时,有时会弹出类似图2-1的项目设置对话框,这些对话框都是采用html + css制作出来的(我对于web前端开发并不熟悉,
图 2-1 Application项目设置
此处难免有笔误),包含了与项目相关的变量如WIN_APP,CONSOLE_APP,DLL_APP,LIB_APP,EMPTY_PROJECT等,将会在以后设置项目属性时用到。最后当我们点击完成时文件scripts/2052/default.js中的OnFinish(selProj , selObj)函数就会被调用来设置编译器链接器属性并创建新项目。
文件夹scripts/2052中的default.js文件主要有五个函数
-
OnFinish(selProj , selObj) : 当用户点击完成按钮后将调用此函数(像Win32控制台程序当点击创建项目后会直接调用此函数),然后调用GetAppType()得到项目类型,调用AddSpecificConfig()设置编译器和链接器属性,最后创建工程。
-
SetFileProperties(projfile , strName) :不明
-
GetTargetName(strName , strProjectName , strResPath , strHelppath) :更改文件名,这将在稍后介绍。
-
GetAppType() :得到项目类型(exe , dll , lib)。
-
AddSpecificConfig(proj, strProjectName, bEmptyProject, strAppType) :设置编译器和链接器属性。
下面我们主要介绍OnFinish(selProj , selObj )函数,如代码 1-1所示,此函数在13行创建一个新的项目文件,就是vcxproj文件和sln文件(编译器与链接器属性设置都在vcxproj文件中),然后通过前面提到过的变量来修改项目属性。
1: function OnFinish(selProj, selObj)
2: {
3: //selProj是我们将创建的工程对象
4: try
5: {
6: var strProjectPath = wizard.FindSymbol("PROJECT_PATH");//工程路径
7: var strProjectName = wizard.FindSymbol("PROJECT_NAME");//工程名
8:
9: var bEmptyProject = wizard.FindSymbol("EMPTY_PROJECT");//是否建立空工程
10:
11: wizard.AddSymbol("RC_FILE_NAME",CreateSafeRCFileName(strProjectName) + ".rc");
12:
13: selProj = CreateProject(strProjectName, strProjectPath);//建立工程
14: selProj.Object.Keyword = "Win32Proj";
15:
16: AddCommonConfig(selProj, strProjectName);//添加常规编译器,链接器设置
17: var strAppType = GetAppType(); //得到项目输出类型(exe,dll或lib)
18: AddSpecificConfig(selProj, strProjectName, bEmptyProject, strAppType);//添加自定义设置
19:
20: SetupFilters(selProj);//文件过滤,稍后介绍
21:
22: if (!bEmptyProject)
23: {
24: SetResDlgFont();
25: //是否添加预编译头
26: var Pch = wizard.FindSymbol("PRE_COMPILED_HEADER");
27: //(项目输出为LIB || 项目类型为控制台 ) && 项目不支持MFC && 项目不支持ATL && 项目不支持预编译头
28: if ((strAppType == "LIB" || ((strAppType == "CONSOLE") &&
29: !wizard.FindSymbol("SUPPORT_MFC") && !wizard.FindSymbol("SUPPORT_ATL"))) && !Pch)
30: {
31: //添加文件到项目
32: AddFilesToProjectWithInfFile(selProj, strProjectName);
33: //设置不适用预编译头
34: SetNoPchSettings(selProj);
35: }
36: else
37: {
38: AddFilesToProjectWithInfFile(selProj, strProjectName);
39: SetCommonPchSettings(selProj);
40: }
41: }
42: selProj.Object.Save();
43: }
44: catch(e)
45: {
46: if (e.description.length != 0)
47: SetErrorInfo(e);
48: return e.number
49: }
50: }
代码 1-1
代码 1-1中13行的CreateProject()函数在[vcdir]\VC\VCWizards\2052\common.js中定义,应该说与我们建立模板相关的js函数都可以在这个文件中找到。由代码 1-2我们可以知道CreateProject()仅仅将default.vcxproj拷贝到新建项目文件夹并重命名,这使得我们可以使用简便方法来建立新模板。
1: function CreateProject(strProjectName, strProjectPath)
2: {
3: try
4: {
5: var strProjTemplatePath = wizard.FindSymbol("PROJECT_TEMPLATE_PATH");
6: //vcxproj文件,这个default.vcxproj就是上一章介绍的,CreateProject()主要通过这个文件建立新项目
7: var strProjTemplate = strProjTemplatePath + "\\default.vcxproj";
8: //sln文件
9: var Solution = dte.Solution;
10: var strSolutionName = "";
11: if (wizard.FindSymbol("CLOSE_SOLUTION"))
12: {
13: Solution.Close();
14: strSolutionName = wizard.FindSymbol("VS_SOLUTION_NAME");
15: if (strSolutionName.length)
16: {
17: var strSolutionPath = strProjectPath.substr(0, strProjectPath.length - strProjectName.length);
18: Solution.Create(strSolutionPath, strSolutionName);
19: }
20: }
21:
22: var strProjectNameWithExt = strProjectName + ".vcxproj";
23: var oTarget = wizard.FindSymbol("TARGET");
24: var oProj;
25: if (wizard.FindSymbol("WIZARD_TYPE") == vsWizardAddSubProject) // vsWizardAddSubProject
26: {
27: var prjItem = oTarget.AddFromTemplate(strProjTemplate, strProjectPath + "\\" + strProjectNameWithExt);
28: oProj = prjItem.SubProject;
29: }
30: else
31: {
32: oProj = oTarget.AddFromTemplate(strProjTemplate, strProjectPath, strProjectNameWithExt);
33: }
34: return oProj;
35: }
36: catch (e)
37: {
38: throw e;
39: }
40: }
代码 1-2 CreateProject()函数
OnFinish()中的SetupFilters()函数主要起到文件过滤的作用,图2-2显示了我们新建的Win32项目的文件排列,新建项目中的文件被分为头文件,
图2-3 项目文件分类 图 2-4 项目默认文件
源文件还有资源文件,通过文件后缀名对文件进行分类,就是这个函数的作用。
在default.js中还有两个函数SetFileProperties(projfile , strName) , GetTargetName()并未被OnFinish()调用,它们将被common.js中的函数回调。当我们新建Win32工程时,默认会添加Resource.h , stdafx.h , targetver.h win32.h等文件,其实这些文件都在application模板主体文件夹Application\templates\2052里,如图2-4所示,其中Templates.inf会通过项目设置来筛选文件,例如如果我们创建空项目,就不会复制文件到新建项目文件夹,如果我们没有选中预编译头,stdafx.h和stdafx.cpp就不会被复制到新建项目文件夹。当文件被复制到新建项目文件夹中后,GetTargetName()就会修改部分的文件名时期与项目名称相同,当然有些文件内容也会被修改,这点大家看看这几个文件就可以了解了。
编译器与链接器设置
AddCommonConfig()与AddSpecificConfig()都是设置编译器与链接器选项,这里我们通过讲解AddSpecificConfig()来介绍项目模板中的编译器与链接器设置。代码 1-3显示了编译器与链接器设置的一个大纲,当然这只是代表了我的习惯(这样代码会清晰,但有时候会有重复定义)。与编译器与链接
1: function AddSpecificConfig(proj, strProjectName, bEmptyProject, strAppType)
2: {
3: try
4: {
5: //Debug选项
6: var config = oProj.Object.Configurations("Debug");
7: //Debug的编译器设置
8: var CLTool = config.Tools("VCCLCompilerTool");
9: //Debug的链接器设置
10: var LinkTool = config.Tools("VCLinkerTool");
11:
12: //Release选项
13: config = oProj.Object.Configurations("Release");
14: //Release的编译器设置
15: CLTool = config.Tools("VCCLCompilerTool");
16: //Release的链接器设置
17: LinkTool = config.Tools("VCLinkerTool");
18: }
19: catch (e)
20: {
21: throw e;
22: }
23: }
代码 1-3 编译器与链接器设置
器设置相关的变量将会在附录一中给出,或者大家也可以从微软相关网页来找到更详细的介绍。代码1-4介绍了部分编译器与链接器设置。
1: var config = oProj.Object.Configurations("Debug");
2: //输出目录
3: config.OutputDirectory = "H:\\OgreSDK_vc9_v1-8-0\\bin\\Debug\\ ";
4: var CLTool = config.Tools("VCCLCompilerTool");
5: //debug编译器设置
6: //警告等级
7: CLTool.WarningLevel = warningLevel_3; //warningLevel_0: 关闭所有警告 ; warningLevel_4 : ;
8: //内联函数扩展
9: CLTool.InlineFunctionExpansion = expandDisable //0 默认值 | expandDisable 禁用 | expandOnlyInline 只适用于 _inline | expandAnySuitable 适用于任何项 |
10: //优化
11: CLTool.Optimization = optimizeDisabled;//optimizeDisabled Disabled (/Od) ; optimizeMinSpace Minimize Size (/O1)
12: //optimizeMaxSpeed Maximize Speed (/O2) ; optimizeFull Full Optimization (/Ox)
13: //optimizeCustom Custom
14: //预处理器定义
15: CLTool.PreprocessorDefinitions += ";WIN32";
16:
17: //debug链接器设置
18: var LinkTool = config.Tools("VCLinkerTool");
19: //启用增量链接
20: LinkTool.LinkIncremental = linkIncrementalYes; //linkIncrementalDefault Default ; linkIncrementalNo No (/INCREMENTAL:NO)
21: //linkIncrementalYes Yes (/INCREMENTAL)
22: //附加依赖项
23: LinkTool.AdditionalDependencies += " OIS_d.lib OgreMain_d.lib";
代码1-4 编译器与链接器设置实例
这一章我们主要讲解了使用javascript设置项目模板,基本的介绍了visual c++ express自定义模板的相关知识。下一章我们以OGRE项目模板,来介绍如何创建一个新的自定义模板。
附:相关外文文档: