|
-
February 23rd, 2002, 04:59 AM
#4
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!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|