XTPDatePickerItemMonth.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:18k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPDatePickerItemMonth.cpp: implementation of the CXTPDatePickerItemMonth class.
  2. //
  3. // This file is a part of the XTREME CALENDAR MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "XTPDatePickerItemMonth.h"
  22. #include "XTPDatePickerControl.h"
  23. #include "XTPDatePickerPaintManager.h"
  24. #include "XTPDatePickerItemDay.h"
  25. #include "XTPDatePickerDaysCollection.h"
  26. #include "XTPDatePickerNotifications.h"
  27. #include "Common/XTPDrawHelpers.h"
  28. #include "XTPCalendarUtils.h"
  29. #ifdef _DEBUG
  30. #define new DEBUG_NEW
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CXTPDatePickerItemMonth
  36. CXTPDatePickerItemMonth::CXTPDatePickerItemMonth(CXTPDatePickerControl* pControl,
  37.  COleDateTime dtMonth,
  38.  int nRow, int nCol)
  39. : m_nRow(nRow), m_nColumn(nCol), m_pControl(pControl), m_dtMonth(dtMonth)
  40. {
  41. m_rcHeader.SetRectEmpty();
  42. m_rcDaysOfWeek.SetRectEmpty();
  43. m_rcWeekNumbers.SetRectEmpty();
  44. m_rcDaysArea.SetRectEmpty();
  45. m_rcLeftScroll.SetRectEmpty();
  46. m_rcRightScroll.SetRectEmpty();
  47. m_bShowDaysBefore = FALSE;
  48. m_bShowDaysAfter = FALSE;
  49. m_bShowLeftScroll = FALSE;
  50. m_bShowRightScroll = FALSE;
  51. PopulateDays();
  52. }
  53. CXTPDatePickerItemMonth::~CXTPDatePickerItemMonth()
  54. {
  55. ClearDays();
  56. }
  57. void CXTPDatePickerItemMonth::PopulateDays()
  58. {
  59. if (m_dtMonth.GetStatus() != COleDateTime::valid)
  60. {
  61. ASSERT(FALSE);
  62. m_dtMonth = CXTPCalendarUtils::ResetTime(COleDateTime::GetCurrentTime());
  63. }
  64. // init days from 1st to last
  65. COleDateTime dtDay(m_dtMonth.GetYear(), m_dtMonth.GetMonth(), 1, 0, 0, 0);
  66. COleDateTimeSpan spDay(1, 0, 0, 0);
  67. // adjust first day of the week
  68. int nOleFirstDayOfWeek = m_pControl->GetFirstDayOfWeek();
  69. while (dtDay.GetDayOfWeek() != nOleFirstDayOfWeek)
  70. {
  71. dtDay -= spDay;
  72. }
  73. // populate all grid days
  74. for (int nWeek = 0; nWeek < XTP_MAX_WEEKS; nWeek++)
  75. {
  76. for (int nDay = 0; nDay < XTP_WEEK_DAYS; nDay++)
  77. {
  78. // create and add new day item
  79. CXTPDatePickerItemDay* pDay = new CXTPDatePickerItemDay(m_pControl, this, dtDay);
  80. m_arrDays.Add(pDay);
  81. // move next day
  82. dtDay += spDay;
  83. }
  84. }
  85. }
  86. void CXTPDatePickerItemMonth::AutoAdjustLayout(CRect rcClient)
  87. {
  88. m_rcMonth = rcClient;
  89. // calc header rect
  90. m_rcHeader = m_rcMonth;
  91. m_rcHeader.bottom = m_rcHeader.top + 18; // TODO: change to font height
  92. // calc days of week rect
  93. m_rcDaysOfWeek = m_rcMonth;
  94. m_rcDaysOfWeek.top = m_rcHeader.bottom;
  95. m_rcDaysOfWeek.bottom = m_rcDaysOfWeek.top + 18; // TODO: change to font height
  96. // draw week numbers
  97. m_rcWeekNumbers = m_rcMonth;
  98. m_rcWeekNumbers.top = m_rcDaysOfWeek.bottom;
  99. m_rcWeekNumbers.right = m_rcWeekNumbers.left + 18; // TODO: change to font width
  100. // calc triangles rect
  101. m_rcLeftScroll = m_rcHeader;
  102. m_rcRightScroll = m_rcHeader;
  103. int nScrollWidth = min(m_rcWeekNumbers.Width(), m_rcHeader.Width() / 8);
  104. m_rcHeader.left += nScrollWidth;
  105. m_rcHeader.right -= nScrollWidth;
  106. m_rcLeftScroll.right = m_rcHeader.left;
  107. m_rcRightScroll.left = m_rcHeader.right;
  108. // calc days display params
  109. m_rcDaysArea = m_rcMonth;
  110. m_rcDaysArea.top = m_rcDaysOfWeek.bottom;
  111. m_rcDaysArea.left = m_rcWeekNumbers.right;
  112. m_rcDaysArea.right -= m_rcWeekNumbers.Width();
  113. // calc simple day rect sizes
  114. CSize szDay(m_rcDaysArea.Width() / XTP_WEEK_DAYS,
  115. m_rcDaysArea.Height() / XTP_MAX_WEEKS);
  116. // calc rects for all days
  117. CRect rcDay;
  118. int nIndex = 0;
  119. for (int nWeek = 0; nWeek < XTP_MAX_WEEKS; nWeek++)
  120. {
  121. for (int nDay = 0; nDay < XTP_WEEK_DAYS; nDay++)
  122. {
  123. CXTPDatePickerItemDay* pDay = GetDay(nIndex);
  124. nIndex++;
  125. rcDay.left = m_rcDaysArea.left + nDay * szDay.cx + 1;
  126. rcDay.top = m_rcDaysArea.top + nWeek * szDay.cy;
  127. rcDay.right = rcDay.left + szDay.cx;
  128. rcDay.bottom = rcDay.top + szDay.cy;
  129. pDay->SetRect(rcDay);
  130. }
  131. }
  132. }
  133. void CXTPDatePickerItemMonth::ByFontAdjustLayout(CRect rcClient)
  134. {
  135. CWindowDC dc(CWnd::GetDesktopWindow());
  136. CSize szDay(m_pControl->m_pPaintManager->CalcDayRect(&dc));
  137. CSize szHeader(m_pControl->m_pPaintManager->CalcMonthHeaderRect(&dc));
  138. CSize szWeekText(m_pControl->m_pPaintManager->CalcDayOfWeekRect(&dc));
  139. CSize szWeekNumber(m_pControl->m_pPaintManager->CalcWeekNumbersRect(&dc));
  140. m_rcMonth = rcClient;
  141. // calc header rect
  142. m_rcHeader = m_rcMonth;
  143. m_rcHeader.bottom = m_rcHeader.top + szHeader.cy;
  144. //m_rcHeader.right = m_rcHeader.left + szHeader.cx;
  145. // calc days of week rect
  146. m_rcDaysOfWeek = m_rcMonth;
  147. m_rcDaysOfWeek.top = m_rcHeader.bottom;
  148. //m_rcDaysOfWeek.bottom = m_rcDaysOfWeek.top + 18; // TODO: change to font height
  149. m_rcDaysOfWeek.bottom = m_rcDaysOfWeek.top + szWeekText.cy;
  150. // draw week numbers
  151. m_rcWeekNumbers = m_rcMonth;
  152. m_rcWeekNumbers.top = m_rcDaysOfWeek.bottom;
  153. //m_rcWeekNumbers.right = m_rcWeekNumbers.left + 18; // TODO: change to font width
  154. m_rcWeekNumbers.right = m_rcWeekNumbers.left + szWeekNumber.cx;
  155. // calc triangles rect
  156. m_rcLeftScroll = m_rcHeader;
  157. m_rcRightScroll = m_rcHeader;
  158. m_rcLeftScroll.right = m_rcHeader.left+ szWeekNumber.cx + 3;
  159. m_rcRightScroll.left = m_rcHeader.right - szWeekNumber.cx - 3;
  160. // calc days display params
  161. m_rcDaysArea = m_rcMonth;
  162. m_rcDaysArea.top = m_rcDaysOfWeek.bottom;
  163. m_rcDaysArea.left = m_rcWeekNumbers.right;
  164. m_rcDaysArea.right -= m_rcWeekNumbers.Width();
  165. CRect rcDay;
  166. int nIndex = 0;
  167. for (int nWeek = 0; nWeek < XTP_MAX_WEEKS; nWeek++)
  168. {
  169. for (int nDay = 0; nDay < XTP_WEEK_DAYS; nDay++)
  170. {
  171. CXTPDatePickerItemDay* pDay = GetDay(nIndex);
  172. nIndex++;
  173. rcDay.left = m_rcDaysArea.left + nDay * szDay.cx + 1;
  174. rcDay.top = m_rcDaysArea.top + nWeek * szDay.cy;
  175. rcDay.right = rcDay.left + szDay.cx ;
  176. rcDay.bottom = rcDay.top + szDay.cy;
  177. pDay->SetRect(rcDay);
  178. }
  179. }
  180. }
  181. void CXTPDatePickerItemMonth::AdjustLayout(CRect rcClient, BOOL bIsAuto)
  182. {
  183. if (bIsAuto)
  184. AutoAdjustLayout(rcClient);
  185. else
  186. ByFontAdjustLayout(rcClient);
  187. }
  188. CXTPDatePickerItemDay* CXTPDatePickerItemMonth::GetDay(int nIndex)
  189. {
  190. if (nIndex < GetDayCount())
  191. return m_arrDays[nIndex];
  192. return NULL;
  193. }
  194. int CXTPDatePickerItemMonth::GetDayCount() const
  195. {
  196. return (int)m_arrDays.GetSize();
  197. }
  198. void CXTPDatePickerItemMonth::Draw(CDC* pDC)
  199. {
  200. // draw header
  201. CXTPDatePickerPaintManager* pPaintManager = m_pControl->GetPaintManager();
  202. pPaintManager->DrawMonthHeader(pDC, this);
  203. // draw days of week
  204. pPaintManager->DrawDaysOfWeek(pDC, this);
  205. //  draw all days
  206. int nDaysCount = GetDayCount();
  207. for (int nIndex = 0; nIndex < nDaysCount; nIndex++)
  208. {
  209. CXTPDatePickerItemDay* pDay = GetDay(nIndex);
  210. pDay->Draw(pDC);
  211. }
  212. // draw week numbers
  213. pPaintManager->DrawWeekNumbers(pDC, this);
  214. }
  215. // TODO: remove
  216. //void CXTPDatePickerItemMonth::DrawHeader(CDC* pDC)
  217. //{
  218. //  if (m_rcHeader.IsRectEmpty())
  219. //      return;
  220. //
  221. //  // get current paint manager
  222. //  CXTPDatePickerPaintManager* pPaintManager = m_pControl->GetPaintManager();
  223. //
  224. //  // fill background
  225. //  pDC->FillSolidRect(m_rcHeader, pPaintManager->GetHeaderBackColor());
  226. //
  227. //  // draw header text
  228. //  pDC->SetBkColor(pPaintManager->GetHeaderBackColor());
  229. //  pDC->SetTextColor(pPaintManager->GetHeaderTextColor());
  230. //  CXTPFontDC fnt(pDC, pPaintManager->GetHeaderTextFont());
  231. //  CString strText;
  232. //  strText.Format(_T("%s %d"), (LPCTSTR)m_pControl->GetMonthName(m_dtMonth.GetMonth()), m_dtMonth.GetYear());
  233. //  pDC->DrawText(strText, &m_rcHeader, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  234. //
  235. //  // draw left scroll triangle
  236. //  if (!m_rcLeftScroll.IsRectEmpty())
  237. //  {
  238. //      // fill background
  239. //      pDC->FillSolidRect(m_rcLeftScroll, pPaintManager->GetHeaderBackColor());
  240. //      // draw left triangle itself
  241. //      if (m_bShowLeftScroll)
  242. //          pPaintManager->DrawScrollTriangle(pDC, m_rcLeftScroll, TRUE);
  243. //  }
  244. //
  245. //  // draw right scroll triangle
  246. //  if (!m_rcRightScroll.IsRectEmpty())
  247. //  {
  248. //      // fill background
  249. //      pDC->FillSolidRect(m_rcRightScroll, pPaintManager->GetHeaderBackColor());
  250. //      // draw right triangle itself
  251. //      if (m_bShowRightScroll)
  252. //          pPaintManager->DrawScrollTriangle(pDC, m_rcRightScroll, FALSE);
  253. //  }
  254. //}
  255. //
  256. //void CXTPDatePickerItemMonth::DrawDaysOfWeek(CDC* pDC)
  257. //{
  258. //  if (m_rcDaysOfWeek.IsRectEmpty())
  259. //      return;
  260. //
  261. //  // get current paint manager
  262. //  CXTPDatePickerPaintManager* pPaintManager = m_pControl->GetPaintManager();
  263. //
  264. //  // fill background
  265. //  pDC->FillSolidRect(m_rcDaysOfWeek, pPaintManager->GetDaysOfWeekBackColor());
  266. //
  267. //  // draw days of week text
  268. //  pDC->SetBkColor(pPaintManager->GetDaysOfWeekBackColor());
  269. //  pDC->SetTextColor(pPaintManager->GetDaysOfWeekTextColor());
  270. //  CXTPFontDC fnt(pDC, pPaintManager->GetDaysOfWeekTextFont());
  271. //  int nMaxX = 0;
  272. //  for (int nDayDelta = 0; nDayDelta < XTP_WEEK_DAYS; nDayDelta++)
  273. //  {
  274. //      // calc item rect
  275. //      CXTPDatePickerItemDay* pDay = GetDay(nDayDelta);
  276. //      CRect rcItem(pDay->GetRect());
  277. //      rcItem.top = m_rcDaysOfWeek.top;
  278. //      rcItem.bottom = m_rcDaysOfWeek.bottom - 2;
  279. //      nMaxX = rcItem.right;
  280. //      // get item text
  281. //      CString strText(m_pControl->GetDayOfWeekName(pDay->GetDate().GetDayOfWeek()));
  282. //      pDC->DrawText(strText.Left(1), &rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  283. //  }
  284. //
  285. //  // draw bottom line on days of the week
  286. //  CRect rcBottomLine(m_rcDaysOfWeek);
  287. //  rcBottomLine.bottom--;
  288. //  rcBottomLine.top = rcBottomLine.bottom - 1;
  289. //  rcBottomLine.left = m_rcWeekNumbers.right - 1;
  290. //  rcBottomLine.right = nMaxX;
  291. //  pDC->FillSolidRect(rcBottomLine, pPaintManager->GetNonMonthDayTextColor());
  292. //}
  293. //
  294. //void CXTPDatePickerItemMonth::DrawWeekNumbers(CDC* pDC)
  295. //{
  296. //  if (!m_pControl->GetShowWeekNumbers() || m_rcWeekNumbers.IsRectEmpty())
  297. //      return;
  298. //
  299. //  // get current paint manager
  300. //  CXTPDatePickerPaintManager* pPaintManager = m_pControl->GetPaintManager();
  301. //
  302. //  // fill background
  303. //  pDC->FillSolidRect(m_rcWeekNumbers, pPaintManager->GetWeekNumbersBackColor());
  304. //
  305. //  // draw week numbers
  306. //  pDC->SetBkColor(pPaintManager->GetWeekNumbersBackColor());
  307. //  pDC->SetTextColor(pPaintManager->GetWeekNumbersTextColor());
  308. //  CXTPFontDC fnt(pDC, pPaintManager->GetWeekNumbersTextFont());
  309. //
  310. //  // draw right line on week days
  311. //  CRect rcLine(m_rcWeekNumbers);
  312. //
  313. //  for (int nWeek = 0; nWeek < XTP_MAX_WEEKS; nWeek++)
  314. //  {
  315. //      // calculate item rectangle (get week middle day)
  316. //      CXTPDatePickerItemDay* pDayFirst = GetDay(nWeek * XTP_WEEK_DAYS);
  317. //      CXTPDatePickerItemDay* pDayLast = GetDay((nWeek + 1) * XTP_WEEK_DAYS - 1);
  318. //
  319. //      if (pDayFirst && (pDayFirst->IsVisible() || nWeek < 4) && pDayLast)
  320. //      {
  321. //          CRect rcItem(pDayFirst->GetRect());
  322. //          rcItem.left = m_rcWeekNumbers.left;
  323. //          rcItem.right = m_rcWeekNumbers.right - 3;
  324. //          // get item text
  325. //          CString strText;
  326. //          int nWeekNumber = ((pDayLast->GetDate() - COleDateTimeSpan(m_pControl->GetFirstWeekOfYearDays() - 1)).GetDayOfYear() - 1) / 7 + 1;
  327. //          strText.Format(_T("%d"), nWeekNumber);
  328. //          pDC->DrawText(strText, &rcItem, DT_SINGLELINE | DT_VCENTER | DT_RIGHT);
  329. //
  330. //          rcLine.bottom = rcItem.bottom;
  331. //      }
  332. //  }
  333. //
  334. //  pDC->FillSolidRect(rcLine.right - 1, rcLine.top - 1, 1, rcLine.Height(), pPaintManager->GetNonMonthDayTextColor());
  335. //}
  336. void CXTPDatePickerItemMonth::ClearDays()
  337. {
  338. // cleanup old month array
  339. int nOldDayCount = GetDayCount();
  340. for (int nDay = 0; nDay < nOldDayCount; nDay++)
  341. {
  342. CXTPDatePickerItemDay* pDay = GetDay(nDay);
  343. pDay->InternalRelease();
  344. }
  345. m_arrDays.RemoveAll();
  346. }
  347. void CXTPDatePickerItemMonth::OnLButtonDown(UINT nFlags, CPoint point)
  348. {
  349. if (!m_pControl)
  350. return;
  351. BOOL bMultiselect = !!(nFlags & MK_CONTROL) || m_pControl->IsMultiSelectionMode();
  352. // check left scroll item
  353. if (m_bShowLeftScroll &&
  354. !m_rcLeftScroll.IsRectEmpty() && m_rcLeftScroll.PtInRect(point))
  355. {
  356. m_pControl->m_mouseMode = CXTPDatePickerControl::mouseScrollingLeft;
  357. m_pControl->m_nTimerID = (UINT)m_pControl->SetTimer(XTP_DATEPICKER_TIMERID, XTP_DATEPICKER_TIMER_INTERVAL, NULL);
  358. m_pControl->ScrollLeft(m_pControl->GetMonthDelta());
  359. return;
  360. }
  361. // check right scroll item
  362. if (m_bShowRightScroll &&
  363. !m_rcRightScroll.IsRectEmpty() && m_rcRightScroll.PtInRect(point))
  364. {
  365. m_pControl->m_mouseMode = CXTPDatePickerControl::mouseScrollingRight;
  366. m_pControl->m_nTimerID = (UINT)m_pControl->SetTimer(XTP_DATEPICKER_TIMERID, XTP_DATEPICKER_TIMER_INTERVAL, NULL);
  367. m_pControl->ScrollRight(m_pControl->GetMonthDelta());
  368. return;
  369. }
  370. // check header click
  371. if (!m_rcHeader.IsRectEmpty() && m_rcHeader.PtInRect(point))
  372. {
  373. // call month popup list
  374. m_pControl->ShowListHeader(m_rcHeader, m_dtMonth);
  375. return;
  376. }
  377. // check week numbers click
  378. m_pControl->m_bSelectWeek = !m_rcWeekNumbers.IsRectEmpty() && m_rcWeekNumbers.PtInRect(point);
  379. CPoint ptFirstWeekDay(point);
  380. ptFirstWeekDay.x = m_rcWeekNumbers.right + 3;
  381. // check day item
  382. CXTPDatePickerItemDay* pDay = HitTest(m_pControl->m_bSelectWeek ? ptFirstWeekDay : point, FALSE);
  383. if (pDay)
  384. {
  385. m_pControl->ClearFocus();
  386. BOOL bAllowNoncontinuousSelection = m_pControl->IsAllowNoncontinuousSelection();
  387. COleDateTime dtDay(pDay->GetDate());
  388. BOOL bSelected = m_pControl->IsSelected(dtDay);
  389. if (m_pControl->m_bSelectWeek)
  390. {
  391. // week is selected only when all week days are selected
  392. for (int i = 0; i < 7; i++)
  393. {
  394. COleDateTime dtDay_i = dtDay + COleDateTimeSpan(i, 0, 0, 0);
  395. bSelected &= m_pControl->IsSelected(dtDay_i);
  396. }
  397. }
  398. if (bSelected && bMultiselect && bAllowNoncontinuousSelection)
  399. m_pControl->m_mouseMode = CXTPDatePickerControl::mouseDeselecting;
  400. else
  401. m_pControl->m_mouseMode = CXTPDatePickerControl::mouseSelecting;
  402. if (!bMultiselect || !bAllowNoncontinuousSelection)
  403. m_pControl->m_pSelectedDays->Clear();
  404. if (nFlags & MK_SHIFT)
  405. {
  406. if (m_pControl->m_dtFirstClicked.GetStatus() == COleDateTime::valid)
  407. {
  408. m_pControl->m_dtLastClicked = dtDay;
  409. }
  410. else if (m_pControl->m_dtLastClicked.GetStatus() == COleDateTime::valid)
  411. {
  412. m_pControl->m_dtFirstClicked = m_pControl->m_dtLastClicked;
  413. m_pControl->m_dtLastClicked = dtDay;
  414. }
  415. else if (m_pControl->GetSelRange(m_pControl->m_dtFirstClicked, m_pControl->m_dtLastClicked))
  416. {
  417. if (m_pControl->m_dtFirstClicked < dtDay)
  418. m_pControl->m_dtLastClicked = dtDay;
  419. else
  420. m_pControl->m_dtFirstClicked = dtDay;
  421. }
  422. else
  423. {
  424. m_pControl->m_dtFirstClicked = dtDay;
  425. m_pControl->m_dtLastClicked = dtDay;
  426. }
  427. }
  428. else
  429. {
  430. m_pControl->m_dtFirstClicked = dtDay;
  431. m_pControl->m_dtLastClicked = m_pControl->m_bSelectWeek ?
  432. dtDay + COleDateTimeSpan(6, 0, 0, 0) : dtDay;
  433. }
  434. m_pControl->_RedrawControl(FALSE);
  435. }
  436. }
  437. void CXTPDatePickerItemMonth::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/)
  438. {
  439. }
  440. void CXTPDatePickerItemMonth::OnMouseMove(UINT /*nFlags*/, CPoint point)
  441. {
  442. if ((m_pControl->m_mouseMode == CXTPDatePickerControl::mouseDeselecting ||
  443.  m_pControl->m_mouseMode == CXTPDatePickerControl::mouseSelecting) &&
  444. (m_rcDaysArea.PtInRect(point) || m_rcWeekNumbers.PtInRect(point)))
  445. {
  446. // check day item
  447. CPoint ptWeekBegin(m_rcWeekNumbers.right + 3, point.y);
  448. CXTPDatePickerItemDay* pDay = HitTest(m_pControl->m_bSelectWeek ? ptWeekBegin : point, FALSE);
  449. if (pDay)
  450. {
  451. // save old clicked dates
  452. COleDateTime dtOldFirstClicked = m_pControl->m_dtFirstClicked;
  453. COleDateTime dtOldLastClicked = m_pControl->m_dtLastClicked;
  454. // calculate new clicked dates
  455. COleDateTime dtDay(pDay->GetDate());
  456. if (m_pControl->m_bSelectWeek)
  457. {
  458. COleDateTime dtWeekEnd(dtDay + COleDateTimeSpan(6, 0, 0, 0));
  459. if (dtWeekEnd >= m_pControl->m_dtFirstClicked)
  460. {
  461. if (dtDay.GetDayOfWeek() != m_pControl->m_dtFirstClicked.GetDayOfWeek())
  462. m_pControl->m_dtFirstClicked -= COleDateTimeSpan(6, 0, 0, 0);
  463. m_pControl->m_dtLastClicked = dtWeekEnd;
  464. }
  465. if (dtDay < m_pControl->m_dtFirstClicked)
  466. {
  467. if (dtDay.GetDayOfWeek() == m_pControl->m_dtFirstClicked.GetDayOfWeek())
  468. m_pControl->m_dtFirstClicked += COleDateTimeSpan(6, 0, 0, 0);
  469. m_pControl->m_dtLastClicked = dtDay;
  470. }
  471. }
  472. else
  473. {
  474. m_pControl->m_dtLastClicked = dtDay;
  475. }
  476. // update control if needed
  477. if (((dtOldLastClicked - m_pControl->m_dtLastClicked).GetDays() != 0) ||
  478.  ((dtOldFirstClicked - m_pControl->m_dtFirstClicked).GetDays() != 0))
  479. {
  480. m_pControl->RedrawControl();
  481. }
  482. }
  483. }
  484. }
  485. CXTPDatePickerItemDay* CXTPDatePickerItemMonth::HitTest(CPoint point, BOOL bCheckVisible)
  486. {
  487. // enumerate month array
  488. int nDayCount = GetDayCount();
  489. for (int nDay = 0; nDay < nDayCount; nDay++)
  490. {
  491. CXTPDatePickerItemDay* pDay = GetDay(nDay);
  492. if (pDay && pDay->GetRect().PtInRect(point) &&
  493. (pDay->IsVisible() || !bCheckVisible))
  494. {
  495. return pDay;
  496. }
  497. }
  498. return NULL;
  499. }
  500. BOOL CXTPDatePickerItemMonth::OnSetCursor(CPoint point)
  501. {
  502. if (!m_rcWeekNumbers.IsRectEmpty() && m_rcWeekNumbers.PtInRect(point) &&
  503. m_pControl && m_pControl->GetPaintManager())
  504. {
  505. // week selection cursor
  506. SetCursor(m_pControl->GetPaintManager()->GetCursorBack());
  507. return TRUE;
  508. }
  509. return FALSE;
  510. }