Click here to Skip to main content
12,297,840 members (53,989 online)
Click here to Skip to main content
Add your own
alternative version


246 bookmarked

CFilterEdit: Use Regular Expressions to Filter Your Input

, 3 Oct 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
The definitive approach to filtering input text. Includes configurable error display.
Screenshot - FilterEdit.png


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.

Design Decisions

  • Validation must be clean and reliable
  • The control should be usable exactly like CEdit
  • Only a handful of visual effects will be included as standard
  • 'WM_KILLFOCUS is the wrong time to do field validation'
  • Auto-formatting should be easy to add from a derived class
  • FilterEdit must stay as simple as possible and not get too bloated!

Intercepted Windows Messages

The following Windows messages are trapped for validation purposes:

  • WM_CUT

... and these are trapped to perform the visual effects:


Windows Message Overrides for Validation


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.


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


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.


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


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:

BOOL CEditTestDlg::OnInitDialog()
    CDialog::OnInitDialog ();
    m_DateEdit.CreateToolTip (this, _T("Tooltip text here"));

The C++ Standard Regular Expression Library

The boost::regex library has been accepted into the C++ Standard Library. Due to its partial match support, the library is also ideal for this control. Get the Boost library here.


  • Add more demo controls
  • Tutorial for deriving controls


All feedback is most welcome!

Revision History

  • - 30th July, 2004
    • Original version posted
  • - 8th August, 2007
    • BUG FIX: Now using GetKeyState() in CBaseEdit::OnKeyDown()
  • - 22nd August, 2007
    • Now allows user to delete the entire contents of an edit control, regardless of the regex
  • - 14th January, 2008
    • Changed CDateEdit - now CDateTimeEdit
  • - 25th February, 2008
    • Fixed double paste bug
  • - 13th June, 2008
    • Added bool CDateTimeEdit::GetTimeStamp (SQL_TIMESTAMP_STRUCT *pTS)
    • Filter out Ctrl-X, Ctrl-C and Ctrl-V in CBaseEdit::ValidateChar()
  • - 8th August, 2008
    • Display tooltip right at the bottom of the edit control to avoid painting overwriting spin control border!
  • - 15th September, 2008
    • Use system colours as defaults, support boost::gregorian::date
  • - 15th October, 2008
    • Dynamic calendar dialog and bitmap for CDateTimeEdit (no resource file entries required now)
  • - 7th November, 2008
    • Fixed assertions in CDateTimeEdit::WindowProc
  • - 5th December, 2008
    • Added boost posix_time support to CDateTimeEdit
  • - 9th January, 2009
    • Allow WM_SETTEXT to set an empty string even if regex forbids it
  • - 1st May, 2009
    • Interface change for Date/Time Get functions
  • - 7th September, 2009
    • Bug fix to CDateTimeEdit::SyntaxCheck
  • - 19th May, 2010
    • Adds unsigned support to FloatEdit
  • - 7th October, 2010
    • This version extends CFloatEdit so that you can specify the number of digits for the whole part
  • - 25th October, 2010
    • This version fixes a bug in CDateTimeEdit::SetTime()
  • - 26th January, 2011
    • This version adds an HHMM mode for times
  • - 17th February, 2011
    • This version adds the BS_DEFPUSHBUTTON style to the calendar button in CDateTimeEdit
  • - 21st February, 2011
    • Changed the date ordering for get/set functions in CDateTimEdit to bring it in line with COleDateTime
  • - 8th April, 2011
    • This update fixes range checking in CDateTimeEdit::SetTime()
  • - 12th September, 2011
    • This version adds SetMin() and SetMax() to CDateTimeEdit and fixes some bugs
  • - 3rd October, 2011
    • This version fixes a bug in CDateTimeEdit::SemanticCheck()


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Ben Hanson
Software Developer (Senior)
United Kingdom United Kingdom
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.

You may also be interested in...

Comments and Discussions

