Introduction
This article describes a simple approach to implementing special character use in a C# based text editor. If your OS is configured for English and you'd like to leave it like that, and if you have not quite memorized all of the key code values required to insert all of the special characters you might use in writing; or if you work from a laptop without a number pad, then this article will offer an alternative approach and may be of interest.
Figure 1: Test Application in Use
Figure 2: Character Selection from a Context Menu
Rather than remembering to lock the number pad and to type things like ALT+0192 or ALT+134, I found it easier to provide an interface in the form of a context menu. To handle case differences, I set it up to insert upper case versions of the characters if I use Shift+F1 to open the menu or lower case versions of the characters if I open the menu with F1 without the shift key. The lower case version is also available using a right click. You won't win any speed typing awards going this route but it is less error prone than keying the codes and will work for you even if you don't have a number pad on your keyboard as is the case with my laptop.
I built the example on top of a fleshed out rich text editor that is also described and available on this site.
Getting Started
The solution contains a developed word processor built around the rich text box control; that much of the code will not be described herein but a description is available on this site in an earlier article. This article will only address that part of the code used to handle the context menu to do the character inserts.
Figure 3: Solution Explorer with the Project Visible
All of the code discussed in this article is contained in frmMain.cs. As a delta from the original editor, the main form was modified by the addition of an insert menu which contains most of the French Accent Marks and through the addition of a context menu with the same characters made available by the new insert menu. A similar approach could be used to allow the user to insert other special characters such as mathematical equation symbols or any other special character that might be of interest to the user.
Code: Main Form (frmMain.cs)
This class provides all of the functionality used in this example to allow the user to insert special characters. The bulk of the code in this class will not be discussed; only those parts that pertain to the placement of special characters into the document.
The first part of the code to depart from the original version of the C# based word processor project is the declarations region of the main form. In this section, two new variables are declared, the first is a point used to maintain awareness as to the physical location of the mouse (which is later used to decide where to show the context menu) and the second is a string variable entitled "mode" which is used to maintain awareness as to whether or not to use upper case or lower case when inserting the character.
#region "Declaration"
private string currentFile;
private int checkPrint;
private Point pLocation;
private string mode;
#endregion
The next new part of the application is used to insert the French accent marks into the active document. The following event handlers and these are the handlers for the new insert menu. All work the same and when called, each will insert the requested accent mark into the document at the position of the cursor.
#region French Accent Marks
/// <summary>
/// Accent Grave - à
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void àToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "à";
}
/// <summary>
/// Accent Grave - è
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void èToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "è";
}
/// <summary>
/// Accent Grave - ù
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ùToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "ù";
}
/// <summary>
/// Accent Aigu - é
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void éToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "é";
}
/// <summary>
/// Accent circonflexe - â
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void âToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "â";
}
/// <summary>
/// Accent circonflexe - ê
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void êToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "ê";
}
/// <summary>
/// Accent circonflexe - î
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void îToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "î";
}
/// <summary>
/// Accent circonflexe - ô
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ôToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "ô";
}
/// <summary>
/// Accent circonflexe - û
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ûToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "û";
}
/// <summary>
/// Accent tréma - ë
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ëToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "ë";
}
/// <summary>
/// Accent tréma - ï
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ïToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "ï";
}
/// <summary>
/// Accent tréma - ü
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void üToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "ü";
}
/// <summary>
/// Accent Cedille - ç
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void çToolStripMenuItem_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "ç";
}
/// <summary>
/// Open quote
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripMenuItem10_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "«";
}
/// <summary>
/// Close quote
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripMenuItem11_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "»";
}
#endregion
Handling the context menu is not significantly different; the primary difference being that the use of the shift key when selecting F1 will insert the characters in upper case (whereas the use of F1 alone or using the right mouse click event to launch the menu will insert characters in lower case). To support this functionality, the rich text box key down event is used to both define the location where the menu will appear and also to set the mode string variable to either UC or LC for upper or lower case. The mouse move event is used to update the Point pLocation variable to a screen value; that point is used by the key down handler to set the position of the context menu.
The code related to the context menu is contained in the following region:
#region Context Menu
/// <summary>
/// Evoke the insert menu from either F1 or the
/// Shift+F1; use Shift+F1 to make insert uppercase
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rtbDoc_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F1)
contextMenuStrip1.Show(pLocation);
if (e.Shift == true)
mode = "UC";
else
mode = "LC";
}
private void rtbDoc_MouseMove(object sender, MouseEventArgs e)
{
Control control = (Control)sender;
pLocation = control.PointToScreen(new Point(e.X, e.Y));
}
private void toolStripMenuItem9_Click(object sender, EventArgs e)
{
if(mode == "LC")
rtbDoc.SelectedText = "à";
else
rtbDoc.SelectedText = "à".ToUpper();
}
private void toolStripMenuItem12_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "è";
else
rtbDoc.SelectedText = "è".ToUpper();
}
private void toolStripMenuItem13_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "ù";
else
rtbDoc.SelectedText = "ù".ToUpper();
}
private void toolStripMenuItem14_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "é";
else
rtbDoc.SelectedText = "é".ToUpper();
}
private void toolStripMenuItem15_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "â";
else
rtbDoc.SelectedText = "â".ToUpper();
}
private void toolStripMenuItem16_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "ê";
else
rtbDoc.SelectedText = "ê".ToUpper();
}
private void toolStripMenuItem17_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "î";
else
rtbDoc.SelectedText = "î".ToUpper();
}
private void toolStripMenuItem18_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "ô";
else
rtbDoc.SelectedText = "ô".ToUpper();
}
private void toolStripMenuItem19_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "û";
else
rtbDoc.SelectedText = "û".ToUpper();
}
private void toolStripMenuItem20_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "ë";
else
rtbDoc.SelectedText = "ë".ToUpper();
}
private void toolStripMenuItem21_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "ï";
else
rtbDoc.SelectedText = "ï".ToUpper();
}
private void toolStripMenuItem22_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "ü";
else
rtbDoc.SelectedText = "ü".ToUpper();
}
private void toolStripMenuItem23_Click(object sender, EventArgs e)
{
if (mode == "LC")
rtbDoc.SelectedText = "ç";
else
rtbDoc.SelectedText = "ç".ToUpper();
}
private void toolStripMenuItem24_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "«";
}
private void toolStripMenuItem25_Click(object sender, EventArgs e)
{
rtbDoc.SelectedText = "»";
}
#endregion
Summary.
This article was intended to demonstrate a simple approach to adding a UI to a text editor that is intended to ease the insertion of special characters into the document. The example shows the insertion of upper or lower case French accent marks but one could use it to insert any special characters (custom, odd fonts like wingdings and webdings, etc.).