For lack of a better workflow I decided to start my project off by focusing on restoring it's state in CWinApp::InitInstance() and saving its state in CMainFrame::OnDestroy() as I put in data structures.

One of the items to restore/save is the simulation time. In fact the app pretty much can't run w/o one set. So I decided in InitInstance() to ask the user to enter a time for the simulator via a dialog with a CMonthCalCtrl and a subclassed CEdit made just for entering time values.

The problem is that my setup is a little like a mixed salad.... VC++ 6 with the MSDN from VC++ 5. One of those things where my brother destroys my VC5 CD and makes up for it by grabbing a copy of VC6 from his employer. Anyway... this results in the documentation I have saying nothing about CMonthCalCtrl or CDateTimeCtrl at all. So I've been searching online for a while.

I want to set the date in the control to 8/31/1999. Seems simple enough.... call Get/SetCurSel() with SYSTEMTIME *, CTime &, or COleDateTime &. I tried originally with CTime but the peeps at Microsoft didn't implement that correctly... SYSTEMTIME should work but SetCurSel() still returns 0..... Then comes COleDateTime. It seems to work as SetCurSel() returns 1 in the debugger but now I have some stack problem from somewhere. The IDE says the ESP register isn't saved across a function call.

How do I get this to work? Thanks for any advice.

The error occurs when OnInitDialog() returns.... and is apparently caused by sysTime.SetDate(). The following code (now that I uncommented the SetCurSel call) sets the control to 12/31/1969 so that part works..... just not the SetDate() call.

Other things I've tried and failed (in place of the commented SetDate() call) which failed.....

sysTime = (time_t)(t - t%86400);
	....
	::memset(&sysTime,0,sizeof(SYSTEMTIME));
	sysTime.wDay = vTimeData.tm_mday;
	sysTime.wMonth = vTimeData.tm_mon + 1;
	sysTime.wYear = vTimeData.tm_year + 1900;

First one was both with CTime and COleDateTime. Second group is with SYSTEMTIME. All cases failed except SetDate() :(

BOOL CAppTimeDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	CMonthCalCtrl *pCalendar = (CMonthCalCtrl *) this->GetDlgItem(IDC_MONTHCALENDAR);
	CStatic *pStatic = (CStatic *) this->GetDlgItem(IDC_STATIC_APPMOD);

	struct tm vTimeData;
	time_t t;
	string s;
	char date[32];

	vTimeData.tm_sec = 0;
	vTimeData.tm_hour = 0;
	vTimeData.tm_min = 0;
	vTimeData.tm_mday = 1;	//1-based
	vTimeData.tm_mon = 8;	//0-based
	vTimeData.tm_year = 99;	//Must subtract 1900

	t = ::mktime(&vTimeData);
	t -= ::g_Timer.GetTZOffset() << 1;	//Removing shift and changing to ::localtime
	vTimeData = *::gmtime(&t);		//results in almost the correct behavior. DST
						//ruins it. Of course it could be fine and my
						//math could be off.. per usual.

//	sysTime.SetDate(vTimeData.tm_year + 1900,vTimeData.tm_mon + 1,vTimeData.tm_mday);

	::strftime(date,31,"%H:%M %b %d, %Y",&vTimeData);
	
	s = "Set the simulation start time. Please enter a date and time between ";
	s += date;

	::time(&t);
	vTimeData = *::gmtime(&t);
	vTimeData.tm_mon -= 3;

	if(vTimeData.tm_mon < 0) {
		vTimeData.tm_mon += 12;
		--vTimeData.tm_year;
	}
	::strftime(date,31,"%b %d, %Y",&vTimeData);

	s += " and midnight ";
	s += date;

	pStatic->SetWindowText(_T(s.c_str()));
	bool b = pCalendar->SetCurSel(sysTime);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

Do I need to setup the environment somehow to use OLE functions? Doing simple things like using a constructor to set the date fails. When I try and get the time from the Calendar I get junk. I cant even use the GetYear/Month/Day functions on the variable without the program crashing.

Well it took some time but I figured out a way to get it done. In a book I had two pages talk about this control (unfortunately it's not in the index or the chapter on controls LOL). Although the author mentions the CMonthCalCtrl function calls which aren't working for me one thing did...... using messages. So below is how I fixed it after a little searching online to find the various messages I needed.

BOOL CAppTimeDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	CMonthCalCtrl *pCalendar = (CMonthCalCtrl *) this->GetDlgItem(IDC_MONTHCALENDAR);
	CStatic *pStatic = (CStatic *) this->GetDlgItem(IDC_STATIC_APPMOD);

	SYSTEMTIME st[2];
	struct tm vTimeDataBeg, vTimeDataEnd;
	string s;
	char date[32];

	m_wndTime.SubclassDlgItem(IDC_EDIT_APPTIME,this);

	vTimeDataBeg.tm_sec = 0;
	vTimeDataBeg.tm_hour = 0;
	vTimeDataBeg.tm_min = 0;
	vTimeDataBeg.tm_mday = 1;	//1-based
	vTimeDataBeg.tm_mon = 8;	//0-based
	vTimeDataBeg.tm_year = 99;	//Must subtract 1900

	m_tBeg = ::mktime(&vTimeDataBeg);
	m_tBeg -= ::g_Timer.GetTZOffset() << 1;	//Removing shift and changing to ::localtime
	vTimeDataBeg = *::gmtime(&m_tBeg);		//results in almost the correct behavior. DST
										//ruins it. Of course it could be fine and my
										//math could be off.. per usual.
	m_wndTime.UpdateField(m_tBeg%86400);		//Sets time in TimeEdit control.
	::strftime(date,31,"%H:%M %b %d, %Y",&vTimeDataBeg);
	
	s = "Set the simulation start time. Please enter a date and time between ";
	s += date;

	::time(&m_tEnd);
	vTimeDataEnd = *::gmtime(&m_tEnd);
	vTimeDataEnd.tm_mon -= 3;
	m_tEnd = ::mktime(&vTimeDataEnd);

	if(vTimeDataEnd.tm_mon < 0) {
		vTimeDataEnd.tm_mon += 12;
		--vTimeDataEnd.tm_year;
	}
	::strftime(date,31,"%b %d, %Y",&vTimeDataEnd);

	s += " and midnight ";
	s += date;

	st[0].wDay = vTimeDataBeg.tm_mday;
	st[0].wMonth = vTimeDataBeg.tm_mon + 1;
	st[0].wYear = vTimeDataBeg.tm_year + 1900;

	st[1].wDay = vTimeDataEnd.tm_mday;
	st[1].wMonth = vTimeDataEnd.tm_mon + 1;
	st[1].wYear = vTimeDataEnd.tm_year + 1900;


	pStatic->SetWindowText(_T(s.c_str()));
	
	pCalendar->SendMessage(MCM_SETCURSEL,0,(LPARAM) &st);
	pCalendar->SendMessage(MCM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM) &st);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.