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 in
. So after some time I realized that it would be nice to be able to replace existing validation calls in
with my improved code, but in a simple way. That is how I came up with
DDX_RangeDouble vs. (
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
the following check will be performed: 0<=value<90. Write 'inf' or '-inf' to specify positive or negative infinity for an unbound interval. Example:
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.
). 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
functions, however, still validate those values and display errors, which can be confusing to users.
You can also use
in place of
without any validation, by omitting the last parameter (interval range) to the function. It will work exactly as
, except that it will not display an error message for non-numeric values in edit control if the control is invisible or disabled.
To use this in your dialog, include the header file at the top of the dialog implementation class and replace all relevant
and put the value range as a string into
void CDlg_MyDemo::DoDataExchange(CDataExchange* pDX)
DDV_RangeDouble(pDX, IDC_EDIT_UNIT_WT, m_UnitWt,
"Unit Weight (0.0,inf)");
- Make sure that you don't put
DDV_RangeDouble inside the
AFX_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_MinMaxDouble that follows it with
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 wrap
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.