Click here to Skip to main content
12,953,937 members (44,589 online)
Click here to Skip to main content
Add your own
alternative version


60 bookmarked
Posted 2 May 2003

C# SDI/MDI Application wizards

, 30 Nov 2003 CPOL
Rate this:
Please Sign up or sign in to vote.
Useful project templates for C# document-centric applications

Two new C# project templates


It's a fact of life that C# project templates provided by the VS.NET IDE lack SDI/MDI support. Since SDI/MDI fit many real-world requirements when writing applications, especially those being document-centric, I thought that would be nice and hopefully useful to share this stuff.

In the remainder of this article, I'll show :
  • what is brought in the zip files
  • how to install the application wizard
  • the meaning of SDI/MDI, huh ?
  • how it was built

1. Installing the wizard

The zip files has everything you need to get the wizards installed on either VC#2002 or VC#2003. The package can be broken down as follows :

  • SDIMDIwizardinstaller.exe, command-line installer
  • CSharpSDIWiz folder, templates files for the SDI wizard
  • CSharpMDIWiz folder, templates files for the MDI wizard
  • *.vsz files, parent files for the wizard, IDE version specific

If you only want to install the stuff and are not very much interested in the details, then extract all the stuff in some folder, and then double-click on SDIMDIwizardinstaller.exe if you are using VC#2003. If you are using VC#2002, bring a command-line up, and type SDIMDIwizardinstaller.exe 2002. Once the wizards are installed, you can delete the temporary extraction folder.

The installer does the following job :

  1. check-out the command-line, whether 2002 is being passed
  2. according to the command-line, retrieve the install directory of VC# from the registry
  3. recurse-copy all template files in the <installdir> / VC#Wizards subfolder
  4. copy all *.vsz files in the <installdir> / CSharpProjects subfolder
  5. update the <installdir> / CSharpProjects / CSharp.vsdir file and add two entries if they don't exist yet.

The code for the installer is reproduced below :

static void Main(string[] args)
 // installation sequence
 // 1- get VC# install dir (regkey)
 // 2- copy template files in the VC# subfolder for files
 // 3- copy vsz files in the VC# subfolder for project wizards
 // 4- add two entries in the VC# vsdir file so that the IDE sees them

 // check out cmdline (type 2002 for VC#2002, none or 
 // everything else for VC#2003)
 bool bIsFor2002 = args.GetLength(0)>0 && args[0] == "2002";

 // 1- regkey
 RegistryKey k;
 if (bIsFor2002)
  k = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
    @"Software\Microsoft\VisualStudio\7.0", true);
  k = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
    @"Software\Microsoft\VisualStudio\7.1", true);

 String szWizardDir = (String) k.GetValue("InstallDir") + @"..\..\VC#\";

 if ( !Directory.Exists(szWizardDir) )
  System.Console.WriteLine("Make sure to install VC# first");

 // 2- template files
 String szSrcDir = AppDomain.CurrentDomain.BaseDirectory;
 RecurseCopyFiles(szSrcDir + @"\CSharpSDIWiz", szWizardDir + 
 RecurseCopyFiles(szSrcDir + @"\CSharpMDIWiz", szWizardDir +

 // 3- vsz files
 if (bIsFor2002) // VC# 2002
  File.Copy(szSrcDir + @"\CSharpSDI_VS2002.vsz", szWizardDir + 
  File.Copy(szSrcDir + @"\CSharpMDI_VS2002.vsz", szWizardDir + 
 else // VC# 2003
  File.Copy(szSrcDir + @"\CSharpSDI_VS2003.vsz", szWizardDir + 
  File.Copy(szSrcDir + @"\CSharpMDI_VS2003.vsz", szWizardDir + 

 // 4- update vsdir file (append 2 entries if they don't exist yet)
 bool bAlreadyInstalled = false;
 using (StreamReader sr = new StreamReader( szWizardDir + 
    @"CSharpProjects\CSharp.vsdir" )) 
  String line;
  while ((line = sr.ReadLine()) != null) 
   if (line.IndexOf("CSharpSDI.vsz") > -1)
    bAlreadyInstalled = true;

  if (!bAlreadyInstalled)
   using (StreamWriter sw = File.AppendText( szWizardDir + 
    @"CSharpProjects\CSharp.vsdir" )) 
    sw.WriteLine("CSharpSDI.vsz|{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" + 
       "|SDI Application|11|" +
       "Builds a Windows single document interface (SDI) application|" +
       "{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}|4554| |SDIApplication");
    sw.WriteLine("CSharpMDI.vsz|{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" +
       "|MDI Application|12|" +
       "Builds a Windows single document interface (MDI) application|" +
       "{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}|4554| |MDIApplication");


static void RecurseCopyFiles(String szSrcDir, String szDestDir)
 if ( !Directory.Exists(szDestDir) )

 string [] fileEntries = Directory.GetFiles(szSrcDir);
 foreach(string fileName in fileEntries)
  File.Copy(fileName, szDestDir + fileName.Substring(

 // recurse
 string [] subdirectoryEntries = Directory.GetDirectories(szSrcDir + @"\");
 foreach(string subdirectory in subdirectoryEntries)
  String szSrcNextDir = subdirectory;
  String szDestNextDir = szDestDir + subdirectory.Substring(
  RecurseCopyFiles(szSrcNextDir, szDestNextDir);


The MDI application is derived from a sample provided by MS in the VS.NET CDs, called "Scribble".

2. What is SDI/MDI ?

SDI/MDI is short for Simple Document Interface / Multiple Document Interface.

Those words are used by VC++ MFC programmers to refer to application wizards that are built within the VC++ IDE and which provide rich and useful application skeleton code. We could also speak about MVC (Model View Controller). In fact, the document-view paradigm is a way to provide functionalities to an application such like the ability to create a new document of a given type (file extension), open an existing document, and save a working document. Each document is rendered, whether on screen or not, using one or more views. The document orders the views to update themselves based on events or other application logic. Each view implements an OnPaint method to display the content purposely. For instance, if a document stores the bits for a 3D graphic model, then one view could be used to display a front view of it, while another view could be used to display a left view of it. And so on.

A SDI application is a one document - one view application. Depending on requirements, one can add views to it. Notepad is a SDI application.

A MDI application is a multiple document - multiple view application. Microsoft Word is a MDI application.

Sample MDI application

3. Views and documents

Both SDI and MDI wizards share a common "architecture". The main form acts like a container. One or more documents (instances of the SDIDoc class) hold all the documents life-cycle (open, save, print, is it dirty?, ...) as well as the application logic itself. One or more views for each document (instances of the SDIView class) hold what's draw on screen or being sent to the printer or any other device.

In the MDI wizard, the main form not only acts like a container, it is really a container and uses the Winforms MDI properties associated to each class derived from System.Windows.Forms.Form, namely IsMdiChild (false for the container), IsMdiContainer (true for the container), MdiChildren (collection of Form-derived classes) and MdiParent (null for the container).

In the SDI wizard, the main form is a container but is mostly a simple form by itself.

In both the SDI and MDI wizards, the drawing and printing are delegated to views. Each view knows its "parent" document, and can use the properties from that document to draw itself, etc.

By analogy, the serialization (load / save) is delegated to the document. Like in the MFC wizard, a document is being associated a file extension, .doc by default. Each document knows all the views being attached, and this custom mechanism is used to delegate the calls.

4. Inside the application wizard

Installing the application wizard allows to create projects using either of two new project templates. Once installed, the 2 new project templates appear with a clearly identifiable icon and label from the VS.NET project wizard. Both can be used like if you were using the default Windows Application project template. Below are explanations on how to install the application :

Below are the steps to add both SDI and MDI application wizards to the list of known C# project wizards.

  • 4.1 Find the VC# installation folder. On my machine, it's c:\program files\VC#, and it has subfolders like VC#Wizards and CSharpProjects. Let's call it <VC#dir> for the remainder of the article.
  • 4.2 When you bring up the VS.NET project box, VS.NET lists all existing .vsdir files, including those found in particular <VC#dir> subfolders. Each .vsdir file is a category of project templates. The <VC#dir> \ CSharpProjects \ CSharp.vsdir lists all standard C# project templates. The definition of the .vsdir file format is detailed here[^]. Entries in a .vsdir file are referenced .vsz files which in turn are small project template identifiers. Among those identifiers is CSharpEXE.vsz, the project which helps build simple C# Windows Applications. What we are going to do is add two entries to the CSharp.vsdir file, one for the SDI project template, one for the MDI project template. So, edit the CSharp.vsdir and clone twice the line referencing CSharpExe.vsz, so as to make sure our two projects are built from this starting point. The documentation for the .vsz file can be found here[^].

    Those two files must be edited, and the reference to the CSharpEXEWiz folder must be replaced with corresponding references to CSharpSDIWiz and CSharpMDIWiz. Those are references to subfolders we are going to create in a while. The two .vsz files should look like this :

    CSharpSDIWiz.vsz // VC# 2002

    VSWIZARD 7.0
    Param="WIZARD_NAME = CSharpSDIWiz"
    Param="WIZARD_UI = FALSE"

    CSharpMDIWiz.vsz // VC# 2002

    VSWIZARD 7.0
    Param="WIZARD_NAME = CSharpMDIWiz"
    Param="WIZARD_UI = FALSE"

    CSharpSDIWiz and CSharpMDIWiz are meant to be <VC#dir> \ VC#Wizards subfolders. Let's create them. Each of these folders must follow the project template guideline, ie have a predefined structure. The structure for a simple project template is straight forward : there must be two subfolders, namely Scripts and Templates. In each of these 2 subfolders must be a localized folder whose name depends on the language version of your VS.NET installation. We assume in the remainder of this article that it's 1033 (US english).

  • 4.3 Filling the Scripts \ 1033 folder : this folder is supposed to contain a default.js script file. The implementation in default.js is what differentiates this project template from another and brings Javascript application code aimed to build the actual .csproj file based on the core Javascript source code from <VC#dir> \ VC#Wizards \ 1033 \ Common.js and the actual VS.NET IDE extensibility object model[^]. The default.js file assumes that Form1.cs is the application mainform. So to make things easier, both SDI and MDI projects are such that Form1.cs is the mainform. Otherwise, default.js would have to be manually edited. Just copy the default.js file found in the CSharpEXEWiz \ Scripts \ 1033 folder.
  • 4.4 Filling the Templates \ 1033 folder : this folder is supposed to contain a Templates.inf file, and all files that are to be included in the target .csproj project file. Things get easy since the Templates.inf file simply lists all files in this folder, one per line.

In short, here is how the file hierarchy should look like for each WIZ subfolder :

 + Scripts
   + 1033
     + default.js  (a copy from the one existing in the CSharpEXEWiz folder)
 + Templates
   + 1033
      + Templates.inf
      + Form1.cs
      + Form1.resx
      + SDIDoc.cs
      + SDIView.cs
      + SDIView.resx
      + New.bmp
      + Open.bmp
      + Preview.bmp
      + Print.bmp
      + Save.bmp
      + App.ico
Where Templates.inf contains this :

Last note, to make sure namespaces are properly transferred to the target project, we have to change the content of the Form1.cs file from the original stand-alone project :

namespace SDIApp

with this (in the Templates \ 1033 folder) :

namespace [!output SAFE_NAMESPACE_NAME]

What is just done and finished for CSharpSDIWiz must be also done for CSharpMDIWiz.

5. Unifying both project templates ?

I have to confess that, for trivial reasons, I have brought two wizards up instead of only one. Actually there is no need to have two additional icons in the project box, one for SDI and one for MDI. The idea is that, in the .vsz file, it's possible to let the Wizard engine know about a HTML UI which, in turn, would let the user choose SDI or MDI, get the return value, and act accordingly. Although this is certainly doable, this is not what I have done for this release.

For those interested in HTML UI-based wizards, just check out the undocumented wizard named CSharpIndexerWiz

Stéphane Rodriguez


  • first time published - May 3rd, 2003.
  • updated - Nov 30, 2003 :
    • added a user-friendly installer
    • the SDI wizard really creates a SDI app.


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


About the Author

Addicted to reverse engineering. At work, I am developing business intelligence software in a team of smart people (independent software vendor).

Need a fast Excel generation component? Try xlsgen.

You may also be interested in...

Comments and Discussions

QuestionPackage not contains files mentioned Pin
Hafiz Sikander Rafiq21-Jan-15 20:12
memberHafiz Sikander Rafiq21-Jan-15 20:12 
AnswerRe: Package not contains files mentioned Pin
Hafiz Sikander Rafiq21-Jan-15 20:15
memberHafiz Sikander Rafiq21-Jan-15 20:15 
GeneralWhy I Voted "1" Pin
John Simmons / outlaw programmer1-Nov-07 3:53
mvpJohn Simmons / outlaw programmer1-Nov-07 3:53 
GeneralRe: Why I Voted "1" Pin
Jeffrey Walton28-Nov-07 13:17
memberJeffrey Walton28-Nov-07 13:17 
GeneralRe: Why I Voted "1" (My Bad) Pin
Jeffrey Walton28-Nov-07 13:19
memberJeffrey Walton28-Nov-07 13:19 
GeneralCorrection. Pin
Mr.Prakash3-Nov-06 22:37
memberMr.Prakash3-Nov-06 22:37 
Generalerror with c# 2005 professional : File name or class name not found during Automation operation Pin
vineet1378014-Sep-06 20:05
membervineet1378014-Sep-06 20:05 
GeneralError for VC# 2005 Pin
qmlee173310-Aug-06 8:24
memberqmlee173310-Aug-06 8:24 
QuestionError Message Pin
olddog7725-Apr-06 2:28
memberolddog7725-Apr-06 2:28 
GeneralHELP!!! Pin
mattp1214846-Dec-04 12:56
membermattp1214846-Dec-04 12:56 
Hey i was wondering if you could give me some help on a project that i have due Wednesday December 8th.

1.What code is required for within an mdi interface, open a form first off. secondly, when that form is open, we will enter the data in text boxes and then click the save button on the mdi window. i need when its clicked, to save the form data and save it in a file with a designated name. when mdi loads the next time...if that file has been saved once, i don't want it to load again. it then needs to proceed to loading the next form windows. if that form has never been saved, it needs to load that form.

2.I need to figure out how to backup and load backup files. those above are what im worried most about. also, i need to somehow figure out how to load a flash window within the mdi interface. and i dont' know if you would know how, but is there a way to make like a calendar, where i could click on a day, and it displays all the information in the form window that is saved on that day?

i know this may be a lot, but i would really appreciate the help...thanks very much

GeneralVC# 2005 update [modified] Pin
Stephane Rodriguez.13-Nov-04 22:56
memberStephane Rodriguez.13-Nov-04 22:56 
GeneralRe: VC# 2005 update Pin
WilsonProgramming28-Nov-04 2:28
memberWilsonProgramming28-Nov-04 2:28 
GeneralRe: VC# 2005 update Pin
Stephane Rodriguez.28-Nov-04 7:18
memberStephane Rodriguez.28-Nov-04 7:18 
GeneralRe: VC# 2005 update Pin
Stephane Rodriguez.4-Dec-04 8:15
memberStephane Rodriguez.4-Dec-04 8:15 
GeneralRe: VC# 2005 update. Please Help!!! Pin
delinhabit31-Mar-06 4:52
memberdelinhabit31-Mar-06 4:52 
GeneralSimilar Task Pin
Matt McGuirk8-Aug-04 3:38
sussMatt McGuirk8-Aug-04 3:38 
GeneralRe: Similar Task Pin
S R8-Aug-04 4:52
sussS R8-Aug-04 4:52 
Generalexcellent work Pin
Allen Anderson15-Dec-03 6:41
memberAllen Anderson15-Dec-03 6:41 
GeneralThis is Great stuff Pin
vbnetuk2-Dec-03 6:56
sussvbnetuk2-Dec-03 6:56 
GeneralRe: This is Great stuff Pin
Stephane Rodriguez.2-Dec-03 7:02
memberStephane Rodriguez.2-Dec-03 7:02 
GeneralRe: This is Great stuff Pin
vbnetuk2-Dec-03 22:26
sussvbnetuk2-Dec-03 22:26 
GeneralRe: This is Great stuff Pin
Stephane Rodriguez.2-Dec-03 22:59
memberStephane Rodriguez.2-Dec-03 22:59 
QuestionInstallation for SharpDevelop IDE? Pin
Chris Meech1-Dec-03 7:08
memberChris Meech1-Dec-03 7:08 
AnswerRe: Installation for SharpDevelop IDE? Pin
Stephane Rodriguez.1-Dec-03 9:19
memberStephane Rodriguez.1-Dec-03 9:19 
QuestionSimplified Setup? Pin
Chris Sells26-Nov-03 6:19
memberChris Sells26-Nov-03 6:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 1 Dec 2003
Article Copyright 2003 by Stephane Rodriguez.
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid