strange CMonthCalCtrl behavior
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: strange CMonthCalCtrl behavior

  1. #1
    Join Date
    Dec 2001
    Location
    GERMANY
    Posts
    198

    strange CMonthCalCtrl behavior

    Hi everyone.
    I've got a problem using the month/calendar control in my dialog based app (running on W2K).
    If I include a calendar control in my app's main dialog and link it to a CTime member variable, everything is fine.
    If I place a calendar control in a dialog which I show after the user clicks a button in the main dialog,
    the calendar control in this 2nd dialog will not correctly retrieve the selected date.
    Here's the code for my modal dialog which is shown when the user clicks a button on the main dialog:

    CalenderCtrlTestDlg1::CalenderCtrlTestDlg1(CWnd* pParent /*=NULL*/)
    : CDialog(CalenderCtrlTestDlg1::IDD, pParent)
    {
    //{{AFX_DATA_INIT(CalenderCtrlTestDlg1)
    m_Calendar1 = 0;
    //}}AFX_DATA_INIT
    }


    void CalenderCtrlTestDlg1:oDataExchange(CDataExchange* pDX)
    {
    CDialog:oDataExchange(pDX);
    //{{AFX_DATA_MAP(CalenderCtrlTestDlg1)
    DDX_MonthCalCtrl(pDX, IDC_MONTHCALENDAR1, m_Calendar1);
    //}}AFX_DATA_MAP
    }


    BEGIN_MESSAGE_MAP(CalenderCtrlTestDlg1, CDialog)
    //{{AFX_MSG_MAP(CalenderCtrlTestDlg1)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    /////////////////////////////////////////////////////////////////////////////
    // CalenderCtrlTestDlg1 message handlers

    void CalenderCtrlTestDlg1::OnOK()
    {
    // TODO: Add extra validation here
    UpdateData(TRUE);
    CString c1;
    CString c2;
    CMonthCalCtrl * pCal2 = (CMonthCalCtrl*) GetDlgItem(IDC_MONTHCALENDAR2);
    c1 = m_Calendar1.Format("%d.%m.%Y ");
    CTime c2Time;
    pCal2->GetCurSel(c2Time);
    c2 = c2Time.Format(" %d.%m.%Y");
    MessageBox(c1 + c2);
    CDialog::OnOK();
    }

    BOOL CalenderCtrlTestDlg1::OnInitDialog()
    {
    CDialog::OnInitDialog();
    m_Calendar1 = CTime::GetCurrentTime();
    UpdateData(FALSE);
    return TRUE; // return TRUE unless you set the focus to a control
    // EXCEPTION: OCX Property Pages should return FALSE
    }





    If I don't change the date in the calendar control, the MessageBox shows the correct information.
    If I choose the next day (i.e. "tomorrow"), the date shown in the messagebox is a date in 2006!
    I'm really stumped here as to what's going on. Any help will be greatly appreciated.


    Please rate my answer, whether good or bad, so I can improve the answers I give. Thanks!

  2. #2
    Join Date
    Dec 2001
    Location
    GERMANY
    Posts
    198

    Re: strange CMonthCalCtrl behavior

    Just to make this even more interesting:
    1) The calendar controls in the main dialog do NOT work,
    they show the same problems as those in the 2nd dialog.

    2) I just ran the same test program on WinNT 4.0 and everything works fine. This seems to confirm a similar problem I had with calendar controls in another program I wrote. A customer had Windows ME and complained that the calendars never worked properly. Now I see what he meant.

    Has anyone else observed this behavior? Any ideas?


    Please rate my answer, whether good or bad, so I can improve the answers I give. Thanks!

  3. #3
    Join Date
    Feb 2002
    Posts
    1

    Re: strange CMonthCalCtrl behavior

    I ran into this problem too using this darn control. Apparently there's a bug in using UpdateDate/CTime to get accurate values and you have to use a SYSTEMTIME structure as an intermediary. Here's a snippet work-around that I found would work:


    void CCalTestView::OnProcess()
    {
    COleDateTime cDateTime;
    SYSTEMTIME stSystemTime;

    CString sDateTime(_T(""));
    m_ctlCalendar.GetCurSel(&stSystemTime);
    cDateTime.SetDate(stSystemTime.wYear, stSystemTime.wMonth, stSystemTime.wDay);
    sDateTime += cDateTime.Format(_T("%B %d, %Y"));
    }




    In this example (triggerd from a button click), I have a dialog-based class and have defined a variable using ClassWizard (m_ctlCalendar) of type CMonthCalCtrl. I call the GetCurSel member function of the CMonthCalCtrl class and pass it the address of my SYSTEMTIME instance which the control will populate with the proper values (based on the user's selection). You can then use a COleDateTime instance in conjunction with the SYSTEMTIME structure to process your values (you don't have to do this, but in this example, I just stuffed the formatted string into a CString for illustrative purposes).

    Hope this helps!

    Jon


  4. #4
    Join Date
    Dec 2001
    Location
    GERMANY
    Posts
    198

    Re: strange CMonthCalCtrl behavior

    Thanks a lot for your suggestions, they provide a great workaround for the problem. I must admit that I'm surprised that a problem like this slipped past the Microsoft test department. Maybe the control isn't popular enough and the general programming population hasn't raised enough hell to force them to offer a fix or an "official" workaround. When stepping through the debugger, it appears that the MCM_GETCURSEL message is improperly handled. The hour, minute, and second fields have values which indicate that they were never initialized to zero. A brief summary of what I observed:

    1) GetCurSel(COleDateTime& refTime) uses SendMessage() to get
    a SYSTEMTIME structure with the current date and time from the control. The time-related fields of this structure are NOT initialized to zero. My system delivers fields with the values wHour=2680, wMinute = 76, wSecond = 64420, wMilliseconds=18.

    2) The time parameter is assigned with the operator =() to a COleDateTime constructor which takes a SYSTEMTIME as its argument:

    refTime = COleDateTime(sysTime);




    3) The ctor with the sysTime argument looks something like this:

    _AFXDISP_INLINE COleDateTime::COleDateTime(const SYSTEMTIME& systimeSrc)
    { *this = systimeSrc; }





    4) The operator =() for COleDateTime with a SYSTEMTIME argument calls the function _AfxOleDateFromTm(),
    which is where everything screws up, as the function checks ALL the fields of the SYSTEMTIME structure before assigning them to the appropriate member items of the COleDateTime object. The hour, minute and second fields don't pass the check, and the function bails out.

    This whole process leaves us with a COleDateTime object which doesn't have the appropriate date info, just because the Win2k / WinME, etc versions of the message handler for MCM_GETCURSEL doesn't initialize the fields of the SYSTEMTIME structure to zero.

    The GetCurSel() version with the SYSTEMTIME structure as an argument directly calls SendMessage with MCM_GETCURSEL and receives the SYSTEMTIME. We can directly use the month, day and year fields (as per your tip), but don't even think about using the time fields. After following your tip, I made the following addition, which allows us to use the other classes (COleDateTime and CTime) in the rest of the code:

    CMonthCalCtrl* pCal = (CMonthCalCtrl*) GetDlgItem(IDC_MONTHCALENDAR1);
    SYSTEMTIME sysTime;
    pCal->GetCurSel(&sysTime);
    COleDateTime badOleTime(sysTime);
    CString txtBadTime = badOleTime.Format("%d.%m.%Y ");
    sysTime.wHour = 0;
    sysTime.wSecond = 0;
    sysTime.wMinute = 0;
    sysTime.wMilliseconds = 0;
    COleDateTime oleTime(sysTime);
    CString txtTime;
    txtTime = oleTime.Format("%d.%m.%Y ");
    MessageBox(txtBadTime + txtTime);




    The txtBadTime always delivers "Invalid Date Time", while the txtTime string hold the desired value.


    Once again, thanks a bunch for your help.
    Best regards,
    Jason

    Please rate my answer, whether good or bad, so I can improve the answers I give. Thanks!

  5. #5
    Join Date
    Apr 2002
    Posts
    1

    Re: strange CMonthCalCtrl behavior

    Hi

    I have a situation where I have to capture the user selected date. I used the foll. code to do it, but it always returns the system date. Never returned the user selection. Any ideas? Any help is appreciated!

    Thanks!
    anantha komaralingam

    CMonthCalCtrl m_Calendar;
    CRect rect(10, 50, 100, 150);
    m_Calendar.Create(WS_CHILD | WS_VISIBLE | DTS_SHORTDATEFORMAT, rect, this, IDD_CALENDER);

    COleDateTime dateTime;
    int ret = m_Calendar.GetCurSel(dateTime);
    UpdateData(FALSE);
    CString wYear = dateTime.GetYear();
    CString wMonth = dateTime.GetMonth();
    CString wDay = dateTime.GetDay();


  6. #6
    Join Date
    Aug 2009
    Posts
    1

    Re: strange CMonthCalCtrl behavior

    Had exactly the same problem using Visual Studio 6 for a simple XML time logging app I'm writing - JBryd you fixed worked a treat many thanks!

    Jon... (techdojo)

    http://www.whitetreegames.com

  7. #7
    Join Date
    Sep 2004
    Location
    Holland (land of the dope)
    Posts
    4,123

    Re: strange CMonthCalCtrl behavior

    jwycoff... after 198 post you should know that we use code tags to post code.

  8. #8
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,057

    Re: strange CMonthCalCtrl behavior

    Quote Originally Posted by Skizmo View Post
    jwycoff... after 198 post you should know that we use code tags to post code.
    After 7 years, I'm not sure he cares any more.

    What is it with noobs and thread archeology? Sigh

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center