home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / winctrl5.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  23KB  |  920 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CORE5_SEG
  14. #pragma code_seg(AFX_CORE5_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CDateTimeCtrl
  26.  
  27. BOOL CDateTimeCtrl::Create(DWORD dwStyle, const RECT& rect,
  28.     CWnd* pParentWnd, UINT nID)
  29. {
  30.    // initialize common controls
  31.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_DATE_REG));
  32.  
  33.     CWnd* pWnd = this;
  34.     return pWnd->Create(DATETIMEPICK_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  35. }
  36.  
  37. DWORD CDateTimeCtrl::GetRange(CTime* pMinTime, CTime* pMaxTime) const
  38. {
  39.     ASSERT(::IsWindow(m_hWnd));
  40.     SYSTEMTIME sysTimes[2];
  41.     memset(sysTimes, 0, sizeof(sysTimes));
  42.  
  43.     DWORD dwResult = ::SendMessage(m_hWnd, DTM_GETRANGE, 0, (LPARAM) &sysTimes);
  44.  
  45.     if (pMinTime != NULL)
  46.     {
  47.         if (dwResult & GDTR_MIN)
  48.             *pMinTime = CTime(sysTimes[0]);
  49.     }
  50.  
  51.     if (pMaxTime != NULL)
  52.     {
  53.         if (dwResult & GDTR_MAX)
  54.             *pMaxTime = CTime(sysTimes[1]);
  55.     }
  56.  
  57.     return dwResult;
  58.  
  59. }
  60.  
  61. DWORD CDateTimeCtrl::GetRange(COleDateTime* pMinTime,
  62.     COleDateTime* pMaxTime) const
  63. {
  64.     ASSERT(::IsWindow(m_hWnd));
  65.  
  66.     SYSTEMTIME sysTimes[2];
  67.     memset(sysTimes, 0, sizeof(sysTimes));
  68.  
  69.     DWORD dwResult = ::SendMessage(m_hWnd, DTM_GETRANGE, 0, (LPARAM) &sysTimes);
  70.     if (pMinTime != NULL)
  71.     {
  72.         if (dwResult & GDTR_MIN)
  73.             *pMinTime = COleDateTime(sysTimes[0]);
  74.         else
  75.             pMinTime->SetStatus(COleDateTime::null);
  76.     }
  77.  
  78.     if (pMaxTime != NULL)
  79.     {
  80.         if (dwResult & GDTR_MAX)
  81.             *pMaxTime = COleDateTime(sysTimes[1]);
  82.         else
  83.             pMaxTime->SetStatus(COleDateTime::null);
  84.     }
  85.  
  86.     return dwResult;
  87. }
  88.  
  89. BOOL CDateTimeCtrl::SetRange(const CTime* pMinTime, const CTime* pMaxTime)
  90. {
  91.     ASSERT(::IsWindow(m_hWnd));
  92.  
  93.     SYSTEMTIME sysTimes[2];
  94.  
  95.     WPARAM wFlags = 0;
  96.     if (pMinTime != NULL && pMinTime->GetAsSystemTime(sysTimes[0]))
  97.         wFlags |= GDTR_MIN;
  98.  
  99.     if (pMaxTime != NULL && pMaxTime->GetAsSystemTime(sysTimes[1]))
  100.         wFlags |= GDTR_MAX;
  101.  
  102.     return (BOOL) ::SendMessage(m_hWnd, DTM_SETRANGE, wFlags, (LPARAM) &sysTimes);
  103. }
  104.  
  105. BOOL CDateTimeCtrl::SetRange(const COleDateTime* pMinTime, const COleDateTime* pMaxTime)
  106. {
  107.     ASSERT(::IsWindow(m_hWnd));
  108.     ASSERT(pMinTime == NULL || pMinTime->GetStatus() != COleDateTime::invalid);
  109.     ASSERT(pMaxTime == NULL || pMaxTime->GetStatus() != COleDateTime::invalid);
  110.  
  111.     SYSTEMTIME sysTime[2];
  112.  
  113.     WPARAM wFlags = 0;
  114.     if (pMinTime != NULL && pMinTime->GetStatus() != COleDateTime::null)
  115.     {
  116.         if (pMinTime->GetAsSystemTime(sysTime[0]))
  117.             wFlags |= GDTR_MIN;
  118.     }
  119.  
  120.     if (pMaxTime != NULL && pMaxTime->GetStatus() != COleDateTime::null)
  121.     {
  122.         if (pMaxTime->GetAsSystemTime(sysTime[1]))
  123.             wFlags |= GDTR_MAX;
  124.     }
  125.  
  126.     return (BOOL) ::SendMessage(m_hWnd, DTM_SETRANGE, wFlags, (LPARAM) &sysTime);
  127. }
  128.  
  129. BOOL CDateTimeCtrl::SetTime(LPSYSTEMTIME pTimeNew /* = NULL */)
  130. {
  131.     ASSERT(::IsWindow(m_hWnd));
  132.     WPARAM wParam = (pTimeNew == NULL) ? GDT_NONE : GDT_VALID;
  133.     return (BOOL) ::SendMessage(m_hWnd, DTM_SETSYSTEMTIME,
  134.         wParam, (LPARAM) pTimeNew);
  135. }
  136.  
  137. BOOL CDateTimeCtrl::SetTime(const COleDateTime& timeNew)
  138. {
  139.     BOOL bRetVal = FALSE;
  140.  
  141.     // make sure the time isn't invalid
  142.     ASSERT(timeNew.GetStatus() != COleDateTime::invalid);
  143.     ASSERT(::IsWindow(m_hWnd));
  144.  
  145.     SYSTEMTIME sysTime;
  146.     WPARAM wParam = GDT_NONE;
  147.     if (timeNew.GetStatus() == COleDateTime::valid &&
  148.         timeNew.GetAsSystemTime(sysTime))
  149.     {
  150.         wParam = GDT_VALID;
  151.     }
  152.  
  153.     bRetVal = (BOOL) ::SendMessage(m_hWnd,
  154.             DTM_SETSYSTEMTIME, wParam, (LPARAM) &sysTime);
  155.  
  156.     return bRetVal;
  157. }
  158.  
  159. BOOL CDateTimeCtrl::SetTime(const CTime* pTimeNew)
  160. {
  161.     BOOL bRetVal = FALSE;
  162.  
  163.     // make sure the time isn't invalid
  164.     ASSERT(::IsWindow(m_hWnd));
  165.  
  166.     SYSTEMTIME sysTime;
  167.     WPARAM wParam = GDT_NONE;
  168.     if (pTimeNew != NULL && pTimeNew->GetAsSystemTime(sysTime))
  169.     {
  170.         wParam = GDT_VALID;
  171.     }
  172.  
  173.     bRetVal = (BOOL) ::SendMessage(m_hWnd,
  174.             DTM_SETSYSTEMTIME, wParam, (LPARAM) &sysTime);
  175.  
  176.     return bRetVal;
  177. }
  178.  
  179. BOOL CDateTimeCtrl::GetTime(COleDateTime& timeDest) const
  180. {
  181.     SYSTEMTIME sysTime;
  182.     BOOL bRetVal = TRUE;
  183.  
  184.     LRESULT result = ::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM) &sysTime);
  185.     if (result == GDT_VALID)
  186.     {
  187.         timeDest = COleDateTime(sysTime);
  188.         bRetVal = TRUE;
  189.         ASSERT(timeDest.GetStatus() == COleDateTime::valid);
  190.     }
  191.     else if (result == GDT_NONE)
  192.     {
  193.         timeDest.SetStatus(COleDateTime::null);
  194.         bRetVal = TRUE;
  195.     }
  196.     else
  197.         timeDest.SetStatus(COleDateTime::invalid);
  198.     return bRetVal;
  199. }
  200.  
  201. DWORD CDateTimeCtrl::GetTime(CTime& timeDest) const
  202. {
  203.     SYSTEMTIME sysTime;
  204.     DWORD dwResult = (DWORD)
  205.         ::SendMessage(m_hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM) &sysTime);
  206.  
  207.     if (dwResult == GDT_VALID)
  208.         timeDest = CTime(sysTime);
  209.  
  210.     return dwResult;
  211. }
  212.  
  213. CDateTimeCtrl::~CDateTimeCtrl()
  214. {
  215.     DestroyWindow();
  216. }
  217.  
  218. /////////////////////////////////////////////////////////////////////////////
  219. // CMonthCalCtrl
  220.  
  221. BOOL CMonthCalCtrl::Create(DWORD dwStyle, const RECT& rect,
  222.     CWnd* pParentWnd, UINT nID)
  223. {
  224.     // initialize common controls
  225.     VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTL_DATE_REG));
  226.  
  227.     CWnd* pWnd = this;
  228.     return pWnd->Create(MONTHCAL_CLASS, NULL, dwStyle, rect, pParentWnd, nID);
  229. }
  230.  
  231. BOOL CMonthCalCtrl::Create(DWORD dwStyle, const POINT& pt,
  232.     CWnd* pParentWnd, UINT nID)
  233. {
  234.     BOOL bWasVisible = (dwStyle & WS_VISIBLE);
  235.     dwStyle &= ~WS_VISIBLE;
  236.  
  237.     CRect rect(pt.x, pt.y, 0, 0);
  238.  
  239.     BOOL bRetVal = FALSE;
  240.    if (Create(dwStyle, rect, pParentWnd, nID))
  241.     {
  242.         if (SizeMinReq())
  243.         {
  244.             if (bWasVisible)
  245.                 ShowWindow(SW_SHOWNA);
  246.             bRetVal = TRUE;
  247.         }
  248.         else
  249.             DestroyWindow();
  250.     }
  251.  
  252.     return bRetVal;
  253. }
  254.  
  255. BOOL CMonthCalCtrl::SizeMinReq(BOOL bRepaint /* = TRUE */)
  256. {
  257.     CRect rect;
  258.     BOOL bRetVal = FALSE;
  259.     if (GetMinReqRect(rect))
  260.     {
  261.         DWORD dwFlags = SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOMOVE | SWP_NOACTIVATE;
  262.         if (!bRepaint)
  263.             dwFlags |= SWP_NOREDRAW;
  264.         SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), dwFlags);
  265.         bRetVal = TRUE;
  266.     }
  267.  
  268.     return bRetVal;
  269. }
  270.  
  271. void CMonthCalCtrl::SetToday(const COleDateTime& refTime)
  272. {
  273.     ASSERT_VALID(this);
  274.  
  275.     // make sure the time isn't invalid
  276.     ASSERT(refTime.GetStatus() != COleDateTime::invalid);
  277.     ASSERT(::IsWindow(m_hWnd));
  278.  
  279.     SYSTEMTIME sysTime;
  280.     LPSYSTEMTIME pSysTime = NULL;
  281.     WPARAM wParam = GDT_NONE;
  282.  
  283.     // if the passed time is null or out of range,
  284.     // we'll set the control to NULL
  285.  
  286.     if (refTime.GetAsSystemTime(sysTime))
  287.     {
  288.         pSysTime = &sysTime;
  289.         wParam = GDT_VALID;
  290.     }
  291.  
  292.     if (::IsWindow(m_hWnd))
  293.         ::SendMessage(m_hWnd, MCM_SETTODAY, wParam, (LPARAM) pSysTime);
  294. }
  295.  
  296. void CMonthCalCtrl::SetToday(const CTime* pDateTime)
  297. {
  298.     ASSERT(::IsWindow(m_hWnd));
  299.     ASSERT_VALID(this);
  300.  
  301.     // if the passed time is NULL, we'll set the
  302.     // control to NULL
  303.  
  304.     WPARAM wParam = GDT_NONE;
  305.     LPSYSTEMTIME pSysTime = NULL;
  306.     SYSTEMTIME sysTime;
  307.  
  308.     if (pDateTime != NULL && pDateTime->GetAsSystemTime(sysTime))
  309.     {
  310.         wParam = GDT_VALID;
  311.         pSysTime = &sysTime;
  312.     }
  313.  
  314.     if (::IsWindow(m_hWnd))
  315.         ::SendMessage(m_hWnd, MCM_SETTODAY, wParam, (LPARAM) pSysTime);
  316. }
  317.  
  318. BOOL CMonthCalCtrl::SetCurSel(const COleDateTime& refTime)
  319. {
  320.     ASSERT(::IsWindow(m_hWnd));
  321.  
  322.     SYSTEMTIME sysTime;
  323.     BOOL bRetVal = FALSE;
  324.  
  325.     // if the passed time is null or out of range,
  326.     // we'll set the control to NULL
  327.  
  328.     if (refTime.GetAsSystemTime(sysTime) &&
  329.         refTime.GetStatus() == COleDateTime::valid)
  330.     {
  331.         bRetVal = (BOOL)
  332.             ::SendMessage(m_hWnd, MCM_SETCURSEL, 0, (LPARAM) &sysTime);
  333.     }
  334.  
  335.     return bRetVal;
  336. }
  337.  
  338. BOOL CMonthCalCtrl::SetCurSel(const CTime& refTime)
  339. {
  340.     ASSERT(::IsWindow(m_hWnd));
  341.  
  342.     SYSTEMTIME sysTime;
  343.     BOOL bRetVal = FALSE;
  344.  
  345.     if (refTime.GetAsSystemTime(sysTime))
  346.     {
  347.         bRetVal = (BOOL)
  348.             ::SendMessage(m_hWnd, MCM_SETCURSEL, 0, (LPARAM) &sysTime);
  349.     }
  350.  
  351.     return bRetVal;
  352. }
  353.  
  354. BOOL CMonthCalCtrl::GetCurSel(COleDateTime& refTime) const
  355. {
  356.     ASSERT(::IsWindow(m_hWnd));
  357.  
  358.     // can't use this method on multiple selection controls
  359.     ASSERT(!(GetStyle() & MCS_MULTISELECT));
  360.  
  361.     SYSTEMTIME sysTime;
  362.     BOOL bResult = (BOOL)
  363.         ::SendMessage(m_hWnd, MCM_GETCURSEL, 0, (LPARAM) &sysTime);
  364.  
  365.     if (bResult)
  366.         refTime = COleDateTime(sysTime);
  367.  
  368.     return bResult;
  369. }
  370.  
  371. BOOL CMonthCalCtrl::GetToday(COleDateTime& refTime) const
  372. {
  373.     ASSERT(::IsWindow(m_hWnd));
  374.  
  375.     // can't use this method on multiple selection controls
  376.     ASSERT(!(GetStyle() & MCS_MULTISELECT));
  377.  
  378.     SYSTEMTIME sysTime;
  379.     BOOL bResult = (BOOL)
  380.         ::SendMessage(m_hWnd, MCM_GETTODAY, 0, (LPARAM) &sysTime);
  381.  
  382.     if (bResult)
  383.         refTime = COleDateTime(sysTime);
  384.  
  385.     return bResult;
  386. }
  387.  
  388. BOOL CMonthCalCtrl::GetCurSel(CTime& refTime) const
  389. {
  390.     ASSERT(::IsWindow(m_hWnd));
  391.  
  392.     // can't use this method on multiple selection controls
  393.     ASSERT(!(GetStyle() & MCS_MULTISELECT));
  394.  
  395.     SYSTEMTIME sysTime;
  396.     BOOL bResult = (BOOL)
  397.         ::SendMessage(m_hWnd, MCM_GETCURSEL, 0, (LPARAM) &sysTime);
  398.  
  399.     if (bResult)
  400.         refTime = CTime(sysTime);
  401.  
  402.     return bResult;
  403. }
  404.  
  405. BOOL CMonthCalCtrl::GetToday(CTime& refTime) const
  406. {
  407.     ASSERT(::IsWindow(m_hWnd));
  408.  
  409.     // can't use this method on multiple selection controls
  410.     ASSERT(!(GetStyle() & MCS_MULTISELECT));
  411.  
  412.     SYSTEMTIME sysTime;
  413.     BOOL bResult = (BOOL)
  414.         ::SendMessage(m_hWnd, MCM_GETTODAY, 0, (LPARAM) &sysTime);
  415.  
  416.     if (bResult)
  417.         refTime = CTime(sysTime);
  418.  
  419.     return bResult;
  420. }
  421.  
  422. CMonthCalCtrl::~CMonthCalCtrl()
  423. {
  424.     DestroyWindow();
  425. }
  426.  
  427. int CMonthCalCtrl::GetFirstDayOfWeek(BOOL* pbLocal /* = NULL */) const
  428. {
  429.     ASSERT(::IsWindow(m_hWnd));
  430.     DWORD dwResult;
  431.     dwResult = (DWORD) ::SendMessage(m_hWnd, MCM_GETFIRSTDAYOFWEEK, 0, 0);
  432.  
  433.     // set *pbLocal to reflect if the first day of week
  434.     // matches current locale setting
  435.  
  436.     if (pbLocal)
  437.         *pbLocal = HIWORD(dwResult);
  438.     return LOWORD(dwResult);
  439. }
  440.  
  441. BOOL CMonthCalCtrl::SetFirstDayOfWeek(int iDay, int* lpnOld /* = NULL */)
  442. {
  443.     ASSERT(::IsWindow(m_hWnd));
  444.     DWORD dwResult;
  445.     dwResult = (DWORD) ::SendMessage(m_hWnd, MCM_SETFIRSTDAYOFWEEK, 0, (WPARAM) iDay);
  446.  
  447.     if (lpnOld != NULL)
  448.         *lpnOld = LOWORD(dwResult);
  449.  
  450.     return (BOOL) HIWORD(dwResult);
  451. }
  452.  
  453. BOOL CMonthCalCtrl::SetDayState(int nMonths, LPMONTHDAYSTATE pStates)
  454. {
  455.     ASSERT(::IsWindow(m_hWnd));
  456.     ASSERT(AfxIsValidAddress(pStates, nMonths * sizeof(MONTHDAYSTATE), FALSE));
  457.     return (BOOL) ::SendMessage(m_hWnd, MCM_SETDAYSTATE, (WPARAM) nMonths, (LPARAM) pStates);
  458. }
  459.  
  460. BOOL CMonthCalCtrl::SetRange(const COleDateTime* pMinRange,
  461.     const COleDateTime* pMaxRange)
  462. {
  463.     ASSERT(::IsWindow(m_hWnd));
  464.     ASSERT(pMinRange == NULL || pMinRange->GetStatus() != COleDateTime::invalid);
  465.     ASSERT(pMaxRange == NULL || pMaxRange->GetStatus() != COleDateTime::invalid);
  466.  
  467.     SYSTEMTIME sysTimes[2];
  468.     WPARAM wFlags = 0;
  469.  
  470.     if (pMinRange != NULL && pMinRange->GetStatus() != COleDateTime::null)
  471.     {
  472.         if (pMinRange->GetAsSystemTime(sysTimes[0]))
  473.             wFlags |= GDTR_MIN;
  474.     }
  475.  
  476.     if (pMaxRange != NULL && pMaxRange->GetStatus() != COleDateTime::null)
  477.     {
  478.         if (pMaxRange->GetAsSystemTime(sysTimes[1]))
  479.             wFlags |= GDTR_MAX;
  480.     }
  481.  
  482.     return (BOOL)
  483.         ::SendMessage(m_hWnd, MCM_SETRANGE, wFlags, (LPARAM) &sysTimes);
  484. }
  485.  
  486. BOOL CMonthCalCtrl::SetRange(const LPSYSTEMTIME pMinRange,
  487.     const LPSYSTEMTIME pMaxRange)
  488. {
  489.     ASSERT(::IsWindow(m_hWnd));
  490.  
  491.     SYSTEMTIME sysTimes[2];
  492.     WPARAM wFlags = 0;
  493.  
  494.     if (pMinRange != NULL)
  495.     {
  496.         memcpy(&sysTimes[0], pMinRange, sizeof(SYSTEMTIME));
  497.         wFlags |= GDTR_MIN;
  498.     }
  499.  
  500.     if (pMaxRange != NULL)
  501.     {
  502.         memcpy(&sysTimes[1], pMaxRange, sizeof(SYSTEMTIME));
  503.         wFlags |= GDTR_MAX;
  504.     }
  505.  
  506.     return (BOOL)
  507.         ::SendMessage(m_hWnd, MCM_SETRANGE, wFlags, (LPARAM) &sysTimes);
  508. }
  509.  
  510. DWORD CMonthCalCtrl::GetRange(COleDateTime* pMinRange,
  511.     COleDateTime* pMaxRange) const
  512. {
  513.     ASSERT(::IsWindow(m_hWnd));
  514.  
  515.     SYSTEMTIME sysTimes[2];
  516.     memset(sysTimes, 0, sizeof(sysTimes));
  517.  
  518.     DWORD dwRanges = (DWORD)
  519.         ::SendMessage(m_hWnd, MCM_GETRANGE, 0, (LPARAM) &sysTimes);
  520.  
  521.     if (dwRanges & GDTR_MIN && pMinRange)
  522.         *pMinRange = COleDateTime(sysTimes[0]);
  523.  
  524.     if (dwRanges & GDTR_MAX && pMaxRange)
  525.         *pMaxRange = COleDateTime(sysTimes[1]);
  526.  
  527.     return dwRanges;
  528. }
  529.  
  530. DWORD CMonthCalCtrl::GetRange(LPSYSTEMTIME pMinRange,
  531.     LPSYSTEMTIME pMaxRange) const
  532. {
  533.     ASSERT(::IsWindow(m_hWnd));
  534.  
  535.     SYSTEMTIME sysTimes[2];
  536.     memset(sysTimes, 0, sizeof(sysTimes));
  537.  
  538.     DWORD dwRanges = (DWORD)
  539.         ::SendMessage(m_hWnd, MCM_GETRANGE, 0, (LPARAM) &sysTimes);
  540.  
  541.     if (dwRanges & GDTR_MIN && pMinRange)
  542.         memcpy(pMinRange, &sysTimes[0], sizeof(SYSTEMTIME));
  543.  
  544.     if (dwRanges & GDTR_MAX && pMaxRange)
  545.         memcpy(pMaxRange, &sysTimes[1], sizeof(SYSTEMTIME));
  546.  
  547.     return dwRanges;
  548. }
  549.  
  550. BOOL CMonthCalCtrl::SetRange(const CTime* pMinRange, const CTime* pMaxRange)
  551. {
  552.     ASSERT(::IsWindow(m_hWnd));
  553.  
  554.     SYSTEMTIME sysTimes[2];
  555.     WPARAM wFlags = 0;
  556.     if (pMinRange != NULL && pMinRange->GetAsSystemTime(sysTimes[0]))
  557.         wFlags |= GDTR_MIN;
  558.  
  559.     if (pMaxRange != NULL && pMaxRange->GetAsSystemTime(sysTimes[1]))
  560.         wFlags |= GDTR_MAX;
  561.  
  562.     return (BOOL)
  563.         ::SendMessage(m_hWnd, MCM_SETRANGE, wFlags, (LPARAM) &sysTimes);
  564. }
  565.  
  566. DWORD CMonthCalCtrl::GetRange(CTime* pMinRange, CTime* pMaxRange) const
  567. {
  568.     ASSERT(::IsWindow(m_hWnd));
  569.  
  570.     SYSTEMTIME sysTimes[2];
  571.     memset(sysTimes, 0, sizeof(sysTimes));
  572.  
  573.     DWORD dwRanges = (DWORD)
  574.         ::SendMessage(m_hWnd, MCM_GETRANGE, 0, (LPARAM) &sysTimes);
  575.  
  576.     if (dwRanges & GDTR_MIN && pMinRange)
  577.         *pMinRange = CTime(sysTimes[0]);
  578.  
  579.     if (dwRanges & GDTR_MAX && pMaxRange)
  580.         *pMaxRange = CTime(sysTimes[1]);
  581.  
  582.     return dwRanges;
  583. }
  584.  
  585. int CMonthCalCtrl::GetMonthRange(COleDateTime& refMinRange,
  586.     COleDateTime& refMaxRange, DWORD dwFlags) const
  587. {
  588.     ASSERT(::IsWindow(m_hWnd));
  589.     ASSERT(dwFlags == GMR_DAYSTATE || dwFlags == GMR_VISIBLE);
  590.  
  591.     SYSTEMTIME sysTimes[2];
  592.     memset(sysTimes, 0, sizeof(sysTimes));
  593.     int nCount = (int) ::SendMessage(m_hWnd, MCM_GETMONTHRANGE,
  594.         (WPARAM) dwFlags, (LPARAM) &sysTimes);
  595.  
  596.     refMinRange = COleDateTime(sysTimes[0]);
  597.     refMaxRange = COleDateTime(sysTimes[1]);
  598.  
  599.     return nCount;
  600. }
  601.  
  602. int CMonthCalCtrl::GetMonthRange(LPSYSTEMTIME pMinRange,
  603.     LPSYSTEMTIME pMaxRange, DWORD dwFlags) const
  604. {
  605.     ASSERT(::IsWindow(m_hWnd));
  606.     ASSERT_POINTER(pMinRange, SYSTEMTIME);
  607.     ASSERT_POINTER(pMaxRange, SYSTEMTIME);
  608.  
  609.     SYSTEMTIME sysTimes[2];
  610.  
  611.     int nCount = (int) ::SendMessage(m_hWnd, MCM_GETMONTHRANGE,
  612.         (WPARAM) dwFlags, (LPARAM) &sysTimes);
  613.  
  614.     memcpy(pMinRange, &sysTimes[0], sizeof(SYSTEMTIME));
  615.     memcpy(pMaxRange, &sysTimes[1], sizeof(SYSTEMTIME));
  616.  
  617.     return nCount;
  618. }
  619.  
  620. int CMonthCalCtrl::GetMonthRange(CTime& refMinRange, CTime& refMaxRange,
  621.     DWORD dwFlags) const
  622. {
  623.     ASSERT(::IsWindow(m_hWnd));
  624.     ASSERT(dwFlags == GMR_DAYSTATE || dwFlags == GMR_VISIBLE);
  625.  
  626.     SYSTEMTIME sysTimes[2];
  627.     memset(sysTimes, 0, sizeof(sysTimes));
  628.     int nCount = (int) ::SendMessage(m_hWnd, MCM_GETMONTHRANGE,
  629.         (WPARAM) dwFlags,   (LPARAM) &sysTimes);
  630.  
  631.     refMinRange = CTime(sysTimes[0]);
  632.     refMaxRange = CTime(sysTimes[1]);
  633.  
  634.     return nCount;
  635. }
  636.  
  637. BOOL CMonthCalCtrl::GetSelRange(LPSYSTEMTIME pMinRange,
  638.     LPSYSTEMTIME pMaxRange) const
  639. {
  640.     ASSERT(m_hWnd != NULL);
  641.     ASSERT((GetStyle() & MCS_MULTISELECT));
  642.  
  643.     ASSERT_POINTER(pMinRange, SYSTEMTIME);
  644.     ASSERT_POINTER(pMaxRange, SYSTEMTIME);
  645.  
  646.     SYSTEMTIME sysTimes[2];
  647.     BOOL bReturn = (BOOL) ::SendMessage(m_hWnd, MCM_GETSELRANGE,
  648.                                         0, (LPARAM) &sysTimes);
  649.  
  650.     if (bReturn)
  651.     {
  652.         memcpy(pMinRange, &sysTimes[0], sizeof(SYSTEMTIME));
  653.         memcpy(pMaxRange, &sysTimes[1], sizeof(SYSTEMTIME));
  654.     }
  655.  
  656.     return bReturn;
  657. }
  658.  
  659. BOOL CMonthCalCtrl::SetSelRange(const LPSYSTEMTIME pMinRange,
  660.     const LPSYSTEMTIME pMaxRange)
  661. {
  662.     ASSERT(m_hWnd != NULL);
  663.     ASSERT((GetStyle() & MCS_MULTISELECT));
  664.  
  665.     ASSERT_POINTER(pMinRange, SYSTEMTIME);
  666.     ASSERT_POINTER(pMaxRange, SYSTEMTIME);
  667.  
  668.     SYSTEMTIME sysTimes[2];
  669.     memcpy(&sysTimes[0], pMinRange, sizeof(SYSTEMTIME));
  670.     memcpy(&sysTimes[1], pMaxRange, sizeof(SYSTEMTIME));
  671.  
  672.     return (BOOL) ::SendMessage(m_hWnd, MCM_SETSELRANGE,
  673.         0, (LPARAM) &sysTimes);
  674. }
  675.  
  676. BOOL CMonthCalCtrl::SetSelRange(const COleDateTime& refMinRange,
  677.     const COleDateTime& refMaxRange)
  678. {
  679.     // control must have multiple select
  680.     ASSERT((GetStyle() & MCS_MULTISELECT));
  681.     ASSERT(::IsWindow(m_hWnd));
  682.  
  683.     SYSTEMTIME sysTimes[2];
  684.     BOOL bResult = FALSE;
  685.  
  686.     if (refMinRange.GetStatus() == COleDateTime::valid &&
  687.         refMinRange.GetStatus() == COleDateTime::valid)
  688.     {
  689.         if (refMinRange.GetAsSystemTime(sysTimes[0]) &&
  690.             refMaxRange.GetAsSystemTime(sysTimes[1]))
  691.         {
  692.             bResult = (BOOL)
  693.                 ::SendMessage(m_hWnd, MCM_SETSELRANGE, 0, (LPARAM)sysTimes);
  694.         }
  695.     }
  696.  
  697.     return bResult;
  698. }
  699.  
  700. BOOL CMonthCalCtrl::GetSelRange(COleDateTime& refMinRange,
  701.     COleDateTime& refMaxRange) const
  702. {
  703.     // control must have multiple select
  704.     ASSERT((GetStyle() & MCS_MULTISELECT));
  705.     ASSERT(::IsWindow(m_hWnd));
  706.  
  707.     SYSTEMTIME sysTimes[2];
  708.     memset(sysTimes, 0, sizeof(sysTimes));
  709.     BOOL bResult = (BOOL)
  710.         ::SendMessage(m_hWnd, MCM_GETSELRANGE, 0, (LPARAM) &sysTimes);
  711.  
  712.     if (bResult)
  713.     {
  714.         refMinRange = COleDateTime(sysTimes[0]);
  715.         refMaxRange = COleDateTime(sysTimes[1]);
  716.     }
  717.     return bResult;
  718. }
  719.  
  720. BOOL CMonthCalCtrl::SetSelRange(const CTime& refMinRange,
  721.     const CTime& refMaxRange)
  722. {
  723.     // control must have multiple select
  724.     ASSERT((GetStyle() & MCS_MULTISELECT));
  725.     ASSERT(::IsWindow(m_hWnd));
  726.  
  727.     SYSTEMTIME sysTimes[2];
  728.     BOOL bResult = FALSE;
  729.  
  730.     if (refMinRange.GetAsSystemTime(sysTimes[0]) &&
  731.         refMaxRange.GetAsSystemTime(sysTimes[1]))
  732.     {
  733.         bResult = (BOOL)
  734.             ::SendMessage(m_hWnd, MCM_SETSELRANGE, 0, (LPARAM)sysTimes);
  735.     }
  736.  
  737.     return bResult;
  738. }
  739.  
  740. BOOL CMonthCalCtrl::GetSelRange(CTime& refMinRange, CTime& refMaxRange) const
  741. {
  742.     // control must have multiple select
  743.     ASSERT((GetStyle() & MCS_MULTISELECT));
  744.     ASSERT(::IsWindow(m_hWnd));
  745.  
  746.     SYSTEMTIME sysTimes[2];
  747.     memset(sysTimes, 0, sizeof(sysTimes));
  748.     BOOL bResult = (BOOL)
  749.         ::SendMessage(m_hWnd, MCM_GETSELRANGE, 0, (LPARAM) &sysTimes);
  750.  
  751.     if (bResult)
  752.     {
  753.         refMinRange = CTime(sysTimes[0]);
  754.         refMaxRange = CTime(sysTimes[1]);
  755.     }
  756.     return bResult;
  757. }
  758.  
  759. /////////////////////////////////////////////////////////////////////////////
  760. // DDX_ routines
  761.  
  762. void AFXAPI DDX_DateTimeCtrl(CDataExchange* pDX, int nIDC, COleDateTime& value)
  763. {
  764.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  765.     CDateTimeCtrl* pWnd = (CDateTimeCtrl*) CWnd::FromHandle(hWndCtrl);
  766.  
  767.     if (pDX->m_bSaveAndValidate)
  768.         pWnd->GetTime(value);
  769.     else
  770.         pWnd->SetTime(value);
  771. }
  772.  
  773. void AFXAPI DDX_DateTimeCtrl(CDataExchange* pDX, int nIDC, CTime& value)
  774. {
  775.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  776.     CDateTimeCtrl* pWnd = (CDateTimeCtrl*) CWnd::FromHandle(hWndCtrl);
  777.  
  778.     if (pDX->m_bSaveAndValidate)
  779.         pWnd->GetTime(value);
  780.     else
  781.         pWnd->SetTime(&value);
  782. }
  783.  
  784. void AFXAPI DDX_MonthCalCtrl(CDataExchange* pDX, int nIDC,
  785.     COleDateTime& value)
  786. {
  787.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  788.     CMonthCalCtrl* pWnd = (CMonthCalCtrl*) CWnd::FromHandle(hWndCtrl);
  789.  
  790.     if (pDX->m_bSaveAndValidate)
  791.         pWnd->GetCurSel(value);
  792.     else
  793.         pWnd->SetCurSel(value);
  794. }
  795.  
  796. void AFXAPI DDX_MonthCalCtrl(CDataExchange* pDX, int nIDC, CTime& value)
  797. {
  798.     HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  799.     CMonthCalCtrl* pWnd = (CMonthCalCtrl*) CWnd::FromHandle(hWndCtrl);
  800.  
  801.     if (pDX->m_bSaveAndValidate)
  802.         pWnd->GetCurSel(value);
  803.     else
  804.         pWnd->SetCurSel(value);
  805. }
  806.  
  807. void AFXAPI DDV_MinMaxDateTime(CDataExchange* pDX, CTime& refValue,
  808.     const CTime* pMinRange, const CTime* pMaxRange)
  809. {
  810.     ASSERT(pMinRange == NULL || pMaxRange == NULL || *pMinRange <= *pMaxRange);
  811.  
  812.     CDateTimeCtrl* pWnd =
  813.         (CDateTimeCtrl*) CWnd::FromHandle(pDX->m_hWndLastControl);
  814.  
  815.     if (!pDX->m_bSaveAndValidate)
  816.     {
  817.         if ( (pMinRange != NULL && *pMinRange > refValue) ||
  818.               (pMaxRange != NULL && *pMaxRange < refValue))
  819.         {
  820. #ifdef _DEBUG
  821.             int nIDC = GetWindowLong(pDX->m_hWndLastControl, GWL_ID);
  822.             TRACE1("Warning: initial dialog data is out of range in control ID %d.\n", nIDC);
  823. #endif
  824.             return;     // don't stop now
  825.         }
  826.     }
  827.  
  828.     pWnd->SetRange(pMinRange, pMaxRange);
  829. }
  830.  
  831. void AFXAPI DDV_MinMaxDateTime(CDataExchange* pDX,  COleDateTime& refValue,
  832.     const COleDateTime* pMinRange, const COleDateTime* pMaxRange)
  833. {
  834.     ASSERT(pMinRange == NULL || pMaxRange == NULL || *pMinRange <= *pMaxRange);
  835.     CDateTimeCtrl* pWnd =
  836.         (CDateTimeCtrl*) CWnd::FromHandle(pDX->m_hWndLastControl);
  837.  
  838.     if (!pDX->m_bSaveAndValidate)
  839.     {
  840.         if ( (pMinRange != NULL && *pMinRange > refValue) ||
  841.               (pMaxRange != NULL && *pMaxRange < refValue))
  842.         {
  843.             int nIDC = GetWindowLong(pDX->m_hWndLastControl, GWL_ID);
  844.             TRACE1("Warning: initial dialog data is out of range in control ID %d.\n", nIDC);
  845.             return;     // don't stop now
  846.         }
  847.     }
  848.  
  849.     pWnd->SetRange(pMinRange, pMaxRange);
  850. }
  851.  
  852. void AFXAPI DDV_MinMaxMonth(CDataExchange* pDX, CTime& refValue,
  853.     const CTime* pMinRange, const CTime* pMaxRange)
  854. {
  855.     ASSERT(pMinRange == NULL || pMaxRange == NULL || *pMinRange <= *pMaxRange);
  856.     CMonthCalCtrl* pWnd =
  857.         (CMonthCalCtrl*) CWnd::FromHandle(pDX->m_hWndLastControl);
  858.  
  859.     if (!pDX->m_bSaveAndValidate)
  860.     {
  861.         if ( (pMinRange != NULL && *pMinRange > refValue) ||
  862.               (pMaxRange != NULL && *pMaxRange < refValue))
  863.         {
  864. #ifdef _DEBUG
  865.             int nIDC = GetWindowLong(pDX->m_hWndLastControl, GWL_ID);
  866.             TRACE1("Warning: initial dialog data is out of range in control ID %d.\n", nIDC);
  867. #endif
  868.             return;     // don't stop now
  869.         }
  870.     }
  871.  
  872.     pWnd->SetRange(pMinRange, pMaxRange);
  873. }
  874.  
  875. void AFXAPI DDV_MinMaxMonth(CDataExchange* pDX, COleDateTime& refValue,
  876.     const COleDateTime* pMinRange, const COleDateTime* pMaxRange)
  877. {
  878.     ASSERT(pMinRange == NULL || pMaxRange == NULL || *pMinRange <= *pMaxRange);
  879.     CMonthCalCtrl* pWnd =
  880.         (CMonthCalCtrl*) CWnd::FromHandle(pDX->m_hWndLastControl);
  881.  
  882.     if (!pDX->m_bSaveAndValidate)
  883.     {
  884.         if ( (pMinRange != NULL && *pMinRange > refValue) ||
  885.               (pMaxRange != NULL && *pMaxRange < refValue))
  886.         {
  887. #ifdef _DEBUG
  888.             int nIDC = GetWindowLong(pDX->m_hWndLastControl, GWL_ID);
  889.             TRACE1("Warning: initial dialog data is out of range in control ID %d.\n", nIDC);
  890. #endif
  891.             return;     // don't stop now
  892.         }
  893.     }
  894.  
  895.     pWnd->SetRange(pMinRange, pMaxRange);
  896. }
  897.  
  898. /////////////////////////////////////////////////////////////////////////////
  899.  
  900. #ifndef _AFX_ENABLE_INLINES
  901.  
  902. static const char _szAfxWinInl[] = "afxdtctl.inl";
  903. #undef THIS_FILE
  904. #define THIS_FILE _szAfxWinInl
  905. #define _AFXDTCTL_INLINE
  906. #include "afxdtctl.inl"
  907.  
  908. #endif //_AFX_ENABLE_INLINES
  909.  
  910. /////////////////////////////////////////////////////////////////////////////
  911.  
  912. #ifdef AFX_INIT_SEG
  913. #pragma code_seg(AFX_INIT_SEG)
  914. #endif
  915.  
  916. IMPLEMENT_DYNAMIC(CDateTimeCtrl, CWnd)
  917. IMPLEMENT_DYNAMIC(CMonthCalCtrl, CWnd)
  918.  
  919. /////////////////////////////////////////////////////////////////////////////
  920.