65.9K
CodeProject 正在变化。 阅读更多。
Home

带命名空间选择的新类(C++)向导

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.50/5 (15投票s)

2006 年 8 月 18 日

CPOL

4分钟阅读

viewsIcon

38165

downloadIcon

193

本文向您展示了一些关于编写向导的有用技巧。它包含 JScript 格式的脚本,并为您提供了一个已编辑的“新建类”向导,该向导支持命名空间。

New Class Wizard

引言

我正在规划一个类框架(到目前为止,我只尝试过一些想法是否可行),它使用命名空间。每次我需要在命名空间中添加一个类时,我都必须选择“新建项”->“新建类”,然后在文件的开头和结尾手动编辑类文件,以添加“namespace NamespaceName {”然后是“}”。手动完成这些操作很烦人,所以我决定编辑原始向导,加入命名空间字段(以及一个用于选择基类的类似选择的控件),正如您在图片中看到的(我使用了 WTL 示例项目来拍摄截图,我不用 WTL,但我手边有)。

我之前已经处理过向导(在 CodeProject 上,有我另一篇关于向导的文章),创建向导文件没有遇到任何问题。语法简单且统一,MS Visual Studio 2005 提供了一个新的项目向导……用于向导;我心想,太棒了。但是,处理向导的问题不在于了解文件格式,而在于了解如何使用脚本。事实上,MSDN 关于这方面的文档非常分散,即使您需要编写 JScript 文件,MSDN 示例绝大多数都是 VB 或 C#。我对 JScript 不是很了解,仅仅是因为我根本不使用它(除了在向导中),所以找到我需要的东西以及如何使用它非常枯燥。最后,我选择发布不仅是新的类向导(这对于一篇文章来说太少了),还包括一些关于使用 JScript 和 JScript DOM 类以及项目访问类(classes)的技巧。我认为没有多少严肃的程序员在任何严肃的项目中使用 JScript,这就是为什么很多人和我一样处于无知状态,所以我会给您一些信息和链接。对于 JScript 专家来说,这篇文章可能没什么用。

关于 JScript 的一些内容

好的,我们将从基础开始;示例中的字符串数组等是 Java 语法(显然)。您可以在 这个 MSDN 页面 上找到所有您可以使用的函数(以及其他函数)。在左侧的目录中,还有两个其他有用的部分(JScript Functions 和 JScript Objects)。但我链接的那个部分,包含了所有对象方法。您也可以在那里找到 JScript 语法。

JScript DOM 类

关于 CodeModel 的一些内容

如果您使用 VCCodeModel 功能,您将在访问 CodeDOM 方面获得优势。事实上,例如,您可以这样做:

function OnFinish(selProj, selObj)
{
    //Get the Global-Namespace collection in the project.

    //That is, namespace not inside other namespace or CodeElement

    var nss = selProj.CodeModel.Namespaces;
    
    //Get Namespace collection of first global namespace

    var nss2 = nss.Item(1).Namespaces;
    
    //Get Firs class in first sub-namespace

    var cl1 = nss2.Classes.Item(1);
}

正如您在 Visual Studio (8) 的新版本中可以看到的,DOM 提供了更友好的方式来访问代码模型。在早期版本中,您需要检索 CodeModels 集合,然后检查每个 CodeModel 的类型。需要注意的一点是,CodeModel 的组织方式与普通 DOM 类似,因此每个节点都有子节点,并且有一个主集合,通过它可以访问子节点,如上例所示,其中 selProj.CodeModel.Namespaces 并不是一个通用的列表,而是所有命名空间,每个命名空间都包含子节点(即命名空间内部包含的 CodeModels),这些子节点可以是类、接口,也可以是其他命名空间。

在每个向导中,您可能已经知道,都有一个实现界面的 HTML 文件和一个 .js JScript 文件(两者都命名为 default.ext)。您可以通过全局变量 'window' 在 htm 文件中调用 window.external 来访问向导,并在 js 文件中通过 'wizard' 来访问。

由于我在编辑向导时找不到其他有用的资源或链接,因此我无法提供更多帮助,因为我不记得它们了。但如果您好奇,下面是我用来搜索的代码,以及一个命名空间和类的列表,尽管它不是很好的代码(如我所说,我根本不了解 JScript)。而且因为我写得很快,想着“哦,请完成你的工作吧,脚本”,所以您可能会发现一些行对您有用(或者至少有趣)。

