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

对话框与窗口

开发平台:

Visual C++

  1. // XTPDatePickerList.cpp: implementation of the CXTPDatePickerList 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 "Common/XTPDrawHelpers.h"
  22. #include "XTPDatePickerPaintManager.h"
  23. #include "XTPDatePickerItemMonth.h"
  24. #include "XTPDatePickerItemDay.h"
  25. #include "XTPDatePickerControl.h"
  26. #include "XTPDatePickerList.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CXTPDatePickerList
  34. CXTPDatePickerList::CXTPDatePickerList(CXTPDatePickerControl* pControl, COleDateTime dtStartMonth)
  35. : m_pControl(pControl), m_dtStartMonth(dtStartMonth), m_dtSelMonth(dtStartMonth), m_dtMiddleMonth(dtStartMonth)
  36. {
  37. m_nItemsAbove = 3;
  38. m_nItemsBelow = 3;
  39. m_rcListControl.SetRectEmpty();
  40. }
  41. CXTPDatePickerList::~CXTPDatePickerList()
  42. {
  43. }
  44. BEGIN_MESSAGE_MAP(CXTPDatePickerList, CWnd)
  45. //{{AFX_MSG_MAP(CXTPDatePickerList)
  46. ON_WM_ERASEBKGND()
  47. ON_WM_PAINT()
  48. //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CXTPDatePickerList message handlers
  52. BOOL CXTPDatePickerList::OnEraseBkgnd(CDC* /*pDC*/)
  53. {
  54. return TRUE;
  55. }
  56. void CXTPDatePickerList::OnPaint()
  57. {
  58. CPaintDC dcPaint(this); // device context for painting
  59. CXTPClientRect rcClient(this);
  60. CXTPBufferDC dcMem(dcPaint, rcClient);
  61. m_dtSelMonth.SetStatus(COleDateTime::null);
  62. int nMonth = m_dtMiddleMonth.GetMonth();
  63. int nYear = m_dtMiddleMonth.GetYear();
  64. ShiftMonthDown(nYear, nMonth, m_nItemsAbove);
  65. CXTPDatePickerPaintManager* pPaintManager = m_pControl->GetPaintManager();
  66. // prepare DC
  67. CFont* pOldFont = dcMem.SelectObject(pPaintManager->GetListControlTextFont());
  68. int iPosY = 0;
  69. // fill background
  70. dcMem.FillSolidRect(rcClient, pPaintManager->GetListControlBackColor());
  71. dcMem.SetTextColor(pPaintManager->GetListControlTextColor());
  72. dcMem.SetBkMode(TRANSPARENT);
  73. CString strDisplayText;
  74. for (int nItem = 0; nItem < m_nItemsAbove + 1 + m_nItemsBelow; nItem++)
  75. {
  76. CRect rcItem;
  77. if (m_pControl)
  78. strDisplayText.Format(_T("%s %d"), (LPCTSTR)m_pControl->GetMonthName(nMonth), nYear);
  79. CSize szItem = dcMem.GetTextExtent(_T(" "), 1);
  80. szItem.cy += 3;
  81. rcItem.SetRect(0, iPosY, m_rcListControl.Width(), iPosY + szItem.cy);
  82. dcMem.DrawText(strDisplayText, rcItem, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  83. if (IsSelected(nItem, rcItem))
  84. {
  85. dcMem.InvertRect(rcItem);
  86. m_dtSelMonth.SetDate(nYear, nMonth, 1);
  87. m_dtSelMonth.SetStatus(COleDateTime::valid);
  88. }
  89. // next month
  90. ShiftMonthUp(nYear, nMonth, 1);
  91. iPosY += szItem.cy;
  92. }
  93. dcMem.SelectObject(pOldFont);
  94. }
  95. void CXTPDatePickerList::OnMouseMove(UINT /*nFlags*/, CPoint /*point*/)
  96. {
  97. Invalidate();
  98. }
  99. void CXTPDatePickerList::OnTimer(UINT_PTR /*nIDEvent*/)
  100. {
  101. // determine cursor position
  102. DWORD dwPos = ::GetMessagePos();
  103. POINTS ptsPos = MAKEPOINTS(dwPos);
  104. CPoint ptPos;
  105. ptPos.x = ptsPos.x;
  106. ptPos.y = ptsPos.y;
  107. CRect rcClient;
  108. GetClientRect(rcClient);
  109. ClientToScreen(rcClient);
  110. if (ptPos.y < rcClient.top)
  111. {
  112. int nDiff = rcClient.top - ptPos.y;
  113. int nScroll = nDiff / rcClient.Height() + 1;
  114. ScrollUp(nScroll);
  115. Invalidate();
  116. }
  117. else if (ptPos.y > rcClient.bottom)
  118. {
  119. int nDiff = ptPos.y - rcClient.bottom;
  120. int nScroll = nDiff / rcClient.Height() + 1;
  121. ScrollDown(nScroll);
  122. Invalidate();
  123. }
  124. }
  125. BOOL CXTPDatePickerList::IsSelected(int nX, CRect rcItem)
  126. {
  127. BOOL bReturn = FALSE;
  128. // determine cursor position
  129. DWORD dwPos = ::GetMessagePos();
  130. POINTS ptsPos = MAKEPOINTS(dwPos);
  131. CPoint ptPos;
  132. ptPos.x = ptsPos.x;
  133. ptPos.y = ptsPos.y;
  134. ScreenToClient(&ptPos);
  135. CRect rcClient;
  136. GetClientRect(rcClient);
  137. if (ptPos.x < rcClient.left || ptPos.x > rcClient.right ||
  138. ptPos.y < rcClient.top || ptPos.y > rcClient.bottom)
  139. return FALSE;
  140. if (ptPos.y < 0 && nX == 0)
  141. bReturn = TRUE;
  142. else if (ptPos.y > rcClient.Height() && nX == (m_nItemsBelow + m_nItemsAbove))
  143. bReturn = TRUE;
  144. else if (ptPos.y >= rcItem.top && ptPos.y <= rcItem.bottom-1)
  145. bReturn = TRUE;
  146. return bReturn;
  147. }
  148. CSize CXTPDatePickerList::GetListSize()
  149. {
  150. ASSERT(m_pControl);
  151. if (!m_pControl)
  152. return 0;
  153. CSize szMaxItem(0, 0);
  154. CClientDC dc(m_pControl);
  155. CXTPDatePickerPaintManager* pPaintManager = m_pControl->GetPaintManager();
  156. CFont* pOldFont = dc.SelectObject(pPaintManager->GetListControlTextFont());
  157. szMaxItem.cy = dc.GetTextExtent(_T(" "), 1).cy + 3;
  158. for (int nMonth = 1; nMonth <= 12; nMonth++)
  159. {
  160. CString strText;
  161. if (m_pControl)
  162. strText.Format(_T("%s 0000"), (LPCTSTR)m_pControl->GetMonthName(nMonth));
  163. int iWidth = dc.GetTextExtent(strText).cx;
  164. if (iWidth > szMaxItem.cx)
  165. szMaxItem.cx = iWidth;
  166. }
  167. dc.SelectObject(pOldFont);
  168. // calculate rectangle
  169. CSize szCalendar(szMaxItem.cx + 20, szMaxItem.cy * (m_nItemsAbove + 1 + m_nItemsBelow) + 2);
  170. return szCalendar;
  171. }
  172. void CXTPDatePickerList::ShiftMonthUp(int& nYear, int& nMonth, const int nCount)
  173. {
  174. for (int nItem = 0; nItem < nCount; nItem++)
  175. {
  176. nMonth++;
  177. if (nMonth > 12)
  178. {
  179. nMonth = 1;
  180. nYear++;
  181. }
  182. }
  183. }
  184. void CXTPDatePickerList::ShiftMonthDown(int& nYear, int& nMonth, const int nCount)
  185. {
  186. for (int nItem = 0; nItem < nCount; nItem++)
  187. {
  188. nMonth--;
  189. if (nMonth < 1)
  190. {
  191. nMonth = 12;
  192. nYear--;
  193. }
  194. }
  195. }
  196. void CXTPDatePickerList::ScrollUp(int nCount)
  197. {
  198. int nMonth = m_dtMiddleMonth.GetMonth();
  199. int nYear = m_dtMiddleMonth.GetYear();
  200. ShiftMonthDown(nYear, nMonth, nCount);
  201. COleDateTime dtMinRange, dtMaxRange;
  202. DWORD dwRes = m_pControl->GetRange(&dtMinRange, &dtMaxRange);
  203. if (dwRes & GDTR_MIN)
  204. {
  205. int nTopMonth = nMonth;
  206. int nTopYear = nYear;
  207. ShiftMonthDown(nTopYear, nTopMonth, m_nItemsAbove);
  208. COleDateTime dtTmp(nTopYear, nTopMonth, m_dtMiddleMonth.GetDay(), 0, 0, 0);
  209. if (dtTmp < dtMinRange)
  210. {
  211. nYear = dtMinRange.GetYear();
  212. nMonth = dtMinRange.GetMonth();
  213. ShiftMonthUp(nYear, nMonth, m_nItemsAbove);
  214. }
  215. }
  216. m_dtMiddleMonth.SetDate(nYear, nMonth, 1);
  217. }
  218. void CXTPDatePickerList::ScrollDown(int nCount)
  219. {
  220. int nMonth = m_dtMiddleMonth.GetMonth();
  221. int nYear = m_dtMiddleMonth.GetYear();
  222. ShiftMonthUp(nYear, nMonth, nCount);
  223. COleDateTime dtMinRange, dtMaxRange;
  224. DWORD dwRes = m_pControl->GetRange(&dtMinRange, &dtMaxRange);
  225. if (dwRes & GDTR_MAX)
  226. {
  227. int nBottomMonth = nMonth;
  228. int nBottomYear = nYear;
  229. ShiftMonthUp(nBottomYear, nBottomMonth, m_nItemsBelow);
  230. COleDateTime dtTmp(nBottomYear, nBottomMonth, m_dtMiddleMonth.GetDay(), 0, 0, 0);
  231. if (dtTmp > dtMaxRange)
  232. {
  233. nYear = dtMaxRange.GetYear();
  234. nMonth = dtMaxRange.GetMonth();
  235. ShiftMonthDown(nYear, nMonth, m_nItemsBelow);
  236. }
  237. }
  238. m_dtMiddleMonth.SetDate(nYear, nMonth, 1);
  239. ScrollUp(0);
  240. }
  241. int CXTPDatePickerList::GetMonthInterval()
  242. {
  243. if (m_dtSelMonth.GetStatus() == COleDateTime::valid)
  244. {
  245. return (m_dtSelMonth.GetYear() * 12 + m_dtSelMonth.GetMonth()) -
  246. (m_dtStartMonth.GetYear() * 12 + m_dtStartMonth.GetMonth());
  247. }
  248. return 0;
  249. }
  250. BOOL CXTPDatePickerList::Create(CRect rcList)
  251. {
  252. // create list control
  253. DWORD dwStyle = WS_POPUP | WS_EX_TOPMOST | WS_EX_WINDOWEDGE | WS_BORDER;
  254. m_pControl->ClientToScreen(rcList);
  255. if (!CreateEx(0, AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
  256. NULL, dwStyle, rcList, m_pControl, 0, 0))
  257. return FALSE;
  258. CSize szCalendar = GetListSize();
  259. m_rcListControl = rcList;
  260. m_rcListControl.left = m_rcListControl.CenterPoint().x - szCalendar.cx / 2 - 1;
  261. m_rcListControl.right = m_rcListControl.left + szCalendar.cx;
  262. m_rcListControl.top = m_rcListControl.CenterPoint().y - szCalendar.cy / 2 + 1;
  263. m_rcListControl.bottom = m_rcListControl.top + szCalendar.cy;
  264. SetWindowPos(NULL, m_rcListControl.left, m_rcListControl.top, m_rcListControl.Width(), m_rcListControl.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
  265. ScrollDown(0);
  266. RedrawWindow();
  267. return TRUE;
  268. }