Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version

Improvement of the .NET Menu Style class

, 14 Jan 2003
This is an improvement by Francesco Natali over an improvement by Sajith M of the "Visual Studio .NET Menu Style" by Carlos H. Perez
myrtf editor.zip
backimage.jpg
bin
Debug
Release
Icone
about.ico
Application.ico
arrange.ico
binoc.ico
chars.ico
Child.ico
close.ico
copy.ico
cut.ico
delete.ico
find.ico
font.ico
gotonet.ico
lock.ico
lowercase.ico
net.ico
new.ico
open.ico
paste.ico
preference.ico
printer.ico
recentfiles.ico
redo.ico
save.ico
selectedtext.ico
turnoff.ico
undo.ico
uppercase.ico
ModifyRegistry.zip
myRTF Editor.csproj.user
myRTF Editor.suo
paper01.jpg
paper02.jpg
paper03.jpg
myrtfeditor.zip
backimage.jpg
about.ico
Application.ico
arrange.ico
binoc.ico
chars.ico
Child.ico
close.ico
copy.ico
cut.ico
delete.ico
find.ico
font.ico
gotonet.ico
lock.ico
lowercase.ico
net.ico
new.ico
open.ico
paste.ico
preference.ico
printer.ico
recentfiles.ico
redo.ico
save.ico
selectedtext.ico
turnoff.ico
undo.ico
uppercase.ico
ModifyRegistry.zip
myRTF Editor.csproj.user
paper01.jpg
paper02.jpg
paper03.jpg
nicemenu.zip
nicemenu2.zip
prjnicemenu.zip
App.ico
prjNiceMenu.exe
prjNiceMenu.pdb
nicemenu.png
obj
Debug
MenuSample.Form1.resources
prjNiceMenu.exe
prjNiceMenu.exe.incr
prjNiceMenu.NiceMenu.resources
prjNiceMenu.pdb
prjNiceMenu.projdata
prjProvaFunzioni.projdata
temp
TempPE
prjNiceMenu.csproj.user
prjNiceMenu.suo
using System;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;
using Utility.NiceMenu;
using Utility.ModifyRegistry;

namespace myRTF_Editor
{
	public class MenuFunctions
	{
		// the Parent form
		public FormMDI parentForm;
		// the Parent imagelist
		public ImageList parentImageList;
		// parentMenuFunctions 
		public MenuFunctions parentMenuFunctions;
		// myPersonalMenuItem
		private NiceMenu myPersonalMenuItem = new NiceMenu();

		// Get the format for the object type.
		private DataFormats.Format rtfFormat = DataFormats.GetFormat(DataFormats.Rtf);
		// Get the format for the object type.
		private DataFormats.Format textFormat = DataFormats.GetFormat(DataFormats.Text);
		// Array of Recent Files
		private string[] arrayRecentFiles = new string[8];

		// Printing
		private PageSettings storedPageSettings = null;

		// Undo - Redo
		private static string UndoText = "Undo";
		private static string RedoText = "Redo";
		private static string UndoOldText = "Undo";
		private static string RedoOldText = "Redo";

		/* ********************************************
		 *				MenuSelected
		 * *******************************************/
		public void MenuSelected(string menuText)
		{
			/* Undo - Redo
			 * I have to do a separate control for 
			 * Undo and Redo functions 'cause the values
			 * of their relative menu texts are not constants
			 * and there's no way (or I don't know it)
			 * to use variable values with the SWITCH function.
			 * */
			if (menuText == UndoText)
				Undo();

			if (menuText == RedoText)
				Redo();

			switch (menuText)
			{
				case "Exit":
					parentForm.Dispose();
					Application.Exit();
					break;
				case "Copy":
					Copy();
					break;
				case "Cut":
					Cut();
					break;
				case "Paste":
					Paste();
					break;
				case "Delete":
					Del();
					break;
				case "Select All":
					SelectAll();
					break;
				case "Open...":
					Open();
					break;
				case "Save":
					Save();
					break;
				case "Save As...":
					SaveAs();
					break;
				case "New":
					New();
					break;
				case "Close":
					Close();
					break;
				case "Close All":
					CloseAll();
					break;
				case "Entire document":
					ProtectDocument(true);
					break;
				case "Selected text":
					ProtectDocument(false);
					break;
				case "Upper Case":
					ModifyCase("U");
					break;
				case "Lower Case":
					ModifyCase("L");
					break;
				case "Invert Case":
					ModifyCase("I");
					break;
				case "Capitalize":
					ModifyCase("C");
					break;
				case "Cascade":
					LayoutMdi(MdiLayout.Cascade);
					break;
				case "Tile Horizontally":
					LayoutMdi(MdiLayout.TileHorizontal);
					break;
				case "Tile Vertically":
					LayoutMdi(MdiLayout.TileVertical);
					break;
				case "Minimize All":
					FormWindowState(System.Windows.Forms.FormWindowState.Minimized);
					break; 
				case "Print...":
					Print();
					break; 
				case "Page Setup...":
					PageSetup();
					break; 
				default:
					break; 
			}

			/* Recent Files list
			 * if the first char of the menuText string is
			 * a number, a recent file menu item has been clicked!
			 *  */
			char myChar = Convert.ToChar(menuText.Substring(0,1));
			if (((int)myChar >= 49) && // 1
				((int)myChar <= 56))   // 8
				OpenRecentFile(menuText.Substring(3));  // 1. C:\myfile.rtf

		}

		/* ********************************************
		 *					 Print
		 * *******************************************/
		private void Print()
		{
			FormChild activeChild = (FormChild)parentForm.ActiveMdiChild;

			try 
			{
				StreamReader streamToPrint = new StreamReader(activeChild.OpenFile);
				try
				{
					TextFilePrintDocument pd = new TextFilePrintDocument(streamToPrint);
					if (storedPageSettings != null)
						pd.DefaultPageSettings = storedPageSettings;

					PrintDialog dlg = new PrintDialog();
					dlg.Document = pd;
					DialogResult result = dlg.ShowDialog();

					if (result == DialogResult.OK)
						pd.Print();
				}
				finally
				{
					streamToPrint.Close();
				}
			}
			catch (Exception e)
			{
				MessageBox.Show("Error: " + e.Message);
			}
		}

		/* ********************************************
		 *  			  Page Setup
		 * *******************************************/
		private void PageSetup()
		{
			try	
			{
				PageSetupDialog psDlg = new PageSetupDialog();

				if (storedPageSettings == null)
					storedPageSettings = new PageSettings();

				psDlg.PageSettings = storedPageSettings;
				psDlg.ShowDialog();
			}
			catch (Exception e)
			{
				MessageBox.Show("Error: " + e.Message);
			}
		}

		/* ********************************************
		 *				Open Recent File
		 * *******************************************/
		private void OpenRecentFile(string myFile)
		{
			FormChild newRTFChild = NewChild();
			newRTFChild.OpenFile = myFile;
			newRTFChild.Show();
		}

		/* ********************************************
		 *				Form Window State
		 * *******************************************/
		private void FormWindowState(System.Windows.Forms.FormWindowState myState)
		{
			// Determine the active child form.
			Form activeChild = parentForm.ActiveMdiChild;

			// If there is an active child form...
			while (activeChild.WindowState != myState)
			{
				activeChild.WindowState = myState;
				// Determine the active child form.
				activeChild = parentForm.ActiveMdiChild;
			}			
		}

		/* ********************************************
		 *					LayoutMdi
		 * *******************************************/
		private void LayoutMdi(System.Windows.Forms.MdiLayout myLayout)
		{
			parentForm.LayoutMdi(myLayout);
		}

		/* ********************************************
		 *				  Mofify Case
		 * *******************************************/
		private void ModifyCase(string myCase)
		{
			RichTextBox myBox = ActiveRichTextBoxControl();

			if (myBox != null)
			{
				switch (myCase)
				{
					case "U":
						myBox.SelectedText = myBox.SelectedText.ToUpper();
						break;
					case "L":
						myBox.SelectedText = myBox.SelectedText.ToLower();
						break;
					case "I":
						myBox.SelectedText = InvertCase(myBox.SelectedText);
						break;
					case "C":
						myBox.SelectedText = CapitalizeCase(myBox.SelectedText);
						break;
				}
			}
		}

		/* ********************************************
		 *				  Invert Case
		 * *******************************************/
		private string InvertCase(string myString)
		{
			string[] myInitialString = new string[myString.Length];
			string myFinalString = "";

			char[] myCharArray = myString.ToCharArray();
			// ---------------------------------------
			for (int i=0; i < myCharArray.Length; i++)
				myInitialString[i] = myCharArray[i].ToString();
			// ----------- Upper / Lower -------------
			for (int i=0; i < myString.Length; i++)
				if ((int)myCharArray[i] >= 97) // 97 = "a"
					myInitialString[i] = myInitialString[i].ToUpper();
				else
					myInitialString[i] = myInitialString[i].ToLower();
			// ------------ Final String -------------
			for (int i=0; i < myString.Length; i++)
				myFinalString += myInitialString[i];
			
			return myFinalString;
		}

		/* ********************************************
		 *			    Capitalize Case
		 * *******************************************/
		private string CapitalizeCase(string myString)
		{
			string[] myInitialString = new string[myString.Length];
			string myFinalString = "";

			char[] myCharArray = myString.ToCharArray();
			// ---------------------------------------
			for (int i=0; i < myCharArray.Length; i++)
				myInitialString[i] = myCharArray[i].ToString();
			// ------------- Capitalize --------------
			for (int i=0; i < myString.Length; i++)
				if (i == 0)
					myInitialString[i] = myInitialString[i].ToUpper();
				else
					myInitialString[i] = myInitialString[i].ToLower();
			// ------------ Final String -------------
			for (int i=0; i < myString.Length; i++)
				myFinalString += myInitialString[i];
			
			return myFinalString;
		}

		/* ********************************************
		 *					Undo
		 * *******************************************/
		private void Undo()
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
				myBox.Undo();
		}

