segmentation_fault
segmentation_fault

Reputation: 315

MFC initialize datetime picker control before custom validation gets executed

I have a dialog with two datetime controls whose format is set to time. One represents a start time and the other represents a end time.

One of the requirements is that the start time cannot be ahead of the end time and the end time cannot be before the start time.

So I am initializing the end time one hour ahead of whatever the current time is via the SetTime() function.

My problem is that I am initializing the two controls in the OnInitDialog() method, but DoDataExchange() is running before the OnInitDialog() function and thus the start time and end time are the exact same and it's causing my validation to fail and the dialog doesn't get created. The checking of the dates is being done in a custom validator which I adapted from here

How can I get the datetime controls to be initialized first? Or am I perhaps not approaching this correctly or is there something I am missing?

In OnInitDialog():

BOOL CNewManualEntryDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    m_dtStartTime.SetRange(&GetTodayTimeMin(), &GetTodayTimeMax());
    m_dtEndTime.SetRange(&GetTodayTimeMin(), &GetTodayTimeMax());

    m_dtEndTime.SetTime(&SetEndTimeOneHourAhead());

    return TRUE;
}

The functions above just return a CTime object. For reference the validator looks like so:

void CNewManualEntryDlg::TimePickerValidation(CDataExchange* pDX)
{
    CTime startTime;
    CTime endTime;
    m_dtStartTime.GetTime(startTime);
    m_dtEndTime.GetTime(endTime);

    BOOL isStartTimeBehindEndTime = startTime > endTime;
    CString errorMsg;
    if (!isStartTimeBehindEndTime)
    {
        errorMsg += "Error - Start time cannot be ahead of end time\n";
    }
    if (!errorMsg.IsEmpty())
    {
        ::AfxMessageBox(errorMsg);
        pDX->Fail();
        return;
    }

}

And I am just calling it in DoDataExchange() as such:

void CNewManualEntryDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialogEx::DoDataExchange(pDX);

   DDX_Control(pDX, IDDT_STARTTIMEPICKER, m_dtStartTime);
   DDX_Control(pDX, IDDT_ENDTIMEPICKER, m_dtEndTime);

   TimePickerValidation(pDX);
}

Upvotes: 1

Views: 458

Answers (1)

xMRi
xMRi

Reputation: 15355

You are doing the validation always. Always means, you are performing the validation when you load the data into the dialog, and when you commit the data.

DoDataExchange() is called in both ways. You can determine the pDX->m_bSaveAndValidate to check if you are in the saving phase.

if (pDX->m_bSaveAndValidate)
   TimePickerValidation(pDX);

Upvotes: 4

Related Questions