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 in
DoDataExchange
. 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 relevant
DDX_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);
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 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_Text
and DDX_MinMaxDouble
that follows it with DDV_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 wrap
DDV_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.