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 15 years.

There are n+1 ways of doing input validation and to report errors to user, can you elaborate on why is this one so objectionable to you and what is your preferred solution ? THAT would be helpful... txs

Bug Report: When a message map is added to the derived class, for example, CFloatEdit, Regular Expression do not get evaluated by the edit box. The edit box essentially become a standard edit box again.
CFilterEdit is an excellent project. The use of Boost Regular Expressions is beautiful.

What you are describing regarding message maps is normal behaviour. Have a look at CDateEdit to see how to use a message map in a derived class and still use the base behaviour. Think of it as the same as over-riding a virtual function - if you want to also include the behaviour of the class you are deriving from you must manually call the base function yourself.

For example you will see in CDateEdit::OnChar I call CFilterEdit::OnChar, but only on certain conditions. The rule is, that as soon as you trap one of the Windows messages that CFilterEdit would normally handle, you take on the responsibility for everything continuing to work as it should. I have strived to make CFilterEdit flexible enough to allow any extra validation anyone could dream up, whilst still being able to use the base behaviour.

All of this needs explaining in the article at some point - the more questions I get, the more I will be motivated to do it!

I've added a check so that the wavy line is not drawn on the edit control border. I tried redrawing the border, but in the case where an error colour is set, some of the wavy line is still not cleared. I'm therefore sticking with the approach of only drawing the line if there is enough space in the control.

Hi,what about STLport support for this class? More precisely for non-unicode version of your DfaRegEx class under STLport. STLport does not support basic_string<unsigned char>, only basic_string<signed char>. Or is there any way I can use boost::regex library without rest of boost?

Many thanks for your reply and mainly for these classes - they are great! ;o)