![]() |
Serialize CDateTimeCtrl state impossible? |
Post Reply
|
| Author | |
znakeeye
Senior Member
Joined: 26 July 2006 Status: Offline Points: 1672 |
Post Options
Thanks(0)
Quote Reply
Topic: Serialize CDateTimeCtrl state impossible?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 |
Post Options
Thanks(0)
Quote Reply
Posted: 15 April 2009 at 6:25am |
|
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
Senior Member
Joined: 21 May 2003 Location: United States Status: Offline Points: 11234 |
Post Options
Thanks(0)
Quote Reply
Posted: 15 April 2009 at 8:25am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 15 April 2009 at 4:25pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 01 July 2009 at 3:34am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 01 July 2009 at 11:41pm |
![]() 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 |
Post Options
Thanks(0)
Quote Reply
Posted: 04 July 2009 at 7:25pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 04 July 2009 at 7:40pm |
|
|
![]() |
|
znakeeye
Senior Member
Joined: 26 July 2006 Status: Offline Points: 1672 |
Post Options
Thanks(0)
Quote Reply
Posted: 05 July 2009 at 6:26am |
|
I'm impressed!
Thanks a lot! :)
|
|
|
PokerMemento - http://www.pokermemento.com/
|
|
![]() |
|
mdoubson
Senior Member
Joined: 17 November 2008 Status: Offline Points: 1705 |
Post Options
Thanks(0)
Quote Reply
Posted: 06 July 2009 at 10:42am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 07 July 2009 at 3:06am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 07 July 2009 at 7:56am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 22 July 2009 at 4:40pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 22 July 2009 at 4:45pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 22 July 2009 at 4:45pm |
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 23 July 2009 at 3:54pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 23 July 2009 at 11:04pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 24 July 2009 at 1:29am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 25 July 2009 at 2:38am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 26 July 2009 at 3:07am |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 03 August 2009 at 2:37pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 03 August 2009 at 2:54pm |
|
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 |
Post Options
Thanks(0)
Quote Reply
Posted: 04 August 2009 at 3:01am |
|
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 |