• vc++ express添加自定义模板(二) 利用javascript修改项目模板属性


          这一章我们介绍使用javascript脚本设置项目模板属性,关于visual c++ IDE中利用模板创建项目的内部机制在本章尾的外文文章中已有详细介绍,所以这里我们只是简述一下。

    函数介绍

          当我们使用模板新建工程时,有时会弹出类似图2-1的项目设置对话框,这些对话框都是采用html + css制作出来的(我对于web前端开发并不熟悉,

    win32set

                              图 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项目的文件排列,新建项目中的文件被分为头文件,

          win32guolv                                                                  捕获

                     图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项目模板,来介绍如何创建一个新的自定义模板。

    附:相关外文文档:

    1. Small Application Wizard

    2. Visual C++ Express Custom Wizard

    3. Inside Visual C++ Wizards

  • 相关阅读:
    好不容易通过了算法面试,进了大厂,怎么跟想象中完全不一样?
    有一说一,很多时候加班还是因为效率不高,教你 10 个技巧
    动画解析:图的遍历方式有哪些?
    二分查找就该这样学
    跟零计算机基础的房东女儿讲了一下午的中间人劫持京东事件后,她感激涕零,决定给我免除房租...
    疯狂JAVA讲义学习——基础代码练习——static关键字——static修饰成员变量、修饰成员方法、静态块、静态导包
    疯狂JAVA讲义学习——基础代码练习——类&对象——构造器&成员变量局部变量&方法—— 隐藏和封装
    疯狂JAVA讲义学习——基础代码练习——final关键字——final修饰类、成员变量、成员方法、局部变量
    疯狂JAVA讲义学习——基础代码练习——abstract关键字——抽象类
    My SQL数据库引擎快速指点2
  • 原文地址:https://www.cnblogs.com/nottvlike/p/2871400.html
Copyright © 2020-2023  润新知