Improved Dialog Data Validation for Doubles






4.88/5 (4 votes)
Dialog data validation for doubles that allows you to specify a variable name and an interval range (e.g. [-90,90))
Introduction
Originally I wrote this as an utility class to check data when user clicks on OK button. However, a lot of checks in existing projects were done inDoDataExchange
. So after some time I realized that it would be nice to be able to replace existing validation calls in DoDataExchange
with my improved code, but in a simple way. That is how I came up with DDV_RangeDouble
.
DDX_RangeDouble
vs. (DDX_Text
and DDX_MinMaxDouble
)
DDV_RangeDouble
replaces both DDX_Text
and DDX_MinMaxDouble
in one call. But this is not the only difference. The main advantage is that instead of a simple min < value < max
comparison you can specify an interval range to check against the value. This interval is the same as an algebraic interval expression and is given as a string. For example, if you specify an interval "[0,90)"
the following check will be performed: 0<=value<90. Write 'inf' or '-inf' to specify positive or negative infinity for an unbound interval. Example: "[0.0,inf)"
will only test if the value is greater or equal to 0.0 Also, since the interval is specified as a string, you can put the name of the variable in the same string before the interval part (e.g.
"Angle [0,90)"
). This name will be shown in an error message similar to the one in the picture above. And the final difference is that, if the control is invisible or disabled, the validation will not be performed and no error message will be shown. The reason for this is that often you want to hide or disable edit controls when an associated variable is irrelevant in data input at certain state. MFC's
DDV_
functions, however, still validate those values and display errors, which can be confusing to users. You can also use
DDX_RangeDouble
in place of DDX_Text
without any validation, by omitting the last parameter (interval range) to the function. It will work exactly as DDX_Text
, except that it will not display an error message for non-numeric values in edit control if the control is invisible or disabled.
Usage
To use this in your dialog, include the header file at the top of the dialog implementation class and replace all relevantDDX_Text
calls with DDX_RangeDouble
. Remove DDX_MinMaxDouble
that follows DDX_Text
and put the value range as a string into DDX_RangeDouble
call. #include "DValidateValue.h" // header for Dialog Data Validation ... void CDlg_MyDemo::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDlg_MyDemo) //}}AFX_DATA_MAP DDV_RangeDouble(pDX, IDC_EDIT_UNIT_WT, m_UnitWt, "Unit Weight (0.0,inf)"); }
Important
- Make sure that you don't put
DDV_RangeDouble
inside theAFX_DATA_MAP
scope. Leave it outside, as shown in example, otherwise Class Wizard will not be able to parse the code. - Remember to replace both
DDX_Text
andDDX_MinMaxDouble
that follows it withDDV_RangeDouble
call.
Last Words
Although I wrote this code to work with doubles (I deal with mostly real numbers in my field), it is very easy to add similar functionality for integers. The easiest way would be to wrapDDV_RangeDouble
with a function that takes an integer argument. However, you would also want to add a check if the number in the edit control is an actual integer.