Custom wizards in MS Visual Studio 2003 for C++ projects

(August 7, 2003)

Introduction

C++ as no other language stores code in a lot of files. Separating declaration from definition is a must in C++ development. Using folders in VS IDE, we can form some structure in our projects as shown in picture below.

folders

Still for each new class we need to manually create h/cpp pair, place guard header in h file, include header file in cpp file. VS has Add Class feature, but it places new class in the root of source files, not into selected IDE folder.

The custom wizard, which we are going to create, will allow us to select IDE folder and new class name. Then it will automatically create h and cpp files on disk, fill h and cpp files with code template using new class name, add this h/cpp pair to VS project into selected IDE folder.

Creating wizard

VS has a template for custom wizards. It's a good place to start from, so in VS IDE select in main menu File - New - Project. In New Project dialog select Visual C++ Projects - General project type and Custom Wizard template. As project name type in Add Class (make sure Close Solution radiobutton is on, not Add to Solution) and press OK. In Custom Wizard - Add Class dialog on Application Settings page uncheck User Interface checkbutton and press Finish.

Now you have a solution with a code in default.js file. This file contains OnFinish function which does all wizard work (it called after you enter new class name to create). You can replace whole default.js, browse for it in Solution Explorer, with a code below.

function OnFinish(selProj, selObj)
{
    try {
      var className = wizard.FindSymbol('ITEM_NAME');
      var fullFileNameH = wizard.FindSymbol('PROJECT_PATH') + className + ".h"
      var fullFileNameCpp = wizard.FindSymbol('PROJECT_PATH') + className + ".cpp"

      addFileToSolutionExplorerFolder(fullFileNameH, selProj);
      addFileToSolutionExplorerFolder(fullFileNameCpp, selProj);

      writeTemplateH(createFileOnDisk(fullFileNameH), className);
      writeTemplateCpp(createFileOnDisk(fullFileNameCpp), className);
    } catch(e) {
        if (e.description.length != 0)
            SetErrorInfo(e);
        return e.number
    }
}

function writeTemplateH(file, className){
    var uniqueString = className + "_" + uid();
    file.WriteLine("#ifndef " + uniqueString);
    file.WriteLine("#define " + uniqueString);
    file.WriteLine();
    file.WriteLine("class " + className + "{");
    file.WriteLine();
    file.WriteLine("};");
    file.WriteLine();
    file.WriteLine("#endif");
}

function writeTemplateCpp(file, className){
    file.WriteLine('#include "stdafx.h"');
    file.WriteLine("#include " + '"' + className + '.h"');
    file.WriteLine();
}

function createFileOnDisk(fullFileName){
    var fso = new ActiveXObject('Scripting.FileSystemObject');
    var file = fso.CreateTextFile(fullFileName, true, false);
    return file;
}

function addFileToSolutionExplorerFolder(fullFileName, selProj){
    var folder
    if (dte.SelectedItems(1).Name != "Source Files"){
        folder = selProj.Object.Filters.Item("Source Files").Filters.Item(dte.SelectedItems(1).Name);
    } else {
        folder = selProj.Object.Filters.Item(dte.SelectedItems(1).Name);
    }
    folder.AddFile(fullFileName);
}

function uid(){
    var date = new Date();
    return "" + date.getHours() + date.getMinutes() + date.getSeconds();
}

Installing wizard

The wizard template in VS which we used is actually for project wizards, i.e. you can use it when creating new Visual C++ project. But we want to use it from Add New Item context menu. So, you have to move 3 files Add Class.ico, Add Class.vsdir and Add Class.vsz from Microsoft Visual Studio .NET 2003\Vc7\vcprojects directory to Microsoft Visual Studio .NET 2003\Vc7\vcprojectitems directory. I also recommend to edit default Add Class.ico to something more bright.

That's all. Now, when you'll open C++ solution, you can add new items to IDE folders using our custom Add Class wizard. For further customization just edit default.js as text file (VS doesn't cache it, so there is no need for any kind of restarts).

Conclusion

I also have the same wizards for new Function and Test. VS C++ clearly has a lot of duplication in this area. There are needs for Delete Class and Rename Class and the only way out is to create our own tools. Good news is that it's at least possible.

Organize Visual Studio tabs with Tabs Studio add-in