Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
4.9 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: flexcheckbox.cpp
  3. //
  4. // Desc: Implements a check box control similar to Windows check box.
  5. // CFlexCheckBox is derived from CFlexWnd. The only place that
  6. // uses CFlxCheckBox is in the keyboard for sorting by assigned
  7. // keys.
  8. //
  9. // Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
  10. //-----------------------------------------------------------------------------
  11. #include "common.hpp"
  12. CFlexCheckBox::CFlexCheckBox() :
  13. m_hWndNotify(NULL),
  14. m_bChecked(FALSE),
  15. m_rgbText(RGB(255,255,255)),
  16. m_rgbBk(RGB(0,0,0)),
  17. m_rgbSelText(RGB(0,0,255)),
  18. m_rgbSelBk(RGB(0,0,0)),
  19. m_rgbFill(RGB(0,0,255)),
  20. m_rgbLine(RGB(0,255,255)),
  21. m_hFont(NULL),
  22. m_tszText(NULL)
  23. {
  24. }
  25. CFlexCheckBox::~CFlexCheckBox()
  26. {
  27. delete[] m_tszText;
  28. }
  29. void CFlexCheckBox::SetText(LPCTSTR tszText)
  30. {
  31. LPTSTR tszTempText = NULL;
  32. if (tszText)
  33. {
  34. tszTempText = new TCHAR[_tcslen(tszText) + 1];
  35. if (!tszTempText) return;
  36. _tcscpy(tszTempText, tszText);
  37. }
  38. delete[] m_tszText;
  39. m_tszText = tszTempText;
  40. }
  41. void CFlexCheckBox::SetFont(HFONT hFont)
  42. {
  43. m_hFont = hFont;
  44. if (m_hWnd == NULL)
  45. return;
  46. Invalidate();
  47. }
  48. void CFlexCheckBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
  49. {
  50. m_rgbText = text;
  51. m_rgbBk = bk;
  52. m_rgbSelText = seltext;
  53. m_rgbSelBk = selbk;
  54. m_rgbFill = fill;
  55. m_rgbLine = line;
  56. Invalidate();
  57. }
  58. void CFlexCheckBox::SetRect()
  59. {
  60. if (m_hWnd == NULL)
  61. return;
  62. RECT rect = GetRect();
  63. SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
  64. }
  65. RECT CFlexCheckBox::GetRect(const RECT &rect)
  66. {
  67. int h = GetTextHeight(m_hFont);
  68. RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
  69. return ret;
  70. }
  71. RECT CFlexCheckBox::GetRect()
  72. {
  73. RECT rect;
  74. GetClientRect(&rect);
  75. return GetRect(rect);
  76. }
  77. void CFlexCheckBox::OnPaint(HDC hDC)
  78. {
  79. HDC hBDC = NULL, hODC = NULL;
  80. CBitmap *pbm = NULL;
  81. if (!InRenderMode())
  82. {
  83. hODC = hDC;
  84. pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
  85. if (pbm != NULL)
  86. {
  87. hBDC = pbm->BeginPaintInto();
  88. if (hBDC != NULL)
  89. {
  90. hDC = hBDC;
  91. }
  92. }
  93. }
  94. InternalPaint(hDC);
  95. if (!InRenderMode())
  96. {
  97. if (pbm != NULL)
  98. {
  99. if (hBDC != NULL)
  100. {
  101. pbm->EndPaintInto(hBDC);
  102. pbm->Draw(hODC);
  103. }
  104. delete pbm;
  105. }
  106. }
  107. }
  108. void CFlexCheckBox::InternalPaint(HDC hDC)
  109. {
  110. HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
  111. if (hBrush != NULL)
  112. {
  113. HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
  114. // Erase the background first
  115. RECT client;
  116. GetClientRect(&client);
  117. Rectangle(hDC, client.left, client.top, client.right, client.bottom);
  118. // Create pen for check box
  119. HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
  120. if (hPen != NULL)
  121. {
  122. HGDIOBJ hOldPen = SelectObject(hDC, hPen);
  123. RECT rect = {0, 0, 0, 0}, textrc;
  124. GetClientRect(&rect);
  125. textrc = rect;
  126. int iBoxDim = rect.bottom - rect.top;
  127. // Draw the square box
  128. rect.right = rect.left + iBoxDim;
  129. InflateRect(&rect, -2, -2);
  130. OffsetRect(&rect, 0, -2); // Move up to align with the text
  131. Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
  132. // Draw the check mark if the state is checked.
  133. if (m_bChecked)
  134. {
  135. HGDIOBJ hCrossPen = CreatePen(PS_SOLID, 3, m_rgbLine);
  136. if (hCrossPen != NULL)
  137. {
  138. SelectObject(hDC, hCrossPen);
  139. MoveToEx(hDC, rect.left + 2, rect.top + 2, NULL); // Upper left
  140. LineTo(hDC, rect.right - 2, rect.bottom - 2); // Lower right
  141. MoveToEx(hDC, rect.right - 2, rect.top + 2, NULL); // Upper right
  142. LineTo(hDC, rect.left + 2, rect.bottom - 2); // Lower left
  143. SelectObject(hDC, hPen);
  144. DeleteObject(hCrossPen);
  145. }
  146. }
  147. SetBkMode(hDC, TRANSPARENT);
  148. // Draw the message text
  149. SetTextColor(hDC, m_rgbText);
  150. textrc.left = rect.right + 8;
  151. DrawText(hDC, m_tszText, -1, &textrc, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
  152. SelectObject(hDC, hOldPen);
  153. DeleteObject(hPen);
  154. }
  155. SelectObject(hDC, hOldBrush);
  156. DeleteObject(hBrush);
  157. }
  158. }
  159. void CFlexCheckBox::Notify(int code)
  160. {
  161. if (!m_hWndNotify)
  162. return;
  163. PostMessage(m_hWndNotify, WM_FLEXCHECKBOX,
  164. (WPARAM)code, (LPARAM)(LPVOID)this);
  165. }
  166. void CFlexCheckBox::OnClick(POINT point, WPARAM fwKeys, BOOL bLeft)
  167. {
  168. if (!m_hWnd)
  169. return;
  170. RECT rect;
  171. GetClientRect(&rect);
  172. rect.right = rect.left + (rect.bottom - rect.top); // Adjust the width to same as height.
  173. InflateRect(&rect, -2, -2);
  174. OffsetRect(&rect, 0, -2); // Move up to align with the text
  175. if (PtInRect(&rect, point))
  176. {
  177. m_bChecked = !m_bChecked;
  178. Invalidate();
  179. Notify(m_bChecked ? CHKNOTIFY_CHECK : CHKNOTIFY_UNCHECK); // Notify the page object about the state change.
  180. } else
  181. {
  182. // Unhighlight current callout
  183. HWND hWndParent;
  184. hWndParent = GetParent(m_hWnd);
  185. SendMessage(hWndParent, WM_UNHIGHLIGHT, 0, 0); // Send click message to page to unhighlight callout
  186. }
  187. }
  188. void CFlexCheckBox::OnMouseOver(POINT point, WPARAM fwKeys)
  189. {
  190. Notify(CHKNOTIFY_MOUSEOVER);
  191. }