Introduction

Ever since computers were invented, data validation has been an important concern. When it comes to a user interface, the fastest way to validate data is whilst it is being input. Strange, then, that there is no standard Windows edit control that tackles this problem for any kind of data.

This validating edit control aims to provide the ultimate Framework for data validation, no matter how complex the data you are attempting to input is.

Windows Message Overrides for Validation

CBaseEdit::OnChar

WM_CHAR is the Windows message that every validating edit control ever written for Windows must have trapped. This is where a single character can be checked to see if the control will accept it or not.

CBaseEdit::OnKeyDown

WM_KEYDOWN is where the Delete key, Ctrl-X, Ctrl-C and Ctrl-V are trapped.

CBaseEdit::OnKillFocus

Again, WM_KILLFOCUS is a very popular message to trap. However, rather than trying to set the focus back to the control in the event that the input is incomplete, we just flag the error and allow the focus to switch normally.

CBaseEdit::OnSetFocus

WM_SETFOCUS is trapped simply so that we can set any colours we need to and display a tooltip if required.

CBaseEdit::WindowProc

This is where the rest of the Windows messages we are interested in are processed.

How to Derive Your Own Custom Control

Here are the four obvious things you might want to do:

Override SemanticCheck

See the CUIntRangeEdit example to see how this works.

Trap WM_CHAR yourself

By trapping characters yourself, you can automatically format input and perform semantic validation as the user types. Refer to the CDateTimeEdit example to see how this works.

Trap WM_KILLFOCUS yourself

You may want to perform extra formatting when the user leaves the control. Again, see the CDateTimeEdit example. Don't forget to call CBaseEdit::OnKillFocus if you do this!

Override SyntaxCheck

This is if you want to pre-process the string before running the syntax checking. See CDateTimeEdit for an example.

Example Controls Included in the ZIP

CCurrencyEdit

CDateTimeEdit

CFloatEdit

CIntEdit

CUIntEdit

CUIntRangeEdit

CSpin

Tooltip Support

You might want to explain the data format for your controls at runtime. For this reason, Balloon Help support is included. To include this support, you must call CreateToolTip:

Share

About the Author

I started programming in 1983 using Sinclair BASIC, then moving on to Z80 machine code and assembler. In 1988 I programmed 68000 assembler on the ATARI ST and it was 1990 when I started my degree in Computing Systems where I learnt Pascal, C and C++ as well as various academic programming languages (ML, LISP etc.)

I have been developing commercial software for Windows using C++ for 22 years.

Unfortunately too many programmers do input validation as an afterthought, if they think about it at all. Also not enough programmers are familiar with RegEx.So cudos for a well written and useful article.

The short answer is that I favoured a C++ solution (exception safety blah, blah, blah...) Of course boost::regex provides this and incidentally so does lexertl (http://www.benhanson.net/lexertl.html[^]).

I am trying to determine how to use FloatEdit to validate a string from a dialog as a float or double value. First, in FloatEdit.cpp I notice the function:double CFloatEdit::GetValue () const

Let see, GetValue(), that means go and get/ retrieve something from somewhere. But there is no argument to specify the source of the data. Rather than being a straight forward function, it must rely on what is called a side effect. So we check into the function and look for that side effect.

I find function:GetWindowText (strFloat);

Another function that gets (that is to say, retrieves) something, expectedly text. But what is the source of the data retrieved. The name of the argument indicates a string. But a string is what I want it to get. Now I see that StrFloat is declared locally so GetWindowText must get the string from somewhere. Where? How does it know where to get the text.

Search for GetWindowText. Not found. Go to the boot library that I installed in C:/Program Files\boost. Not found.

Go to windows help function and loop up GetWindowText:

int GetWindowText( HWND hWnd, LPTSTR lpString, int nMaxCount );

Hmmm, not the same function. There appears to be insufficient information to determine how this works.

So, describe my need and maybe someone will give me a clue:

One of the fields if my dialog that I want filtered is an edit control box and has the ID: IDC_X_POSITION_EDITand strings in the box can be accessed via a variable name as follows:GBE_x_position_string.GetWindowTextW( str );That puts the value into CString names str. This does indeed provide the string from the dialog box.

Will someone tell me how to use this FloatEdit to:1. verify that the text in this dialog box text field is valid for a float or double, and 2. How put that value into a double variable?

The horse is dead only when there are no more people interested in it. This is not the case here, partially because WPF was released unfinished and because the C++/CLI syntax to access Windows Forms is not so pleasant. And you may want to control the memory footprint of your application.

I need to take an existing English application and accept special characters typed from the keyboard like èï, et. The member variable of the dialog is defined as a CString. When I trap the CString the character is properly displayed in debugger but the value is negative. Using iswalpha does not identify it as an alpha character (using isalpha throws exception.) I also need to disallow digits and iswdigit does not work. Where do I go for help?Thanks.