		/* ********************************************
		 *					Redo
		 * *******************************************/
		private void Redo()
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
				myBox.Redo();
		}

		/* ********************************************
		 *					Copy
		 * *******************************************/
		private void Copy()
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
				myBox.Copy();
		}

		/* ********************************************
		 *					Cut
		 * *******************************************/
		private void Cut()
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
				myBox.Cut();
		}

		/* ********************************************
		 *					Del
		 * *******************************************/
		private void Del()
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
				myBox.SelectedText = "";
		}

		/* ********************************************
		 *					Paste
		 * *******************************************/
		private void Paste()
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
			{
				// Create a new instance of the DataObject interface.
//				IDataObject data = Clipboard.GetDataObject();
				// If the data is rtf text or image, 
				// then set the text of the 
				// RichTextBox to the text in the clipboard.
//				if (data.GetDataPresent(DataFormats.Rtf))
					myBox.Paste();               
			}
		}

		/* ********************************************
		 *					Select All
		 * *******************************************/
		private void SelectAll()
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
			{
				myBox.SelectAll();
			}
		}

		/* ********************************************
		 *				Protect Document
		 * *******************************************/
		private void ProtectDocument(bool entireDoc)
		{
			RichTextBox myBox = ActiveRichTextBoxControl();
			if (myBox != null)
			{
				if (entireDoc == true)
					myBox.SelectAll();
				if (myBox.SelectedText != "")
					myBox.SelectionProtected = true;
			}
		}

		/* ********************************************
		 *					Close
		 * *******************************************/
		private void Close()
		{
			// Determine the active child form.
			Form activeChild = parentForm.ActiveMdiChild;

			// If there is an active child form...
			if (activeChild != null)
			{
				activeChild.Close();
				activeChild.Dispose();
				activeChild = null;
			}
		}

		/* ********************************************
		 *					Close All
		 * *******************************************/
		private void CloseAll()
		{
			// Determine the active child form.
			Form activeChild = parentForm.ActiveMdiChild;

			// If there is an active child form...
			while (activeChild != null)
			{
				activeChild.Close();
				activeChild.Dispose();
				activeChild = null;
				// Determine the active child form.
				activeChild = parentForm.ActiveMdiChild;
			}
		}

		/* ********************************************
		 *					 New
		 * -------------------------------------------
		 *		this function will be called 
		 *			only by the FormMDI
		 * *******************************************/
		private void New()
		{
			// Retrive a new FormChild
			FormChild newRTFChild = NewChild();
			newRTFChild.Show();
			// Update main menu and context menu
			UpdateChildMenu(newRTFChild.richTextBox);
		}

		private FormChild NewChild()
		{
			// Instancing
			FormChild newRTFfile = new FormChild();
			// Properties
			newRTFfile.MdiParent = parentForm; 
			newRTFfile.childMenuFunctions = parentMenuFunctions;
			newRTFfile.richTextBox.ContextMenu = parentForm.contextChildMenu;
			// Return
			return newRTFfile;
		}

		/* *******************************************
		 *					 Save
		 * *******************************************/
		private void Save()
		{
			// Get the active FormChild
			FormChild activeChild = (FormChild)parentForm.ActiveMdiChild;
		
			// If there is an active child form...
			if (activeChild != null)
			{
				// if it's a new document...
				if (activeChild.OpenFile == "new file")
				{	SaveAs();
					return;	}
				else
					activeChild.SaveFile(activeChild.OpenFile);
			}
		}

		/* *******************************************
		 *					 Save As
		 * *******************************************/
		private void SaveAs()
		{
			// Get the active FormChild
			FormChild activeChild = (FormChild)parentForm.ActiveMdiChild;

			// If there is an active child form...
			if (activeChild != null)
			{
				SaveFileDialog myDialog = new SaveFileDialog();
				myDialog.ShowHelp = false;
				myDialog.Title = "Save as...";
				myDialog.Filter = "RTF files (*.rtf)|*.rtf|All files (*.*)|*.*" ;
				myDialog.FilterIndex = 1 ; // RTF

				if (myDialog.ShowDialog() == DialogResult.OK)
				{
					string myFile = myDialog.FileName;
					activeChild.SaveFile(myFile);	
					activeChild.OpenFile = myFile;
				}
			}
		}

		/* ********************************************
		 *					 Open
		 * *******************************************/
		private void Open()
		{
			OpenFileDialog myDialog = new OpenFileDialog();
			myDialog.Multiselect = true;
			myDialog.ShowHelp = false;
			myDialog.Title = "Select a RTF file";
			myDialog.Filter = "RTF files (*.rtf)|*.rtf|All files (*.*)|*.*" ;
			myDialog.FilterIndex = 1 ;
			myDialog.ShowReadOnly = true ;
			myDialog.CheckFileExists = true;

			if (myDialog.ShowDialog() == DialogResult.OK)
			{
				string[] fileRTF = myDialog.FileNames;
				// Loading all selected files
				for (int i = 0 ; i < fileRTF.Length ; i++)
				{
					FormChild newRTFChild = NewChild();
					newRTFChild.OpenFile = fileRTF[i].ToString();
					newRTFChild.ReadOnlyFile = myDialog.ReadOnlyChecked;
					newRTFChild.Show();
				}
			}
		}

		/* ********************************************
		 *			ActiveRichTextBoxControl
		 * *******************************************/
		private RichTextBox ActiveRichTextBoxControl()
		{
			// Determine the active child form.
			Form activeChild = parentForm.ActiveMdiChild;
			// Initializing
			RichTextBox theBox = null;

			// If there is an active child form, find the active control, 
			// which should be a RichTextBox.
			if (activeChild != null)
			{
				try 
				{
					theBox = (RichTextBox)activeChild.ActiveControl;
				}
				catch 
				{
					// Yes, in a FormChild there's always 
					// a RichTextBox control, however a
					// secure code is a good 
					MessageBox.Show("You need to select a RichTextBox.","Control",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
				}
			}
			if (theBox != null)
				return theBox;
			else
				return null;
		}

		/* ********************************************
		 *			Menu_EnableDisableMDI
		 *			Menu_EnableDisableChild
		 *			Menu_ChangeTextUndoRedoMDI
		 * *******************************************/
		private void Menu_EnableDisableMDI(string MenuText, bool EnableMenu)
		{
			myPersonalMenuItem = parentForm.myNiceMenu.SearchNiceMenuItem(MenuText);
			myPersonalMenuItem.Enabled = EnableMenu;
		}
		private void Menu_EnableDisableChild(string MenuText, bool EnableMenu)
		{
			myPersonalMenuItem = parentForm.myNiceContextMenu.SearchContextNiceMenuItem(MenuText);
			myPersonalMenuItem.Enabled = EnableMenu;
		}
		private void Menu_ChangeTextUndoRedo(string myUndoText, string myRedoText)
		{
			if (myUndoText == "") 
				UndoText = "Undo";
			else
				UndoText = "Undo <" + myUndoText + ">";

			if (myRedoText == "") 
				RedoText = "Redo";
			else
				RedoText = "Redo <" + myRedoText + ">";

			// Main
			myPersonalMenuItem = parentForm.myNiceMenu.SearchNiceMenuItem(UndoOldText);
			myPersonalMenuItem.Text = UndoText;
			myPersonalMenuItem = parentForm.myNiceMenu.SearchNiceMenuItem(RedoOldText);
			myPersonalMenuItem.Text = RedoText;
			// Child
			myPersonalMenuItem = parentForm.myNiceContextMenu.SearchContextNiceMenuItem(UndoOldText);
			myPersonalMenuItem.Text = UndoText;
			myPersonalMenuItem = parentForm.myNiceContextMenu.SearchContextNiceMenuItem(RedoOldText);
			myPersonalMenuItem.Text = RedoText;

			// Updating old menus...
			UndoOldText = UndoText;
			RedoOldText = RedoText;
		}

		/* ********************************************
		 *				Add Recent File
		 * *******************************************/
		public void AddRecentFile(string myFile)
		{
			NiceMenu myNewMenuItem = null;

			string[] myClonedArray = new String[8];
			myClonedArray.Initialize();

			myClonedArray[0] = myFile;
			for (int i = 1; i < 8 ; i++)
				myClonedArray[i] = arrayRecentFiles[i-1];

			arrayRecentFiles = myClonedArray;

			// Retriving the Recent Files menu item
			myPersonalMenuItem = parentForm.myNiceMenu.SearchNiceMenuItem("Recent Files");
			// Removing all old menu items
			myPersonalMenuItem.MenuItems.Clear();

			for (int i = 0; i < 8 ; i++)
			{
				if (arrayRecentFiles[i] == null)
					break;

				// Initializing new menu item (example: 1. c:\myfile.rtf)
				myNewMenuItem = new NiceMenu(Convert.ToString(i+1) + ". " + arrayRecentFiles[i], new EventHandler(parentForm.mnuGestioneEventoClick));
				// Add menu item to its parent
				myPersonalMenuItem.MenuItems.Add(myNewMenuItem);
			}
			// These properties are static, so I have to set it again
			// or the menu colors will be replaced with the default colors
			myNewMenuItem.SelectionColor = Color.AliceBlue;
			myNewMenuItem.BackColor = Color.White;
			// -----------------------------------
		}

		/* ********************************************
		 *		  Update Recent File Registry
		 * *******************************************/
		public void UpdateRecentFileRegistry()
		{
			ModifyRegistry myRegistry = new ModifyRegistry();
			myRegistry.SubKey = "SOFTWARE\\RTF_SHARP_EDIT\\RECENTFILES";
			myRegistry.ShowError = true;
			myRegistry.DeleteSubKeyTree();
			for (int i = 0; i < 8 ; i++)
			{
				if (arrayRecentFiles[i] == null)
					break;
				myRegistry.Write(i.ToString(), arrayRecentFiles[i]);
			}
		}

		/* ********************************************
		 *		  Update Recent File Menu
		 * *******************************************/
		public void UpdateRecentFileMenu()
		{
			NiceMenu myNewMenuItem = null;
			// Retriving the Recent Files menu item
			myPersonalMenuItem = parentForm.myNiceMenu.SearchNiceMenuItem("Recent Files");

			ModifyRegistry myRegistry = new ModifyRegistry();
			myRegistry.SubKey = "SOFTWARE\\RTF_SHARP_EDIT\\RECENTFILES";
			myRegistry.ShowError = true;
			int numberValues = myRegistry.ValueCount();

			for (int i = 0; i < numberValues; i++)
			{
				arrayRecentFiles[i] = myRegistry.Read(i.ToString());
				// Initializing new menu item (example: 1. c:\myfile.rtf)
				myNewMenuItem = new NiceMenu(Convert.ToString(i+1) + ". " + arrayRecentFiles[i], new EventHandler(parentForm.mnuGestioneEventoClick));
				// Add menu item to its parent
				myPersonalMenuItem.MenuItems.Add(myNewMenuItem);
			}
			if (myNewMenuItem != null)
			{
				// These properties are static, so I have to set it again
				myNewMenuItem.SelectionColor = Color.AliceBlue;
				myNewMenuItem.BackColor = Color.White;
			}
		}

		/* ********************************************
		 *				UpdateChildMenu
		 * *******************************************/
		public void UpdateChildMenu(RichTextBox myRTFBox)
		{
			bool myBool;

			// If there is no selected text...
			if (myRTFBox.SelectedText != "")
				myBool = true;
			else
				myBool = false;
			// Updating...
			Menu_EnableDisableMDI("Copy", myBool);
			Menu_EnableDisableChild("Copy", myBool); 
			Menu_EnableDisableMDI("Cut", myBool);
			Menu_EnableDisableChild("Cut", myBool); 
			Menu_EnableDisableMDI("Delete", myBool);
			Menu_EnableDisableChild("Delete", myBool); 
			Menu_EnableDisableMDI("Selected text", myBool);
			Menu_EnableDisableChild("Selected text", myBool); 
			Menu_EnableDisableMDI("Change Case", myBool);
			Menu_EnableDisableChild("Change Case", myBool); 

			// If there is no selected text...
			if ((myRTFBox.CanPaste(rtfFormat) == true) ||
				(myRTFBox.CanPaste(textFormat) == true)) 
				myBool = true;
			else
				myBool = false;
			// Can PASTE ? Updating...
			Menu_EnableDisableMDI("Paste", myBool);
			Menu_EnableDisableChild("Paste", myBool); 
			
			// Undo - Redo text
			UndoText = myRTFBox.UndoActionName;
			RedoText = myRTFBox.RedoActionName;

			Menu_ChangeTextUndoRedo(UndoText, RedoText);
			// Undo - Redo
			Menu_EnableDisableChild(UndoText, myRTFBox.CanUndo); 
			Menu_EnableDisableChild(RedoText, myRTFBox.CanRedo); 
			Menu_EnableDisableMDI(UndoText, myRTFBox.CanUndo); 
			Menu_EnableDisableMDI(RedoText, myRTFBox.CanRedo); 
		}

		public void UpdateMDIMenu()
		{
			bool myBool;

			// Determine the active child form.
			Form activeChild = parentForm.ActiveMdiChild;

			// If there is no active child form...
			if (activeChild == null)
				myBool = false;
			else
				myBool = true;

			Menu_EnableDisableMDI("Close All", myBool);
			Menu_EnableDisableMDI("Close", myBool);
			Menu_EnableDisableMDI("Arrange", myBool);

			if (myBool == false)
			{
				Menu_EnableDisableMDI("Copy", myBool);
				Menu_EnableDisableMDI("Cut", myBool);
				Menu_EnableDisableMDI("Paste", myBool);
				Menu_ChangeTextUndoRedo("", "");
				Menu_EnableDisableMDI(UndoText, myBool);
				Menu_EnableDisableMDI(RedoText, myBool);
			}
		}

		public void UpdateMDIStatusBar()
		{
			// Retrive the array of child form
			Form[] childList;
			childList = parentForm.MdiChildren;

			parentForm.statusBarMDI.Panels.Clear();

			for (int i = 0; i < childList.Length; i++)
			{
				parentForm.statusBarMDI.Panels.Add(childList[i].Text);
				// Sunken
				parentForm.statusBarMDI.Panels[i].BorderStyle = StatusBarPanelBorderStyle.Sunken;
				// Left
				parentForm.statusBarMDI.Panels[i].Alignment = HorizontalAlignment.Left;
			}
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Francesco Natali
Web Developer
Italy Italy
No Biography provided

| Advertise | Privacy | Mobile
Web04 | 2.8.141015.1 | Last Updated 15 Jan 2003
Article Copyright 2002 by Francesco Natali
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid