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.

320 lines
7.4 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: flexinfobox.cpp
  3. //
  4. // Desc: Implements a simple text box that displays a text string.
  5. // CFlexInfoBox is derived from CFlexWnd. It is used by the page
  6. // for displaying direction throughout the UI. The strings are
  7. // stored as resources. The class has a static buffer which will
  8. // be filled with the string by the resource API when needed.
  9. //
  10. // Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
  11. //-----------------------------------------------------------------------------
  12. #include "common.hpp"
  13. CFlexInfoBox::CFlexInfoBox() :
  14. m_iCurIndex(-1),
  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_bVertSB(FALSE),
  23. m_nSBWidth(11)
  24. {
  25. m_TextRect.top = 0;
  26. m_TextRect.left = 0;
  27. m_TextRect.bottom = 0;
  28. m_TextRect.right = 0;
  29. }
  30. CFlexInfoBox::~CFlexInfoBox()
  31. {
  32. }
  33. BOOL CFlexInfoBox::Create(HWND hParent, const RECT &rect, BOOL bVisible)
  34. {
  35. if (!CFlexWnd::Create(hParent, rect, bVisible))
  36. return FALSE;
  37. FLEXSCROLLBARCREATESTRUCT sbcs;
  38. sbcs.dwSize = sizeof(FLEXSCROLLBARCREATESTRUCT);
  39. sbcs.dwFlags = FSBF_VERT;
  40. sbcs.min = 0;
  41. sbcs.max = 3;
  42. sbcs.page = 1;
  43. sbcs.pos = 1;
  44. sbcs.hWndParent = m_hWnd;
  45. sbcs.hWndNotify = m_hWnd;
  46. RECT rc = {0, 0, 1, 1};
  47. sbcs.rect = rc;
  48. sbcs.bVisible = FALSE;
  49. return m_VertSB.Create(&sbcs);
  50. }
  51. void CFlexInfoBox::SetText(int iIndex)
  52. {
  53. if (iIndex == m_iCurIndex)
  54. return;
  55. // Load the string from resource
  56. LoadString(g_hModule, iIndex, m_tszText, MAX_PATH);
  57. // Calculate the rectangle for text
  58. RECT titlerc;
  59. m_TextRect = g_InfoWndRect;
  60. OffsetRect(&m_TextRect, -m_TextRect.left, -m_TextRect.top);
  61. InflateRect(&m_TextRect, -1, -1);
  62. titlerc = m_TextRect;
  63. HDC hDC = CreateCompatibleDC(NULL);
  64. if (hDC)
  65. {
  66. TCHAR tszResourceString[MAX_PATH];
  67. LoadString(g_hModule, IDS_INFO_TITLE, tszResourceString, MAX_PATH);
  68. DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX|DT_CALCRECT);
  69. m_TextRect.top = titlerc.bottom + 1;
  70. m_TextWinRect = m_TextRect;
  71. DrawText(hDC, m_tszText, -1, &m_TextRect, DT_CENTER|DT_NOPREFIX|DT_CALCRECT|DT_WORDBREAK);
  72. if (m_TextRect.bottom + 1 > g_InfoWndRect.bottom - g_InfoWndRect.top)
  73. {
  74. // Text too long. We need a scroll bar.
  75. m_TextRect.right -= m_nSBWidth;
  76. DrawText(hDC, m_tszText, -1, &m_TextRect, DT_CENTER|DT_NOPREFIX|DT_CALCRECT|DT_WORDBREAK);
  77. SetVertSB(TRUE);
  78. } else
  79. SetVertSB(FALSE);
  80. DeleteDC(hDC);
  81. }
  82. m_iCurIndex = iIndex;
  83. Invalidate();
  84. }
  85. void CFlexInfoBox::SetFont(HFONT hFont)
  86. {
  87. m_hFont = hFont;
  88. if (m_hWnd == NULL)
  89. return;
  90. Invalidate();
  91. }
  92. void CFlexInfoBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
  93. {
  94. m_rgbText = text;
  95. m_rgbBk = bk;
  96. m_rgbSelText = seltext;
  97. m_rgbSelBk = selbk;
  98. m_rgbFill = fill;
  99. m_rgbLine = line;
  100. m_VertSB.SetColors(m_rgbBk, m_rgbFill, m_rgbLine);
  101. Invalidate();
  102. }
  103. void CFlexInfoBox::SetRect()
  104. {
  105. if (m_hWnd == NULL)
  106. return;
  107. RECT rect = GetRect();
  108. SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
  109. }
  110. RECT CFlexInfoBox::GetRect(const RECT &rect)
  111. {
  112. int h = GetTextHeight(m_hFont);
  113. RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
  114. return ret;
  115. }
  116. RECT CFlexInfoBox::GetRect()
  117. {
  118. RECT rect;
  119. GetClientRect(&rect);
  120. return GetRect(rect);
  121. }
  122. void CFlexInfoBox::OnPaint(HDC hDC)
  123. {
  124. HDC hBDC = NULL, hODC = NULL;
  125. CBitmap *pbm = NULL;
  126. if (!InRenderMode())
  127. {
  128. hODC = hDC;
  129. pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
  130. if (pbm != NULL)
  131. {
  132. hBDC = pbm->BeginPaintInto();
  133. if (hBDC != NULL)
  134. {
  135. hDC = hBDC;
  136. }
  137. }
  138. }
  139. InternalPaint(hDC);
  140. if (!InRenderMode())
  141. {
  142. if (pbm != NULL)
  143. {
  144. if (hBDC != NULL)
  145. {
  146. pbm->EndPaintInto(hBDC);
  147. pbm->Draw(hODC);
  148. }
  149. delete pbm;
  150. }
  151. }
  152. }
  153. void CFlexInfoBox::InternalPaint(HDC hDC)
  154. {
  155. TCHAR tszResourceString[MAX_PATH];
  156. HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
  157. if (hPen != NULL)
  158. {
  159. HGDIOBJ hOldPen = SelectObject(hDC, hPen);
  160. HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
  161. if (hBrush != NULL)
  162. {
  163. HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
  164. RECT rect = {0,0,0,0}, titlerc;
  165. GetClientRect(&rect);
  166. titlerc = rect;
  167. Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
  168. InflateRect(&rect, -1, -1);
  169. SetBkMode(hDC, TRANSPARENT);
  170. LoadString(g_hModule, IDS_INFO_TITLE, tszResourceString, MAX_PATH);
  171. // Draw the message text
  172. SetTextColor(hDC, m_rgbText);
  173. rect = m_TextRect;
  174. // Offset the rectangle to account for scroll bar
  175. if (m_bVertSB)
  176. {
  177. OffsetRect(&rect, 0, -m_VertSB.GetPos());
  178. }
  179. DrawText(hDC, m_tszText, -1, &rect, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
  180. GetClientRect(&rect);
  181. InflateRect(&rect, -1, -1);
  182. SetTextColor(hDC, m_rgbLine); // User line color for Information title
  183. // Get the title area rantangle
  184. DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX|DT_CALCRECT);
  185. // Adjust right edge position to old value
  186. titlerc.right = rect.right + 1;
  187. // Draw a rectangle around the title area.
  188. Rectangle(hDC, titlerc.left, titlerc.top, titlerc.right, titlerc.bottom);
  189. // Draw title text (Information)
  190. DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX);
  191. SelectObject(hDC, hOldBrush);
  192. DeleteObject(hBrush);
  193. }
  194. SelectObject(hDC, hOldPen);
  195. DeleteObject(hPen);
  196. }
  197. }
  198. void CFlexInfoBox::SetVertSB(BOOL bSet)
  199. {
  200. if (!bSet && !m_bVertSB)
  201. return;
  202. m_bVertSB = bSet;
  203. if (m_hWnd == NULL)
  204. return;
  205. SetVertSB();
  206. }
  207. void CFlexInfoBox::SetVertSB()
  208. {
  209. if (m_bVertSB)
  210. {
  211. SetSBValues();
  212. SIZE client = GetClientSize();
  213. client.cy = m_TextWinRect.bottom - m_TextWinRect.top;
  214. SetWindowPos(m_VertSB.m_hWnd, NULL, client.cx - m_nSBWidth - 1, m_TextRect.top, m_nSBWidth, client.cy - 1, SWP_NOZORDER);
  215. }
  216. ShowWindow(m_VertSB.m_hWnd, m_bVertSB ? SW_SHOW : SW_HIDE);
  217. }
  218. void CFlexInfoBox::SetSBValues()
  219. {
  220. if (m_hWnd == NULL)
  221. return;
  222. m_VertSB.SetValues(0, m_TextRect.bottom - m_TextRect.top, m_TextWinRect.bottom - m_TextWinRect.top, 0);
  223. }
  224. void CFlexInfoBox::OnWheel(POINT point, WPARAM wParam)
  225. {
  226. if (!m_bVertSB) return;
  227. if (m_VertSB.GetMin() == m_VertSB.GetMax()) return;
  228. int nPage = MulDiv(m_VertSB.GetPage(), 9, 10) >> 1; // Half a page at a time
  229. if ((int)wParam >= 0)
  230. m_VertSB.AdjustPos(-nPage);
  231. else
  232. m_VertSB.AdjustPos(nPage);
  233. Invalidate();
  234. }
  235. LRESULT CFlexInfoBox::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  236. {
  237. switch (msg)
  238. {
  239. case WM_FLEXVSCROLL:
  240. {
  241. int code = (int)wParam;
  242. CFlexScrollBar *pSB = (CFlexScrollBar *)lParam;
  243. if (!pSB)
  244. return 0;
  245. int nLine = 1;
  246. int nPage = MulDiv(pSB->GetPage(), 9, 10);
  247. switch (code)
  248. {
  249. case SB_LINEUP: pSB->AdjustPos(-nLine); break;
  250. case SB_LINEDOWN: pSB->AdjustPos(nLine); break;
  251. case SB_PAGEUP: pSB->AdjustPos(-nPage); break;
  252. case SB_PAGEDOWN: pSB->AdjustPos(nPage); break;
  253. case SB_THUMBTRACK: pSB->SetPos(pSB->GetThumbPos()); break;
  254. case SB_ENDSCROLL:
  255. ::ReleaseCapture();
  256. break;
  257. }
  258. Invalidate();
  259. return 0;
  260. }
  261. default:
  262. if (msg == WM_LBUTTONDOWN)
  263. {
  264. HWND hWndParent;
  265. hWndParent = GetParent(hWnd);
  266. SendMessage(hWndParent, WM_UNHIGHLIGHT, 0, 0); // Send click message to page to unhighlight callout
  267. }
  268. return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
  269. }
  270. return 0;
  271. }