DateTimeCtrl.cpp
上传用户:lxjxxg
上传日期:2007-01-02
资源大小:42k
文件大小:13k
源码类别:

工具条

开发平台:

Visual C++

  1. // DateTimeCtrl.cpp : implementation file
  2. //
  3. // MFC Wrapper class for the IE3 DateTimePicker control
  4. // Check out http://www.microsoft.com/msdn/sdk/inetsdk/help/itt/CommCtls/DateTime/DateTime.htm#ch_dtp_make
  5. // for details.
  6. //
  7. //    To use in a dialog:
  8. //      Create a custom control with classname "SysDateTimePick32"
  9. //    You will then need to subclass the custom control (in the InitDialog fn). 
  10. //    eg.
  11. //
  12. //      m_DateTime.SubclassDlgItem(IDC_CUSTOM1, this);
  13. //
  14. //  To use if creating with "Create":
  15. //      call "CDateTimeCtrl::Create(dwStyle, rect, pParentWnd, nID)"
  16. // 
  17. //  DateTime styles:
  18. //
  19. //        DTS_UPDOWN           - use UPDOWN instead of MONTHCAL
  20. //        DTS_SHOWNONE         - allow a NONE selection
  21. //        DTS_SHORTDATEFORMAT  - use the short date format (app must forward WM_WININICHANGE messages)
  22. //        DTS_LONGDATEFORMAT   - use the long date format (app must forward WM_WININICHANGE messages)
  23. //        DTS_TIMEFORMAT       - use the time format (app must forward WM_WININICHANGE messages)
  24. //        DTS_APPCANPARSE      - allow user entered strings (app MUST respond to DTN_USERSTRING)
  25. //        DTS_RIGHTALIGN       - right-align popup instead of left-align it
  26. //
  27. //  For the CDateTimeCtrl::SetFormat(LPCTSTR szFmt) specs, see the functions GetDateFormat 
  28. //  and GetTimeFormat for the format of szFmt.
  29. // 
  30. //  For the Set- and Get-Colour functions, use the following for the nColIndex:
  31. // 
  32. //        MCSC_BACKGROUND   0   // the background color (between months)
  33. //        MCSC_TEXT         1   // the dates
  34. //        MCSC_TITLEBK      2   // background of the title
  35. //        MCSC_TITLETEXT    3      // title text
  36. //        MCSC_MONTHBK      4   // background within the month cal
  37. //        MCSC_TRAILINGTEXT 5   // the text color of header & trailing days
  38. //
  39. // Written by Chris Maunder (chrismaunder@codeguru.com)
  40. // Copyright (c) 1998.
  41. //
  42. // Modified 7 Feb 1998 - bug fix in OnChildNotify (Jim Richardson)
  43. //                     - Added COleDateTime support
  44. //
  45. // This code is free. If the source code in this file is used in any 
  46. // commercial application then an email would be nice.
  47. //
  48. // This file is provided "as is" with no expressed or implied warranty.
  49. // The author accepts no liability if it causes any damage to your
  50. // computer, causes your pet cat to fall ill, increases baldness or
  51. // makes you car start emitting strange noises when you start it up.
  52. //
  53. // Expect bugs.
  54. // 
  55. // Please use and enjoy. Please let me know of any bugs/mods/improvements 
  56. // that you have found/implemented and I will fix/incorporate them into this
  57. // file. 
  58. //
  59. /////////////////////////////////////////////////////////////////////////////
  60. #include "stdafx.h"
  61. #include "DateTimeCtrl.h"
  62.     
  63. #ifdef _DEBUG
  64. #define new DEBUG_NEW
  65. #undef THIS_FILE
  66. static char THIS_FILE[] = __FILE__;
  67. #endif
  68. // Thanks to Tim Gilman (tdgilman@best.com) for this.
  69. void AFXAPI DDX_DateTime(CDataExchange *pDX, int nIDC, SYSTEMTIME &SysTime)
  70. {
  71.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  72.     ASSERT (hWndCtrl != NULL);
  73.     if (pDX->m_bSaveAndValidate)
  74.     {
  75.         ::SendMessage(hWndCtrl, DTM_GETSYSTEMTIME, 0, (LPARAM)&SysTime);
  76.     }
  77.     else // initializing
  78.     {
  79.         ::SendMessage(hWndCtrl, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&SysTime);
  80.     }
  81. }
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CDateTimeCtrl
  84. BOOL CDateTimeCtrl::nCommonControlsInitialised = FALSE;
  85. CDateTimeCtrl::CDateTimeCtrl()
  86. {
  87.     if (!nCommonControlsInitialised)
  88.     {
  89.         INITCOMMONCONTROLSEX icex;
  90.         icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  91.         icex.dwICC = ICC_DATE_CLASSES;
  92.         ::InitCommonControlsEx(&icex);
  93.         nCommonControlsInitialised = TRUE;
  94.     }
  95.     m_CurrentTime = COleDateTime::GetCurrentTime();
  96.     m_bDroppedDown = FALSE;
  97.     m_bReportDateChangeWhileDropped = FALSE;
  98. }
  99. CDateTimeCtrl::~CDateTimeCtrl()
  100. {
  101. }
  102. BOOL CDateTimeCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) 
  103. {
  104.     return CWnd::Create(DATETIMEPICK_CLASS, _T(""), dwStyle, rect, pParentWnd, nID);
  105. }
  106. BEGIN_MESSAGE_MAP(CDateTimeCtrl, CWnd)
  107.     //{{AFX_MSG_MAP(CDateTimeCtrl)
  108.     //}}AFX_MSG_MAP
  109.     ON_NOTIFY_REFLECT_EX(DTN_DATETIMECHANGE, OnDateTimeChangeNotify)
  110.     ON_NOTIFY_REFLECT_EX(DTN_DROPDOWN,       OnDropDown)
  111.     ON_NOTIFY_REFLECT_EX(DTN_CLOSEUP,        OnCloseUp)
  112.     ON_NOTIFY_REFLECT_EX(DTN_FORMAT,         OnFormat)
  113.     ON_NOTIFY_REFLECT_EX(DTN_FORMATQUERY,    OnFormatQuery)
  114.     ON_NOTIFY_REFLECT_EX(DTN_USERSTRING,     OnUserString)
  115.     ON_NOTIFY_REFLECT_EX(DTN_WMKEYDOWN,      OnKeyDown)
  116. END_MESSAGE_MAP()
  117. /////////////////////////////////////////////////////////////////////////////
  118. // CDateTimeCtrl (public) operations
  119. CTime CDateTimeCtrl::GetDateTime() 
  120. {
  121.     SYSTEMTIME SysTime;
  122.     SysTimeFromCOleDateTime(m_CurrentTime, &SysTime);
  123.     return CTime(SysTime); 
  124. }
  125. COleDateTime CDateTimeCtrl::GetOleDateTime() 
  126. {
  127.     return m_CurrentTime; 
  128. }
  129. BOOL CDateTimeCtrl::SetDateTime(const CTime& time)
  130. {
  131.     SYSTEMTIME SysTime;
  132.     SysTimeFromCTime(time, &SysTime);
  133.     m_CurrentTime = SysTime;
  134.     return SetSystemTime(SysTime);
  135. }
  136. BOOL CDateTimeCtrl::SetDateTime(const COleDateTime& time)
  137. {
  138.     m_CurrentTime = time;
  139.     return SetSystemTime(time);
  140. }
  141. /////////////////////////////////////////////////////////////////////////////
  142. // CDateTimeCtrl overridable
  143. void CDateTimeCtrl::DoDateTimeChange()
  144. {
  145.     TRACE0("In OnDateTimeChangen");
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // CDateTimeCtrl (protected) implementation
  149. COleDateTime CDateTimeCtrl::GetSystemTime()
  150. {    
  151.     SYSTEMTIME SysTime;
  152.     if (DateTime_GetSystemtime(m_hWnd, &SysTime) == GDT_VALID)
  153.         return COleDateTime(SysTime);
  154.     else
  155.         return COleDateTime::GetCurrentTime();
  156. }
  157. void CDateTimeCtrl::SysTimeFromCOleDateTime(const COleDateTime& time, SYSTEMTIME *SysTime)
  158. {
  159.     SysTime->wYear   = (WORD) time.GetYear();
  160.     SysTime->wMonth  = (WORD) time.GetMonth();
  161.     SysTime->wDay    = (WORD) time.GetDay();
  162.     SysTime->wHour   = (WORD) time.GetHour();
  163.     SysTime->wMinute = (WORD) time.GetMinute();
  164.     SysTime->wSecond = (WORD) time.GetSecond();
  165.     SysTime->wMilliseconds = 0;
  166. }
  167. void CDateTimeCtrl::SysTimeFromCTime(const CTime& time, SYSTEMTIME *SysTime)
  168. {
  169.     SysTime->wYear   = (WORD) time.GetYear();
  170.     SysTime->wMonth  = (WORD) time.GetMonth();
  171.     SysTime->wDay    = (WORD) time.GetDay();
  172.     SysTime->wHour   = (WORD) time.GetHour();
  173.     SysTime->wMinute = (WORD) time.GetMinute();
  174.     SysTime->wSecond = (WORD) time.GetSecond();
  175.     SysTime->wMilliseconds = 0;
  176. }
  177. BOOL CDateTimeCtrl::SetSystemTime(const SYSTEMTIME& time)
  178. {
  179.     return DateTime_SetSystemtime(m_hWnd, GDT_VALID, &time);
  180. }
  181. BOOL CDateTimeCtrl::SetSystemTime(const CTime& time)
  182. {
  183.     SYSTEMTIME SysTime;
  184.     SysTimeFromCTime(time, &SysTime);
  185.     return DateTime_SetSystemtime(m_hWnd, GDT_VALID, &SysTime);
  186. }
  187. BOOL CDateTimeCtrl::SetSystemTime(const COleDateTime& time)
  188. {
  189.     SYSTEMTIME SysTime;
  190.     SysTimeFromCOleDateTime(time, &SysTime);
  191.     return DateTime_SetSystemtime(m_hWnd, GDT_VALID, &SysTime);
  192. }
  193. // See GetDateFormat and GetTimeFormat for the format of szFmt.
  194. BOOL CDateTimeCtrl::SetFormat(LPCTSTR szFmt)
  195. {
  196.     return DateTime_SetFormat(m_hWnd, szFmt);
  197. }
  198. // Posible values for nColIndex:
  199. //    MCSC_BACKGROUND   0   // the background color (between months)
  200. //    MCSC_TEXT         1   // the dates
  201. //    MCSC_TITLEBK      2   // background of the title
  202. //    MCSC_TITLETEXT    3
  203. //    MCSC_MONTHBK      4   // background within the month cal
  204. //    MCSC_TRAILINGTEXT 5   // the text color of header & trailing days
  205. COLORREF CDateTimeCtrl::SetMonthCalColour(int nColIndex, COLORREF colour)
  206. {
  207.     return DateTime_SetMonthCalColor(m_hWnd, nColIndex, colour);
  208. }
  209. COLORREF CDateTimeCtrl::GetMonthCalColour(int nColIndex)
  210. {
  211.     return DateTime_GetMonthCalColor(m_hWnd, nColIndex);
  212. }
  213. void CDateTimeCtrl::SetMonthCalFont(CFont& font, BOOL bRedraw /*=TRUE*/)
  214. {
  215.     DateTime_SetMonthCalFont(m_hWnd, (HFONT)font, bRedraw);
  216. }
  217. CFont* CDateTimeCtrl::GetMonthCalFont()    
  218. {
  219.     return CFont::FromHandle( (HFONT)DateTime_GetMonthCalFont(m_hWnd) );
  220. }
  221. // Returns TRUE if success for both times, FALSE otherwise
  222. BOOL CDateTimeCtrl::SetRange(CTime* pMinTime, CTime* pMaxTime)
  223. {
  224.     SYSTEMTIME SysTimeRange[2];
  225.     int nWhich = 0;
  226.     if (pMinTime) {
  227.         nWhich |= GDTR_MIN;
  228.         SysTimeFromCTime( *pMinTime, &(SysTimeRange[0]) );
  229.     }
  230.     if (pMaxTime) {
  231.         nWhich |= GDTR_MAX;
  232.         SysTimeFromCTime( *pMaxTime, &(SysTimeRange[1]) );
  233.     }
  234.     return DateTime_SetRange(m_hWnd, nWhich, SysTimeRange);
  235. }
  236. // Returns TRUE if success for both times, FALSE otherwise
  237. BOOL CDateTimeCtrl::SetRange(COleDateTime* pMinTime, COleDateTime* pMaxTime)
  238. {
  239.     SYSTEMTIME SysTimeRange[2];
  240.     int nWhich = 0;
  241.     if (pMinTime) {
  242.         nWhich |= GDTR_MIN;
  243.         SysTimeFromCOleDateTime( *pMinTime, &(SysTimeRange[0]) );
  244.     }
  245.     if (pMaxTime) {
  246.         nWhich |= GDTR_MAX;
  247.         SysTimeFromCOleDateTime( *pMaxTime, &(SysTimeRange[1]) );
  248.     }
  249.     return DateTime_SetRange(m_hWnd, nWhich, SysTimeRange);
  250. }
  251. // returns GDTR_MIN|GDTR_MAX if there is a minimum|maximum limit
  252. DWORD CDateTimeCtrl::GetRange(CTime* pMinTime, CTime* pMaxTime)
  253. {
  254.     SYSTEMTIME SysTimeRange[2];
  255.     DWORD result = DateTime_GetRange(m_hWnd, SysTimeRange);
  256.     *pMinTime = CTime(SysTimeRange[0]);    // systime is 0 if no limit
  257.     *pMaxTime = CTime(SysTimeRange[1]);
  258.     return result;
  259. }
  260. // returns GDTR_MIN|GDTR_MAX if there is a minimum|maximum limit
  261. DWORD CDateTimeCtrl::GetRange(COleDateTime* pMinTime, COleDateTime* pMaxTime)
  262. {
  263.     SYSTEMTIME SysTimeRange[2];
  264.     DWORD result = DateTime_GetRange(m_hWnd, SysTimeRange);
  265.     *pMinTime = COleDateTime(SysTimeRange[0]);    // systime is 0 if no limit
  266.     *pMaxTime = COleDateTime(SysTimeRange[1]);
  267.     return result;
  268. }
  269. /////////////////////////////////////////////////////////////////////////////
  270. // CDateTimeCtrl notification handlers
  271. BOOL CDateTimeCtrl::OnDropDown(NMHDR* /*pNotifyStruct*/, LRESULT* /*result*/)
  272. {
  273.     m_bDroppedDown = TRUE;
  274.     return FALSE;    // Let parent handle message
  275. }
  276. BOOL CDateTimeCtrl::OnCloseUp(NMHDR* /*pNotifyStruct*/, LRESULT* /*result*/)
  277. {
  278.     m_bDroppedDown = FALSE;
  279.     if (!m_bReportDateChangeWhileDropped)
  280.     {
  281.         NMDATETIMECHANGE dtmh;
  282.         dtmh.nmhdr.hwndFrom = GetSafeHwnd(); 
  283.         dtmh.nmhdr.idFrom = GetDlgCtrlID(); 
  284.         dtmh.nmhdr.code = DTN_DATETIMECHANGE; 
  285.         dtmh.dwFlags = DateTime_GetSystemtime(GetSafeHwnd(), &(dtmh.st));
  286.         CWnd* pOwner = GetOwner();
  287.         if (pOwner && IsWindow(pOwner->m_hWnd) && GetSystemTime() != m_CurrentTime)
  288.             pOwner->SendMessage(WM_NOTIFY, (WPARAM) GetDlgCtrlID(), (LPARAM) &dtmh);
  289.     }
  290.     return FALSE;    // Let parent handle message
  291. }
  292. // This traps the DTN_DATETIMECHANGE notification and checks that
  293. // the date/time has actually changed. If it has, then the message
  294. // is passed on to the parent as normal, otherwise it is blocked.
  295. BOOL CDateTimeCtrl::OnDateTimeChangeNotify(NMDATETIMECHANGE *dtmh, LRESULT* pResult)
  296. {
  297.     *pResult = 0;    // docs say we must return 0
  298.     if (!m_bReportDateChangeWhileDropped && m_bDroppedDown)
  299.         return TRUE;
  300.     // Check box notification sent here.
  301.     if (dtmh->dwFlags == GDT_NONE)
  302.         TRACE0("control Disabledn");
  303.     else
  304.         TRACE0("control Activen");
  305.     // Has the date changed?
  306.     BOOL bDateChanged = FALSE;
  307.     if (dtmh->dwFlags == GDT_VALID)
  308.     {
  309.         COleDateTime time = GetSystemTime();
  310.         if (time != m_CurrentTime)
  311.         {
  312.             m_CurrentTime = time;
  313.             bDateChanged = TRUE;
  314.             DoDateTimeChange();
  315.         }
  316.     }
  317.     BOOL bUpDownStyle = ((GetStyle() & DTS_UPDOWN) == DTS_UPDOWN);
  318.     if (bUpDownStyle) return FALSE;    // Let parent handle message
  319.     // If the control is NOT a DTS_UPDOWN style (ie it has a drop down)
  320.     // then we need to catch multiple notifications of date changes
  321.     // (this can cause infinite loops). 
  322.     if (m_bDroppedDown)
  323.     {
  324.         if (bDateChanged)
  325.             return TRUE;    // Don't let the parent see the message if not dropped down
  326.         else 
  327.             return FALSE;    // Let parent see message, since date hasn't changed
  328.     }
  329.     else
  330.         return FALSE;        // Let parent handle message
  331. }
  332. BOOL CDateTimeCtrl::OnFormat(NMDATETIMEFORMAT* /*lpNMFormat*/, LRESULT* pResult)
  333. {
  334.     *pResult = 0;    // docs say we must return 0
  335.     return FALSE;    // Let parent handle message
  336. }
  337. BOOL CDateTimeCtrl::OnFormatQuery(NMDATETIMEFORMATQUERY* lpDTFormatQuery, LRESULT* pResult)
  338. {
  339.     *pResult = 0;    // docs say we must return 0
  340.     lpDTFormatQuery->szMax = CSize(366,16);    // Must calculate Max time string size
  341.     return FALSE;    // Let parent handle message
  342. }
  343. BOOL CDateTimeCtrl::OnUserString(NMDATETIMESTRING* /*lpDTstring*/, LRESULT* pResult)
  344. {
  345.     *pResult = 0;    // docs say we must return 0
  346.     return FALSE;    // Let parent handle message
  347. }
  348. BOOL CDateTimeCtrl::OnKeyDown(NMDATETIMEWMKEYDOWN* /*lpDTKeystroke*/, LRESULT* pResult)
  349. {
  350.     *pResult = 0;    // docs say we must return 0
  351.     return FALSE;    // Let parent handle message
  352. }