4

I have a CEdit text box which is a part of a property pane and only allows numeric values (positive integers). The box works fine when people enter non-numeric values, but when they delete the value in the box a dialog pops up saying: "Please enter a positive integer."

Here is the situation:
1. I have a number (say 20) in the box.
2. I delete the number.
3. I get the error dialog.
Could anybody tell me how I can intercept this event and put a default value in there?

Here is what my property pane looks like:


const int DEFAULT_VALUE = 20;

class MyPropertyPane:public CPropertyPane
{
    //....
private:
    CEdit m_NumericBox;
    int   m_value;

    //....
public:
    afx_msg void OnEnChangeNumericBox();

    //....
}
void MyPropertyPane::MyPropertyPane()
{
   // Set a default value
   m_value = DEFAULT_VALUE;
}

//....
void MyPropertyPane::DoDataExchange(CDataExchange* pDX)
{
    DDX_Control(pDX, IDC_NUMERIC_BOX, m_NumericBox);

    // this sets the displayed value to 20
    DDX_Text(pDX, IDC_NUMERIC_BOX, m_value);
}

//....
void MyPropertyPane::OnEnChangeNumericBox()
{
    // Somebody deleted the value in the box and I got an event
    // saying that the value is changed.

    // I try to get the value from the box by updating my data
    UpdateData(TRUE);

    // m_value is still 20 although the value is 
    // deleted inside the text box.
}

Kiril
  • 39,672
  • 31
  • 167
  • 226

3 Answers3

9

The message you are receiving is coming from the data validation routines, not the data exchange routines. There is probably a call like this in DoDataExchange():

void MyPropertyPane::DoDataExchange(CDataExchange* pDX)
{
    DDX_Control(pDX, IDC_NUMERIC_BOX, m_NumericBox);
    DDX_Text(pDX, IDC_NUMERIC_BOX, m_value);
    DDV_MinMaxInt(pDX, m_value, 1, 20); // if the value in m_value is outside the range 1-20, MFC will pop up an error dialog
}

You can fix this problem by removing the built-in MFC data validation and adding your own:

void MyPropertyPane::DoDataExchange(CDataExchange* pDX)
{
    DDX_Control(pDX, IDC_NUMERIC_BOX, m_NumericBox);
    DDX_Text(pDX, IDC_NUMERIC_BOX, m_value);

    if( m_value < 1 || m_value > 20 )
    {
        m_value = DefaultValue;
    }
}
John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • But the m_value is still 20 even after it has been deleted... so checking if m_value < 1 will return false and the m_value will not be set to the DEFAULT_VALUE. The pop-up error "Please enter a positive integer" occurs before the OnChange event. – Kiril Apr 13 '09 at 14:57
  • Actually correction.. in DoDataExchange it doesn't even get past the DDX_Text(pDX, IDC_NUMERIC_BOX, m_value) so it wouldn't even hit the validation code. – Kiril Apr 13 '09 at 15:00
0

This one worked for me

void CtimersDlg::OnEnChangeInterval()
{
   CString value; //or use char *
   CWnd *pWnd = GetDlgItem(IDC_INTERVAL);//IDC_EDITBOX

   if(pWnd)
   {
      pWnd->GetWindowTextW(value);
   }

   int i = _wtoi(value); //if char * use _atol()
   if((!value.IsEmpty())&& (i))  //To check i = 0 or 00 entered or not
      UpdateData(TRUE);
}
Rajagopal 웃
  • 8,061
  • 7
  • 31
  • 43
jsmurthy4
  • 1
  • 1
0

John Dibling's hint led me to this solution:


void MyPropertyPane::OnEnChangeNumericBox()
{
    UpdateData(TRUE);
    CString value;
    m_NumericBox.GetWindowText(value);
    if( value.IsEmpty() )
    {
        m_value = DEFAULT_VALUE;
        UpdateData(FALSE);
    }
}

The ONLY validation that I really had to do is to check that the box contains a value, since the actual numeric validation is already handled by the box. The user can't enter a non-numeric value, but they can delete the existing one so that was a situation which was hard to handle in the data exchange function and I had to "hack" the OnChange event.

Kiril
  • 39,672
  • 31
  • 167
  • 226
  • This works in many cases, but it is often best to do all the data exchange & validation within the DoDataExchange() function because OnEnChangeNumericBox() may not be the only place where m_value is changed. For example if you have a radio button that changes m_value to preset values. – John Dibling Apr 13 '09 at 15:49
  • Good point, in general the DoDataExchange() function is probably the best place to do validations... my example is a bit of an exception. – Kiril Apr 13 '09 at 18:16