GeneralMy vote of 5 Pin
Michael Haephrati27-Jan-12 8:30
memberMichael Haephrati27-Jan-12 8:30 
GeneralNice article Pin
CIDev25-May-11 5:11
memberCIDev25-May-11 5:11 
General“,” (Komma) instate decimal “.” Pin
PeetHV31-Mar-11 6:43
memberPeetHV31-Mar-11 6:43 
AnswerRe: “,” (Komma) instate decimal “.” Pin
Ben Hanson7-Apr-11 1:53
memberBen Hanson7-Apr-11 1:53 
Generalnice - have 5 Pin
Pranay Rana26-Jan-11 17:26
memberPranay Rana26-Jan-11 17:26 
GeneralNice Pin
PatLeCat16-Oct-10 4:55
memberPatLeCat16-Oct-10 4:55 
GeneralRe: Nice Pin
Ben Hanson16-Oct-10 8:29
memberBen Hanson16-Oct-10 8:29 
AnswerRe: Nice Pin
PatLeCat16-Oct-10 10:52
memberPatLeCat16-Oct-10 10:52 
AnswerRe: Nice Pin
Ben Hanson17-Oct-10 1:05
memberBen Hanson17-Oct-10 1:05 
GeneralMy vote of 5 Pin
Member 16579811-Oct-10 20:19
memberMember 16579811-Oct-10 20:19 
GeneralRe: My vote of 5 Pin
Ben Hanson16-Oct-10 8:31
memberBen Hanson16-Oct-10 8:31 
GeneralMy vote of 5 Pin
DRLaverdure11-Oct-10 16:40
memberDRLaverdure11-Oct-10 16:40 
GeneralRe: My vote of 5 Pin
Ben Hanson16-Oct-10 8:30
memberBen Hanson16-Oct-10 8:30 
QuestionHow to use class FloatEdit Pin
bkelly1322-Jun-08 2:35
memberbkelly1322-Jun-08 2:35 
AnswerRe: How to use class FloatEdit Pin
Ben Hanson24-Jun-08 8:52
memberBen Hanson24-Jun-08 8:52 
General Pin
bkelly1321-Jun-08 6:21
memberbkelly1321-Jun-08 6:21 
GeneralRe: Pin
Ben Hanson24-Jun-08 8:34
memberBen Hanson24-Jun-08 8:34 
GeneralMessage Automatically Removed Pin
16-Jan-08 5:58
memberHeywood16-Jan-08 5:58 
GeneralRe: This HORSE IS DEAD Jim... Pin
yafan16-Jan-08 6:32
memberyafan16-Jan-08 6:32 
GeneralRe: This HORSE IS DEAD Jim... Pin
Mihai Maerean20-Oct-08 19:07
memberMihai Maerean20-Oct-08 19:07 
QuestionValidating ALT characters Pin
narlad2-Oct-07 6:17
membernarlad2-Oct-07 6:17 
AnswerRe: Validating ALT characters Pin
Ben Hanson10-Oct-07 2:07
memberBen Hanson10-Oct-07 2:07 
GeneralValidate URL with regex Pin
dressman198112-Jun-07 9:30
memberdressman198112-Jun-07 9:30 
AnswerRe: Validate URL with regex Pin
Ben Hanson13-Jun-07 4:30
memberBen Hanson13-Jun-07 4:30 
GeneralRe: Validate URL with regex Pin
dressman198114-Jun-07 4:43
memberdressman198114-Jun-07 4:43 
AnswerRe: Validate URL with regex Pin
Ben Hanson14-Jun-07 22:01
memberBen Hanson14-Jun-07 22:01 
GeneralRe: Validate URL with regex Pin
dressman198114-Jun-07 23:02
memberdressman198114-Jun-07 23:02 
AnswerRe: Validate URL with regex Pin
Ben Hanson15-Jun-07 5:32
memberBen Hanson15-Jun-07 5:32 
GeneralRe: Validate URL with regex Pin
TheBlindSquirrel22-Aug-07 12:15
memberTheBlindSquirrel22-Aug-07 12:15 
GeneralBug with XP-Style / Manifest-file Pin
dressman198123-May-07 4:05
memberdressman198123-May-07 4:05 
GeneralRe: Bug with XP-Style / Manifest-file Pin
Ben Hanson26-May-07 7:30
memberBen Hanson26-May-07 7:30 
GeneralRe: Bug with XP-Style / Manifest-file Pin
dressman198128-May-07 7:22
memberdressman198128-May-07 7:22 
GeneralBeating a dead horse Pin
Heywood22-Dec-06 4:42
memberHeywood22-Dec-06 4:42 
GeneralRe: Beating a dead horse Pin
Chris Conn15-Feb-07 5:52
memberChris Conn15-Feb-07 5:52 
GeneralRe: Beating a dead horse Pin
Galatei8-Oct-10 14:03
memberGalatei8-Oct-10 14:03 
GeneralRe: Beating a dead horse Pin
Heywood11-Oct-10 3:47
memberHeywood11-Oct-10 3:47 
QuestionValidate regex? Pin
are_all_nicks_taken_or_what8-Jan-06 4:10
memberare_all_nicks_taken_or_what8-Jan-06 4:10 
AnswerRe: Validate regex? [modified] Pin
Ben Hanson8-Jan-06 21:34
memberBen Hanson8-Jan-06 21:34 
GeneralRe: Validate regex? Pin
are_all_nicks_taken_or_what9-Jan-06 5:47
memberare_all_nicks_taken_or_what9-Jan-06 5:47 
QuestionBug with paste Pin
Firejano3-Jan-06 2:51
memberFirejano3-Jan-06 2:51 
JokeRe: Bug with paste Pin
Firejano3-Jan-06 2:57
memberFirejano3-Jan-06 2:57 
AnswerRe: Bug with paste Pin
Ben Hanson5-Jan-06 2:58
memberBen Hanson5-Jan-06 2:58 
GeneralRe: Bug with paste Pin
Ben Hanson25-Feb-08 2:10
memberBen Hanson25-Feb-08 2:10 
QuestionBug with Paste Pin
Firejano19-Dec-05 2:31
memberFirejano19-Dec-05 2:31 
AnswerRe: Bug with Paste Pin
Ben Hanson20-Dec-05 20:43
memberBen Hanson20-Dec-05 20:43 
GeneralWavy error line rendered incorrectly with ES_CENTER or ES_RIGHT Pin
Obliterator13-Dec-05 9:10
memberObliterator13-Dec-05 9:10 
Great edit control, thanks!
Its nice to warn the user, without irritating them!