function InitDocument(document)
{
     /* 
     VS generated code
     .
     .
     .
     */       
 
    if (window.external.ProjectObject) {
        var proj = window.external.ProjectObject;
        var codeModel = proj.CodeModel;
        
         var nssArr, nsArr = new Array();
        GetNamespaces(codeModel.Namespaces,nsArr,"");
        nssArr = nsArr.sort();
        
        for (var i = 0; i < nssArr.length; i++) {
          var oOption = document.createElement("OPTION");
          oOption.value = nssArr[i];
          oOption.text = nssArr[i];
          NAMESPACE.add(oOption);
        }
        
          var oOption = document.createElement("OPTION");
          oOption.value = "<new>";
          oOption.text = "<new>";
          NAMESPACE.add(oOption);
        
        var cllArr, clArr = new Array();
        GetClasses(codeModel.Classes,clArr,"");
        GetNamespaceClasses(codeModel.Namespaces,clArr,"");
        clArr = clArr.sort();
        cllArr = clArr.sort(SortClasses);
        
        for (var i = 0; i < cllArr.length; i++) {
          var oOption = document.createElement("OPTION");
          oOption.value = cllArr[i];
          oOption.text = cllArr[i];
          BASE_CLASSES.add(oOption);
        }
        
          var oOption = document.createElement("OPTION");
          oOption.value = "<new>";
          oOption.text = "<new>";
          BASE_CLASSES.add(oOption);
    }
}

function GetNamespaces(nss,nsArr,name)
{
    for (var i = 1; i <= nss.Count; i++) {
        var ns = nss.Item(i);
        var l = 0;
        var nname = ns.Name;
        if (name != "")
        {
           nname = name + "::" + nname;
        }
      for (l = 0; l < nsArr.length; l++) {
        if (nsArr[l] == nname) {
         break;
        }
      }
      if (l == nsArr.length)
      {
        nsArr[l] = nname;
      }
      GetNamespaces(ns.Namespaces,nsArr,nname);
    }
}

function GetClasses(cls,clArr,name)
{
    for (var i = 1; i <= cls.Count; i++) {
        var cl = cls.Item(i);
            var l = 0;
            var nname = cl.Name;
            if (name != "")
            {
               nname = name + "::" + nname;
            }
          for (l = 0; l < clArr.length; l++) {
            if (clArr[l] == nname) {
             break;
            }
          }
          if (l == clArr.length)
          {
            clArr[l] = nname;
          }
          GetClasses(cl.Classes,clArr,nname);
    }
}


function GetNamespaceClasses(nss,clArr,name)
{
    for (var i = 1; i <= nss.Count; i++) {
        var ns = nss.Item(i);
        var l = 0;
        var nname = ns.Name;
        if (name != "")
        {
           nname = name + "::" + nname;
        }
        
        GetClasses(ns.Classes,clArr,nname);
        
        GetNamespaceClasses(ns.Namespaces,clArr,nname);
    }
}

function SortClasses(arr1,arr2)
{
    var arr = arr1.split("::");
    var arrs = arr2.split("::");
    
    if (arr.length > arrs.length)
    {
        return 1;
    }
    else if (arrs.length > arr.length)
    {
        return -1;
    }
    else
    {
        var i;
        for (i = 0; i < arr.length-1; i++)
        {
           if (arrs[i] != arr[i])
           {
             break;
           }
        }
        
        if (i == (arrs.length-1))
        {
            var l = 0;
            while (arr[i][l] == arrs[i][l] && l < 
                   arr[i].length && l < arrs[i].length)
            {
              l++;
            } 
            if (l < arr[i].length || l < arrs[i].length)
            {
               if (arr[i][l] > arrs[i][l])
               {
                    return 1;
               }
               else
               {
                      return -1;
               }
            }
            else
            {
                return 0;
            }
        }
        else
        {
            return 0;
        }
    }
}

排序函数还不完美,但对我来说已经足够了。

结论

我知道这不是一篇很棒的文章,也没有提供任何新内容,但我认为下载部分提供的改进的向导对某些人来说会很有用。

所以,我想就这些了。希望您觉得有用,再见!

© . All rights reserved.