![]() |
Serialize CDateTimeCtrl state impossible? |
Post Reply ![]() |
Author | |
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() Posted: 15 April 2009 at 4:03am |
If you create a CDateTimeCtrl with the DTS_SHOWNONE style, the control will have a checkbox where you can choose "no time". This check can be checked using SetTime(&stValidTime) and unchecked with SetTime(NULL). When you click it manually, the time value is not changed even though the check is not toggled. When doing this programmatically with SetTime() the time is reset (NULL = no time).This yields a problem when serializing the state of the control from a given source (like the Registry).
Q: How do you set a valid time AND uncheck the control programmatically?
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
ABuenger ![]() Newbie ![]() ![]() Joined: 02 February 2006 Status: Offline Points: 1075 |
![]() ![]() ![]() ![]() ![]() |
Haven't used CDateTimeCtrl before, but why aren't you using the XTP control?
(If they don't have a drop in replacement put it on the wish list) |
|
Codejock support
|
|
![]() |
|
Oleg ![]() Admin Group ![]() Joined: 21 May 2003 Location: United States Status: Offline Points: 11234 |
![]() ![]() ![]() ![]() ![]() |
Hello,
Yes, I saw same issue, but seems CDateTimeCtrl doesn't have method to make this :(
|
|
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS |
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
I believe it can be done by simulating a click...
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
There must be a way! This is so annoying... No ideas?
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
![]() CDateTimeCtrl m_DateTimeCtrl;
CRect rect(20, 20, 250, 45);
m_DateTimeCtrl.Create(WS_VISIBLE | WS_CHILD | WS_TABSTOP | DTS_SHOWNONE | DTS_SHORTDATEFORMAT, rect, this, 1005); m_DateTimeCtrl.SetFormat(_T("ddd, MMM d, yyyy - HH:mm:ss")); //Now uncheck it - I always use such thing for datetime fields where app ALLOWS user to keep it not filled
//and if it unchecked - ignore it for store
::SendMessage(m_DateTimeCtrl.GetSafeHwnd(), (UINT) DTM_SETSYSTEMTIME, (WPARAM) (DWORD) GDT_NONE, (LPARAM) NULL);
|
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
Thanks for your reply.
Now, try this:
1) Date should equal 17 january 1982 (not today's date, that is).
2) Checkbox should be unchecked.
This state is possible to achieve when the user clicks the control, but (afaik) impossible to accomplish programmatically.
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
![]() |
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
I'm impressed!
Thanks a lot! :)
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
As you know CDateTimeCtrl not allow to retrieve datetime value (visible on display) if unchecked.
This is simple code to programmatically change mode without user click - after you can get value - and uncheck CDateTimeCtrl control back.
LPARAM lparam = MAKELPARAM(10, 15);
m_DateTimeCtrl.SendMessage(WM_LBUTTONDOWN, NULL, lparam);
//Of course 10 (y) and 15 (x) is coordinates for standard case - normal font. Need to adjust for some custom setup like large font
|
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
Yeah, but in your previous post, you used GDT_NONE instead of simulating a click?
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
This is not about GDT_NONE - it's about opposite - how to porgrammatically set to VALID state and get internal Value - like GetTime
|
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
No, this can't be done!
The problem lies in CDateTimeCtrl::GetTime(). When the control is unchecked, the time cannot be read! This means the time cannot be stored, hence not serialized (yes, deserialization is possible). You would have to capture all date changes and store the date on your own...
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
Control will not answer you on your call but still keep previously set value on it's display. I demonstarted how to get it back!
|
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
Sorry, missed that post. But still, the solution is quite ugly (not to mention that the coordinate of the checkbox cannot be safely determined).
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
If somebody ask a question: "How do you set a valid time AND uncheck the control programmatically?" and recive positive answer - last he can do in his comment - use term ugly or talk about safe way!?
|
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
Sorry, didn't mean it that way :(
The problem is not your solution. The problem is that Microsoft implemented the control this way.
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
OK.
This is a simple way to bypass "the coordinate of the checkbox cannot be safely determined"
for (int i = 0; i < 30; i++)
{ //LPARAM lparam = MAKELPARAM(10, 15);LPARAM lparam = MAKELPARAM(i, 15); m_DateTimeCtrl.SendMessage(WM_LBUTTONDOWN, NULL, lparam); COleDateTime dt; m_DateTimeCtrl.GetTime(dt); if (dt.GetStatus() == COleDateTime::valid){ CString s; s.Format(_T( "Valid with i =%d"), i);AfxMessageBox(s); break;} } i = 0 - bad, 1 - good |
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
Thanks for your hints.
Though, I believe this is the best solution:
BOOL CDateTimeCtrlEx::OnDateTimeChanged(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMECHANGE pDTChange = reinterpret_cast<LPNMDATETIMECHANGE>(pNMHDR);
m_lastDate = pDTChange->st;
*pResult = 0; return FALSE; // Let the parent handle the message as well!
}
"m_lastDate" will always contain the latest selection, no matter if the checkbox was checked or not. Though, just in case, I only use this variable if GetTime() fails (which it does when unchecked). One must also be careful with calls to SetTime() since it cannot be overloaded. |
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
No - this is not true - in the moment user uncheck control - m_lastDate will have invalid data. Proper syntax for notification - void - you can use *pResult to pass TRUE or FALSE)
|
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
Disagree.
If you use ON_NOTIFY_REFLECT_EX() in your message map, your message handler may or may not allow the parent window to handle the message. If the handler returns FALSE, the message will be handled by the parent as well, while a call that returns TRUE does not allow the parent to handle it.
And
If you want more than one object in the notification routing to handle a message, you can use ON_NOTIFY_EX (or ON_NOTIFY_EX_RANGE) rather than ON_NOTIFY (or ON_NOTIFY_RANGE).
If the user unchecks the control, m_lastDate is assigned a valid date. Just verified this.
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson ![]() Senior Member ![]() ![]() Joined: 17 November 2008 Status: Offline Points: 1705 |
![]() ![]() ![]() ![]() ![]() |
Sure I did before posting:
void CMFC_DATEDlg::OnDateTimeChanged(NMHDR *pNMHDR, LRESULT *pResult){LPNMDATETIMECHANGE pDTChange = reinterpret_cast<LPNMDATETIMECHANGE>(pNMHDR);m_lastDate = pDTChange->st; SetWindowText(m_lastDate.Format()); *pResult = 0; }![]() |
|
![]() |
|
znakeeye ![]() Senior Member ![]() ![]() Joined: 26 July 2006 Status: Offline Points: 1672 |
![]() ![]() ![]() ![]() ![]() |
Strange. Anyway, you don't have to assign it if it is invalid.
if ((pDTChange->dwFlags == GDT_VALID)
m_lastDate = pDTChange->st;
Strange indeed, since my date value is not changed when debugging during "unchecking"...
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
Post Reply ![]() |
|
Tweet
|
Forum Jump | Forum Permissions ![]() You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum |