Leaked source code of windows server 2003
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.

267 lines
5.9 KiB

  1. //
  2. // WGRP.CPP
  3. // Widths Group
  4. //
  5. // Copyright Microsoft 1998-
  6. //
  7. // PRECOMP
  8. #include "precomp.h"
  9. static const TCHAR szWGClassName[] = "WB_WGRP";
  10. WbWidthsGroup::WbWidthsGroup()
  11. {
  12. int i;
  13. m_hwnd = NULL;
  14. m_uLast = 0;
  15. //
  16. // Calculate the height of each item in the list--it's the max of the
  17. // pen widths + slop space
  18. //
  19. m_cyItem = 0;
  20. for (i = 0; i < NUM_OF_WIDTHS; i++)
  21. {
  22. m_cyItem = max(m_cyItem, g_PenWidths[i]);
  23. }
  24. m_cyItem += 2 * ::GetSystemMetrics(SM_CYEDGE);
  25. }
  26. WbWidthsGroup::~WbWidthsGroup()
  27. {
  28. if (m_hwnd != NULL)
  29. {
  30. ::DestroyWindow(m_hwnd);
  31. ASSERT(m_hwnd == NULL);
  32. }
  33. ::UnregisterClass(szWGClassName, g_hInstance);
  34. }
  35. BOOL WbWidthsGroup::Create(HWND hwndParent, LPCRECT lprect)
  36. {
  37. WNDCLASSEX wc;
  38. // Register our class
  39. ZeroMemory(&wc, sizeof(wc));
  40. wc.cbSize = sizeof(wc);
  41. wc.style = 0;
  42. wc.lpfnWndProc = WGWndProc;
  43. wc.hInstance = g_hInstance;
  44. wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
  45. wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  46. wc.lpszClassName = szWGClassName;
  47. if (!::RegisterClassEx(&wc))
  48. {
  49. ERROR_OUT(("WbWidthsGroup::Create register class failed"));
  50. return(FALSE);
  51. }
  52. ASSERT(!m_hwnd);
  53. if (!::CreateWindowEx(WS_EX_STATICEDGE, szWGClassName, NULL,
  54. WS_CHILD | WS_CLIPSIBLINGS, lprect->left, lprect->top,
  55. lprect->right - lprect->left, lprect->bottom - lprect->top,
  56. hwndParent, (HMENU)IDM_WIDTH, g_hInstance, this))
  57. {
  58. ERROR_OUT(("Can't create WbWidthsGroup"));
  59. return(FALSE);
  60. }
  61. return(TRUE);
  62. }
  63. //
  64. // WGWndProc()
  65. // Message handler for width window
  66. //
  67. LRESULT CALLBACK WGWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  68. {
  69. LRESULT lResult = 0;
  70. WbWidthsGroup * pwg = (WbWidthsGroup *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
  71. switch (message)
  72. {
  73. case WM_NCCREATE:
  74. pwg = (WbWidthsGroup *)(((LPCREATESTRUCT)lParam)->lpCreateParams);
  75. ASSERT(pwg);
  76. pwg->m_hwnd = hwnd;
  77. ::SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)pwg);
  78. goto DefWndProc;
  79. break;
  80. case WM_NCDESTROY:
  81. ASSERT(pwg);
  82. pwg->m_hwnd = NULL;
  83. break;
  84. case WM_PAINT:
  85. ASSERT(pwg);
  86. pwg->OnPaint();
  87. break;
  88. case WM_LBUTTONDOWN:
  89. ASSERT(pwg);
  90. pwg->OnLButtonDown((short)LOWORD(lParam), (short)HIWORD(lParam));
  91. break;
  92. case WM_NOTIFY:
  93. // Pass up to main window
  94. lResult = ::SendMessage(g_pMain->m_hwnd, message, wParam, lParam);
  95. break;
  96. default:
  97. DefWndProc:
  98. lResult = DefWindowProc(hwnd, message, wParam, lParam);
  99. break;
  100. }
  101. return(lResult);
  102. }
  103. void WbWidthsGroup::GetNaturalSize(LPSIZE lpsize)
  104. {
  105. lpsize->cy = ::GetSystemMetrics(SM_CYEDGE) +
  106. (NUM_OF_WIDTHS * m_cyItem);
  107. if (m_hwnd != NULL)
  108. {
  109. RECT rect;
  110. ::GetWindowRect(m_hwnd, &rect);
  111. rect.right -= rect.left;
  112. lpsize->cx = max(WIDTHBAR_WIDTH, rect.right);
  113. }
  114. else
  115. {
  116. lpsize->cx = WIDTHBAR_WIDTH;
  117. }
  118. }
  119. void WbWidthsGroup::PushDown(UINT uiIndex)
  120. {
  121. if( (uiIndex < NUM_OF_WIDTHS))
  122. {
  123. //
  124. // We really should just invalidate the last selected item, if one,
  125. // and the new selected item, if one. But heck, there are only 4
  126. // items, no big deal to paint.
  127. //
  128. m_uLast = uiIndex;
  129. ::InvalidateRect(m_hwnd, NULL, TRUE);
  130. }
  131. }
  132. void WbWidthsGroup::OnPaint(void)
  133. {
  134. PAINTSTRUCT ps;
  135. int i;
  136. RECT rect;
  137. int cx, cy;
  138. int nPenWidth;
  139. HBRUSH hOldBrush;
  140. ::BeginPaint(m_hwnd, &ps);
  141. ::GetClientRect(m_hwnd, &rect);
  142. cx = ::GetSystemMetrics(SM_CXEDGE);
  143. cy = m_cyItem / 2;
  144. // First, fill the background of the selected item
  145. hOldBrush = SelectBrush(ps.hdc, ::GetSysColorBrush(COLOR_3DHILIGHT));
  146. ::PatBlt(ps.hdc, rect.left, m_uLast * m_cyItem,
  147. rect.right - rect.left, m_cyItem, PATCOPY);
  148. rect.right -= rect.left + 2*cx;
  149. // Now, use the black brush
  150. SelectBrush(ps.hdc, ::GetStockObject(BLACK_BRUSH));
  151. for (i = 0; i < NUM_OF_WIDTHS; i++)
  152. {
  153. nPenWidth = g_PenWidths[i];
  154. ::PatBlt(ps.hdc, cx, rect.top + (m_cyItem - nPenWidth) / 2,
  155. rect.right, nPenWidth, PATCOPY);
  156. rect.top += m_cyItem;
  157. }
  158. SelectBrush(ps.hdc, hOldBrush);
  159. // Finish painting
  160. ::EndPaint(m_hwnd, &ps);
  161. }
  162. //
  163. // ItemFromPoint()
  164. // Returns which item, in the client, is under the point.
  165. //
  166. int WbWidthsGroup::ItemFromPoint(int x, int y) const
  167. {
  168. int iItem;
  169. iItem = y / m_cyItem;
  170. // If it's in the border above the first item, pin it.
  171. if (iItem < 0)
  172. iItem = 0;
  173. // If it's in the border below the last item, pin it.
  174. if (iItem >= (IDM_WIDTHS_END - IDM_WIDTHS_START))
  175. iItem = (IDM_WIDTHS_END - IDM_WIDTHS_START - 1);
  176. return(iItem + IDM_WIDTHS_START);
  177. }
  178. //
  179. // GetItemRect()
  180. // Gets the client-relative rectangle of an item
  181. //
  182. void WbWidthsGroup::GetItemRect(int iItem, LPRECT lprc) const
  183. {
  184. ::GetClientRect(m_hwnd, lprc);
  185. lprc->top = (iItem - IDM_WIDTHS_START) * m_cyItem;
  186. lprc->bottom = lprc->top + m_cyItem;
  187. }
  188. //
  189. // OnLButtonDown()
  190. //
  191. void WbWidthsGroup::OnLButtonDown(int x, int y)
  192. {
  193. int iItem;
  194. iItem = ItemFromPoint(x, y);
  195. ::PostMessage(g_pMain->m_hwnd, WM_COMMAND,
  196. (WPARAM)MAKELONG(iItem, BN_CLICKED),
  197. (LPARAM)m_hwnd);
  198. }