Font, Shell and Masked Edit Controls for MFC

Great communication is a de facto standard for anything aiming for success nowadays. We can talk about a business meeting or an application; this is equally important. Every application first must establish reliable and effortless communication with the user, and afterward with the operating system itself. With the introduction of common controls, doing this got a lot more straightforward.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 5
October 22, 2009
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

Now you can use these already-optimized controls to resolve the communication between the user and the operating system directly. This assures a consistent working environment for the user across multiple programs and fast application creation for the programmer. All that remains unrevealed is how to pull this off.

While the MSDN contains a lot of information, it is far from perfect. Most of the time you will have the feeling that you are flooded with a massive amount of information while you just want to know what a tool can do and how you can use it. In this article, I will try to fill this gap. 

I will use the MSDN example application, which is quite good. If you want to see it for yourself, you can download it from here. The controls I am going to explain are the ones introduced, or at least improved upon, with the launch of the MFC Feature Pack. Therefore, you will need to install this. If you have service pack one for Visual Studio 2008, you already have it. So let's get started.

The font tool allows the user to pick a font from a list. To illustrate the fonts and present as much as possible in a space as small as possible, it uses a combo box. In one of my earlier articles entitled New Controls for MFC, I presented how to create property sheets inside a dialog and use these to add controls. We will use the same approach now. If you are not familiar with this topic, feel free to read that article first.

As the image above already shows, we have four main options we can set in the case of this control. First, at the creation process, because a font combo box in its essence remains a combo box (with custom initial items), you can add a combo box inside the resource editor, and afterward add it as a class of the dialog. Afterward, change the CComboBox to CMFCFontComboBox.

Now the fonts can be of three types: true type, raster or device fonts. Raster fonts are in fact bitmap fonts. Bitmap fonts are simply collections of raster images of glyphs. Therefore, for every character it displays (small, large, italic, bold, and etcetera), there must be another image of it.

True type is an outline font standard developed in the 1980 by Apple. Device, or hardware, fonts are fonts that are provided directly by your system's hardware or by software other than IDL (interface description language). Most of these have a different image icon in front of them: true type fonts get a TT letter, raster fonts get something that resembles a page with writing on it, and the device fonts get no icon.

 

Item

Effect

GetSelFont

Returns a CMFCFontInfo pointer about the currently-selected font.

SelectFont

Select the specified font inside the combo box. You can specify the name of the font with the character set or with a CMFCFontInfo pointer.

Setup

Initializes the combo box with the corresponding items. The first parameter is an int that contains bitwise or which of the three font types to show; the second is a byte of the character set; the third is a byte that tells the font's pitch and family. Every one of these are optional parameters and have defaults.

m_bDrawUsingFont

Draws inside the combo box using the specific font.

 

 

In practice, it all looks like this:

CMFCFontComboBox m_wndFont;

…

m_wndFont.SelectFont (_T ("Arial"));

…

int nFontType = 0;

 

if (m_bTrueType)

{

nFontType |= TRUETYPE_FONTTYPE;

}

 

if (m_bRaster)

{

nFontType |= RASTER_FONTTYPE;

}

 

if (m_bDeviceFont)

{

nFontType |= DEVICE_FONTTYPE;

}

 

CWaitCursor wait;

m_wndFont.Setup (nFontType);

…

CMFCFontComboBox::m_bDrawUsingFont = m_bDrawUsingFont;

With this effect:

Shell controls

There are three new shell controls. These show the file system present on your computer and allow you to select a file or a path. There exists a Tree control for this, a folder selector that resembles the tree control. However, this has its own modeless dialog, and there is the list control that can show both files and folders.

If you are designing your application with the help of the resource editor, you will add a tree control for the tree view shell control, a list control for the list shell control, and a simple button is enough for the folder selector. After you generate the class via the resource editor, rename the tree control to CMFCShellTreeCtrl and the list control to CMFCShellListCtrl.

You only need to initialize the tree control. We will select a default starting point. Again, how you work with it remains the same as for a tree control. However, you do not need to populate it with items. The operating system will take care of this. The beauty of this is that you can bind together a shell list control and tree control. Afterward, the list control will show the items present under the path chosen in the tree control.