Anyhow, one small bug. The wavy error line is not rendered correctly for edit boxes with centred or right aligned text (ES_CENTER|ES_RIGHT sytle).

A quick change to CFilterEdit::OnPaint() soon rectifies this:

void CFilterEdit::OnPaint()
	... Unchanged
		// Check for case of empty string
		if ( == 0) = iIncrement * 3;
		// -- Begin Changes (support left, centred or right aligned styles)
		// Dont draw off the end of the edit control
		else if ( > rect.right) = rect.Width();
		// Starting x co-ordinate to start drawing from			
		int iOffset = 0;
		if (GetStyle () & ES_CENTER)						
			iOffset = ((rectClient.Width();		
		else if(GetStyle () & ES_RIGHT)						
			iOffset = rectClient.Width();			
		// Start at the bottom left of the edit control
		dc.MoveTo (rect.left+iOffset, rect.bottom);				
		int i=0;
		// Draw the wavy line like in Microsoft Word
		while (iX < )
			dc.LineTo (rect.left+iOffset+iX, rect.bottom);
			iX += iIncrement;
			if (iX > )
			dc.LineTo (rect.left+iOffset+iX, rect.bottom + iIncrement);
			iX += iIncrement;
		// -- End Changes
		TRACE (_T("Edit Control too small to draw wavy line!\r\n"));
	... Unchanged


The Obliterator
General1.0.3.3 Posted Pin
Ben Hanson13-Dec-05 20:23
memberBen Hanson13-Dec-05 20:23 
GeneralLet this thing DIEEEEEEEEE! Pin
Heywood18-Jul-05 4:20
memberHeywood18-Jul-05 4:20 
QuestionRe: Let this thing DIEEEEEEEEE! Pin
Panic2k313-Feb-07 15:01
memberPanic2k313-Feb-07 15:01 
GeneralMessage Maps Bug Pin
SeanJasonByrne10-Jun-05 11:54
memberSeanJasonByrne10-Jun-05 11:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160525.2 | Last Updated 3 Oct 2011
Article Copyright 2004 by Ben Hanson
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid