Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / JScript.NET

New Class (C++) Wizard with namespaces selection

3.50/5 (16 votes)
18 Aug 2006CPOL4 min read 1   193  
This article shows you some useful tips about coding a wizard. It includes scripts in JScript format, and provides you an edited "New Class" wizard which supports namespaces.

New Class Wizard

Introduction

I'm projecting a class framework (so far I have tried only if some ideas I'd got were feasible) which uses namespaces. Every time I needed to add a class inside a namespace, I have to select "New Item" -> "New class" and edit the class file manually at the beginning and at the end of the file to add "namespace NamespaceName {" and then "}". It was annoying doing it manually so I decided to edit the original wizard to include the namespace field (and a select-like choice for base class selection) as you can see in the image (I used a WTL sample project for the example shot, I don't use WTL, but I got it handy).

I have already worked with wizards (on the CodeProject, there's another of my article on it) and there have been no problems in creating wizard files. The syntax is simple and even, and the MS Visual Studio 2005 offers a new project wizard.. for wizards; wonderful, I thought. But the problem when working with wizards is not in knowing the file format, but knowing how to use the scripts. In fact, MSDN documentation on this is very dispersive, and even if you need to script a JScript file, a vast majority of the MSDN examples are in VB or C#. I don't know JScript well, simply because I don't use it at all (except in wizards), so it was very boring to find what I needed and how to use that then. Finally, I chose to publish not only the new class wizard (which was too little for an article) but also some tips about using JScript and JScript DOM code and project access classes. I think not many serious programmers use JScript in any serious project, and that's why a lot of people are in my condition of ignorance, and so I'll give you some info and links. For JScript experts, this article might not be very useful.

Something on JScript

OK, we will start from the basics; the strings array and so on in the example are in Java syntax (obviously). You can find all functions the you can use on them (and others) on this MSDN page. In the TOC on the left, there are two other useful sections (JScript Functions and JScript Objects). The section I linked to, however, includes all object methods as well. You can find JScript syntax too there.

JScript DOM classes

Something on CodeModel

If you use the VCCodeModel feature, you will have advantages in accessing the CodeDOM. In fact, for example, you can do something like:

JavaScript
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);
}

As you can see in the new version of Visual Studio (8), the DOM has more user friendly ways to access code models. In previous versions, you retrieve the CodeModels collection and then check the type for each CodeModel. A thing to keep in mind is that the CodeModel is organized as a normal DOM, so each node has subnodes and there's a main collection of nodes through which you access the children, as you can see in the example above, where the selProj.CodeModel.Namespaces is not a generic list of all namespaces but only the global namespaces and each of them contains sub-nodes (that is CodeModels contained inside the namespace) which can be classes or interfaces or also other namespaces as well.

In each wizard, as you probabily already know, there's an HTML file which implements the interface and the .js JScript file (both named default.ext). You have access to the wizard with the global var 'window' calling window.external in the htm file and with 'wizard' inside the js file.

Because I didn't save in my bookmarks other useful resources or links I found while editing the wizard, I can't be more useful than this because I don't remember them. But if you are curious, there's the code below I used to search, and a list of namespaces and classes, even if it's not a very good code (as I said, I don't know JScript at all). Also because I wrote it very fast thinking, "oh please do your job script", probably you'll find some lines useful for your purposes (or at least interesting).

JavaScript
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;
        }
    }
}

The sort function is not perfect yet, but it was enough for me.

Conclusions

I know this is not a great article and it says nothing new, but I think the improved wizard in the setup in the download section would be useful to someone.

So, that's all, I think. I hope you'll find it useful, bye!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)