//Expand the root item

m_wbdShellTree.Expand (m_wbdShellTree.GetRootItem (), TVE_EXPAND);

// Bind together the tree control and the list control

m_wbdShellTree.SetRelatedList (&m_wndShellList);

The application will create the folder selector control. You only need to call the shell manager and ask for a folder. The method has six parameters, of which only the first is mandatory. This is where is put the path chosen by the user. The second parameter is the parent window. The third is the initial folder to show when the window first comes up.

The fourth is the title for the dialog box. The fifth is a flag specifying options for the dialog. By default, this is set to return only directories. For more information about this, look into the BROWSEINFO structure. Within the final parameter you can find the image index of the selected folder.

CString m_strSelectedFolder;

…

theApp.GetShellManager () ->BrowseForFolder (

m_strSelectedFolder, this, m_strSelectedFolder);

Masked Edit

There are times when you are looking for a specific input. In these cases you may want to force the user to enter only a given type of character sequence. The masked edit control will help you in this. The masked edit class (CMFCMaskedEdit) is derived from CEdit. In the resource editor, add an edit box, and after you create the class, rename the type to CMFCMaskedEdit.

A masked edit has a mask string and a template. The masked edit part is where you specify what type of input you allow in which position. The template is where you specify what characters will be shown in places where you did not specify any character (use the space character in the masked edit to do this). You may also specify what character to put instead of any wrong character entered or set up which input characters are allowed. You will find other functions related to this class in the table below:

Method

Effect

DisableMask

Disables input validation. 

EnableGetMaskedCharsOnly

Indicates whether or not the  GetWindowText function should return only masked characters

EnableMask

Initializes the masked edit control.

EnableSelectByGroup

Specifies whether the masked edit control selects particular groups of input or all input.

EnableSetMaskedCharsOnly

Validates against masked characters or against the whole mask.

GetWindowText

Returns the validated text from the control.

SetValidChars

Specifies the string of valid characters you expect from the user.

SetWindowText

Displays a prompt in the masked edit control.

Now let us see a practical example:

CMFCMaskedEdit m_wndMaskEdit1;

CString m_strValue1;

…

// Mask 1: phone number

// Parameters: 1) The mask string (specify in which position // what can appear)

// 2) Template of other characters to show. This // will not be editable. "_" char = character entry

// 3) Default char to substitute when invalid char // is entered as input

// 4) A string that contains the valid input characters

m_wndMaskEdit1.EnableMask (_T (" ddd ddd dddd"), _T ("(___) ___-____"),

_T (' '));

 

// Valid string characters => NULL means that all characters // are valid. Input will not accept any char not in the list.

m_wndMaskEdit1.SetValidChars (NULL);

 

// Set the text to show initially

// the user may modify or delete this)

m_wndMaskEdit1.SetWindowText (_T ("(123) 123-1212"));

…

//Get the text from the masked edit and save it in another

// variable that will be shown in a simple one

m_wndMaskEdit1.GetWindowText (m_strValue1);

The end result will look like this:

The table below points out which mask character means what. With this you can practice a little and make for yourself the other masked edits that you can see above.

Mask Character

Definition

D

Digit

d

Digit or space.

+

Plus ('+'), minus ('-'), or space.

C

Alphabetic character.

c

Alphabetic character or space.

A

Alphanumeric character.

a

Alphanumeric character or space.

*

A printable character.

Edit browse controls

Today I will also show you two additional types of controls. I will start with the edit browse controls. This are also derived from the CEdit and are present under the name CMFCEditBrowseCtrl. This helps you to search for a folder or a file. Do the usual stuff with adding an edit box and replacing it with the corresponding class name. Now all you need to do is call the EnableFolderBrowseButton method (for folders) or EnableFileBrowseButton method (for files) during the initialization of the dialog.

For the folder search, a shell tree control will come up, and the edit box will also have a file icon attached to show that, by clicking on it, you can search for folders. Additionally, once you select a path, it will display it. For the file list, the drill is the same, with the difference that an open type control will pop up and allow you to query for a file.

->The file browse<-

The creation of the corresponding item is inside the OnBrowse function. If you derive from the CMFCEditBrowseCtrl class, you can specify some custom behavior. The code snippet below will give a concrete example for each of these:

->The folder browse<-

class CMyBrowseEdit : public CMFCEditBrowseCtrl

{ virtual void OnBrowse()

{

MessageBox(_T("Browse item..."));

SetWindowText(_T("New value!"));

}

};

 

CMyBrowseEdit m_wndCustomEdit;

CMFCEditBrowseCtrl m_wndFolderEdit;

CMFCEditBrowseCtrl m_wndFileEdit;

 

m_wndFolderEdit.EnableFolderBrowseButton();

m_wndFileEdit.EnableFileBrowseButton();

m_wndCustomEdit.EnableBrowseButton();

->Custom browse<-

CVSListBox

This is the last control I will present. This is an editable list control. It allows some basic manipulation of items in a list control. You can add, remove and move up or down items inside a list control. The picture below presents one that is created.

The list box also allows the user to browse somewhere for the input item. Again, for this to work you need to derive from the CVSListBox class and override the OnBrowse method. Within this, you can do whatever you want. At the end you can either add a new text or exchange the text for one that is already in the list (an edit operation). The table that follows will show the functions you may call for help:

Method

For what can you use it?

AddItem

Add a new string to the list control.

EditItem

Start and edit operation on the text for a list control item. This is automatically called when you double click on a item).

GetCount

Returns the number of items present in the control.

GetItemData

Returns a 32-bit value that it is associated to a item at the given index.

GetItemText

Retrieve the text of an item.

GetSelItem

Retrieve a zero based index of the currently selected item.

RemoveItem

Remove an item form the list. (specify the zero based index)

SelectItem

Select an item in the list control. This happens with a simple left click.

SetItemData

The set pair for the GetItemData.

Below you'll find a code snippet presenting a simple illustration. For now the browse button will do nothing other than display a message box and set the “New text” or “Updated text” depending on whether you called it from an already-existing item or a new one.

 

class CCustomEditListBox : public CVSListBox

{

virtual void OnBrowse()

{

// for which item we started an browse

int nSel = GetSelItem();

 

MessageBox(_T("Browse item..."));

 

//If we edit an item after the last one it must be a new one

if (nSel == GetCount()) // New item

{

int nSel = AddItem(_T("New text"));

SelectItem(nSel);

}

else // or else it already exists

{

SetItemText(nSel, _T("Updated text"));

}

}

};

…

//declare an item

CCustomEditListBox m_wndEditListBox;

…

m_wndEditListBox.SetStandardButtons();

m_wndEditListBox.EnableBrowseButton();

m_wndEditListBox.AddItem(_T("Item 1"));

m_wndEditListBox.AddItem(_T("Item 2"));

m_wndEditListBox.AddItem(_T("Item 3"));

…

 

The CVSListBox is derived ultimately from the CStatic class. Therefore, use this class if you want to use it inside the resource editor.

This will be all for today. I hope I managed to give you some awesome knowledge. I would like to ask you to rate my article according to how good it seemed to you.

I also want to ask you to post your observations or questions regarding this article here in the comments section after the article. Additionally, if you have something else you'd like to talk about, join our friendly forum over at DevHardware and entrust yourself to the hands of our experts. You will not be disappointed! Until we have an opportunity to meet again: Live With Passion!

blog comments powered by Disqus
.NET ARTICLES

- .Net 4.5 Brings Changes
- Understanding Events in VB.NET
- Objects, Properties, Events and Methods in V...
- Install Visual Web Developer Express 2010
- Microsoft Gadgeteer an Open Source Alternati...
- Best DotNetNuke Modules
- Facebook Image Viewer in Visual Basic
- Murach`s ADO.NET 4 Database Programming with...
- 5 Must Have Visual Studio 2010 Extensions
- Dynamic Web Applications with ASP.NET Mono u...
- PDFSharp: HTML to PDF in ASP.NET 3.5 using V...
- Using the PDFSharp Library in ASP.NET 3.5 wi...
- Sending Email in ASP.NET 3.5 using VB.NET wi...
- ASP.NET 3.5 Role Based Security and User Aut...
- Creating ASP.NET Login Web Pages and Basic C...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 7 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials