InfobarCtrl.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /****************************************************************/
  2. /* */
  3. /* InfobarCtrl.cpp */
  4. /* */
  5. /* Implementation of the CInfobarCtrl class. */
  6. /* This class imitates the outlook infobar. */
  7. /* */
  8. /* Programmed by LYFZ van der Meer */
  9. /* Copyright LYFZ Software Solutions 2002 */
  10. /* http://www.LYFZvandermeer.nl */
  11. /* */
  12. /* Last updated: 10 july 2002 */
  13. /* */
  14. /****************************************************************/
  15. #include "stdafx.h"
  16. #include "resource.h"
  17. #include "InfobarCtrl.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. CInfobarCtrl::CInfobarCtrl()
  24. {
  25. m_bMouseInButton = FALSE;
  26. m_bMouseDown = FALSE;
  27. }
  28. CInfobarCtrl::~CInfobarCtrl()
  29. {
  30. }
  31. BEGIN_MESSAGE_MAP(CInfobarCtrl, CStatic)
  32. //{{AFX_MSG_MAP(CInfobarCtrl)
  33. ON_WM_PAINT()
  34. ON_WM_MOUSEMOVE()
  35. ON_WM_TIMER()
  36. ON_WM_LBUTTONDOWN()
  37. ON_WM_LBUTTONUP()
  38. //}}AFX_MSG_MAP
  39. END_MESSAGE_MAP()
  40. /********************************************************************/
  41. /* */
  42. /* Function name : OnPaint */
  43. /* Description : This is where all the painting of our control */
  44. /* takes place. */
  45. /* */
  46. /********************************************************************/
  47. void CInfobarCtrl::OnPaint()
  48. {
  49. CPaintDC dc(this); // device context for painting
  50. CDC memDC;
  51. CBitmap memBitmap;
  52. CBitmap* pOldBitmap;
  53. CRect rcClient;
  54. GetClientRect(&rcClient);
  55. // to avoid flicker, establish a memory dc, draw to it and then BitBlt it to the client
  56. memDC.CreateCompatibleDC(&dc);
  57. memBitmap.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
  58. pOldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap);
  59. // paint background
  60. memDC.FillSolidRect(rcClient, GetSysColor(COLOR_3DSHADOW));
  61. // select font
  62. CFont* pOldFont = (CFont*)memDC.SelectObject(&m_TextFont);
  63. COLORREF oldTextColor;
  64. int nBkMode = memDC.SetBkMode(TRANSPARENT);
  65. // set text color to white
  66. oldTextColor = memDC.SetTextColor(RGB(255,255,255));
  67. CRect rcItem = m_rcButton;
  68. if (rcItem.right >= rcClient.right)
  69. rcItem.right = rcClient.right-1;
  70. if (m_bMouseInButton)
  71. {
  72. if (m_bMouseDown)
  73. memDC.Draw3dRect(rcItem, RGB(0,0,0), RGB(255,255,255));
  74. else
  75. memDC.Draw3dRect(rcItem, RGB(255,255,255), RGB(0,0,0));
  76. }
  77. rcItem.DeflateRect(5, 0);
  78. rcItem.right -= 12;
  79. // draw text
  80. ::DrawTextEx(memDC.m_hDC,
  81. m_strText.GetBuffer (0),
  82. m_strText.GetLength(),
  83. &rcItem,
  84. DT_SINGLELINE | DT_VCENTER | DT_LEFT | DT_PATH_ELLIPSIS,
  85. NULL);
  86. // draw a arrow
  87. rcItem.right += 12;
  88. rcItem.left = rcItem.right-8;
  89. rcItem.top += rcItem.Height() / 2 - 1;
  90. CPoint pt[3];
  91. pt[0] = rcItem.TopLeft();
  92. pt[1] = CPoint(rcItem.right, rcItem.top);
  93. pt[2] = CPoint(rcItem.left + rcItem.Width()/2, rcItem.top + rcItem.Width()/2);
  94. memDC.SelectStockObject(WHITE_BRUSH);
  95. memDC.SelectStockObject(NULL_PEN);
  96. memDC.Polygon(pt, 3);
  97. // finally send the result to the display
  98. dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
  99. // restore old values
  100. memDC.SelectObject(pOldFont);
  101. memDC.SetTextColor(oldTextColor);
  102. memDC.SetBkMode(nBkMode);
  103. memDC.SelectObject(pOldBitmap);
  104. }
  105. /********************************************************************/
  106. /* */
  107. /* Function name : OnLButtonDown */
  108. /* Description : Handle WM_LBUTTONDOWN message */
  109. /* */
  110. /********************************************************************/
  111. void CInfobarCtrl::OnLButtonDown(UINT nFlags, CPoint point)
  112. {
  113. if (m_bMouseInButton)
  114. {
  115. if (!m_bMouseDown)
  116. m_bMouseDown = TRUE;
  117. Invalidate();
  118. }
  119. CStatic::OnLButtonDown(nFlags, point);
  120. }
  121. /********************************************************************/
  122. /* */
  123. /* Function name : OnLButtonUp */
  124. /* Description : Handle WM_LBUTTONUP message */
  125. /* */
  126. /********************************************************************/
  127. void CInfobarCtrl::OnLButtonUp(UINT nFlags, CPoint point)
  128. {
  129. if (m_bMouseInButton)
  130. {
  131. int bOldMode = m_bMouseInButton;
  132. if (m_rcButton.PtInRect(point))
  133. m_bMouseInButton = TRUE;
  134. else
  135. m_bMouseInButton = FALSE;
  136. if (m_bMouseDown)
  137. {
  138. m_bMouseDown = FALSE;
  139. if (m_bMouseInButton == bOldMode)
  140. {
  141. Invalidate();
  142. // do something ...
  143. if (m_bMouseInButton)
  144. {
  145. Invalidate();
  146. // load and display popup menu
  147. CMenu menu;
  148. menu.LoadMenu(IDR_INFOBARMENU);
  149. CMenu* pPopup = menu.GetSubMenu(0);
  150. CRect rect;
  151. GetWindowRect(rect);
  152. // show and track the menu
  153. DWORD dwID = pPopup->TrackPopupMenu((TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD),
  154. rect.left, rect.bottom, this);
  155. GetParent()->SendMessage(WM_COMMAND, dwID);
  156. }
  157. }
  158. else
  159. {
  160. m_bMouseInButton = FALSE;
  161. Invalidate();
  162. }
  163. }
  164. }
  165. CStatic::OnLButtonUp(nFlags, point);
  166. }
  167. /********************************************************************/
  168. /* */
  169. /* Function name : OnMouseMove */
  170. /* Description : Handle WM_MOUSEMOVE message */
  171. /* */
  172. /********************************************************************/
  173. void CInfobarCtrl::OnMouseMove(UINT nFlags, CPoint point)
  174. {
  175. if (nFlags & MK_LBUTTON)
  176. m_bMouseDown = TRUE;
  177. else
  178. m_bMouseDown = FALSE;
  179. BOOL bOldState = m_bMouseInButton;
  180. if (m_rcButton.PtInRect(point))
  181. m_bMouseInButton = TRUE;
  182. else
  183. m_bMouseInButton = FALSE;
  184. if (m_bMouseInButton != bOldState)
  185. {
  186. Invalidate(FALSE);
  187. KillTimer(1);
  188. SetTimer(1,10,NULL);
  189. }
  190. CStatic::OnMouseMove(nFlags, point);
  191. }
  192. /********************************************************************/
  193. /* */
  194. /* Function name : OnTimer */
  195. /* Description : Handle WM_TIMER message -> process timer */
  196. /* */
  197. /********************************************************************/
  198. void CInfobarCtrl::OnTimer(UINT nIDEvent)
  199. {
  200. if (nIDEvent == 1)
  201. {
  202. CPoint pt;
  203. if (!GetCursorPos(&pt))
  204. return;
  205. ScreenToClient(&pt);
  206. CRect rcClient;
  207. GetClientRect(&rcClient);
  208. rcClient.bottom = rcClient.top + 22;
  209. if (!rcClient.PtInRect(pt))
  210. {
  211. KillTimer(1);
  212. m_bMouseInButton = FALSE;
  213. m_bMouseDown = FALSE;
  214. Invalidate();
  215. }
  216. }
  217. CStatic::OnTimer(nIDEvent);
  218. }
  219. /********************************************************************/
  220. /* */
  221. /* Function name : SetText */
  222. /* Description : Set text of the control */
  223. /* */
  224. /********************************************************************/
  225. void CInfobarCtrl::SetText(LPCTSTR lpszText)
  226. {
  227. m_strText = lpszText;
  228. CClientDC dc(this);
  229. CFont* pFont = (CFont*)dc.SelectObject(&m_TextFont);
  230. CRect rcClient;
  231. GetClientRect(&rcClient);
  232. // calculate new button rect
  233. CSize size = dc.GetTextExtent(m_strText);
  234. size.cx += 22;
  235. size.cy = rcClient.Height()-2;
  236. m_rcButton = CRect(CPoint(1, 1), size);
  237. dc.SelectObject(pFont);
  238. Invalidate();
  239. }
  240. /********************************************************************/
  241. /* */
  242. /* Function name : PreSubclassWindow */
  243. /* Description : Initialize control variables */
  244. /* */
  245. /********************************************************************/
  246. void CInfobarCtrl::PreSubclassWindow()
  247. {
  248. m_TextFont.CreateFont(16, 0,0,0,FW_BOLD, 0,0,0,
  249. DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
  250. DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial");
  251. CStatic::PreSubclassWindow();
  252. }