PropertyGridCombo.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // PropertyGridCombo.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "PropertyGridCombo.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. static const int margin = 2;
  11. // CPropertyGridCombo
  12. IMPLEMENT_DYNCREATE(CPropertyGridCombo, CWnd)
  13. CPropertyGridCombo::CPropertyGridCombo()
  14. {
  15. m_pFont = NULL;
  16. m_nSelected = -1;
  17. m_bTracking = false;
  18. m_clrBack = GetSysColor(COLOR_WINDOW);
  19. m_clrText = GetSysColor(COLOR_WINDOWTEXT);
  20. m_clrFocus = GetSysColor(COLOR_HIGHLIGHT);
  21. m_clrHilite = GetSysColor(COLOR_HIGHLIGHTTEXT);
  22. }
  23. CPropertyGridCombo::~CPropertyGridCombo()
  24. {
  25. }
  26. //
  27. // content management
  28. //
  29. void CPropertyGridCombo::AddString(string strItem)
  30. {
  31. m_Items.push_back(strItem);
  32. }
  33. void CPropertyGridCombo::SetCurSel(int nItem)
  34. {
  35. m_nSelected = nItem;
  36. }
  37. BEGIN_MESSAGE_MAP(CPropertyGridCombo, CWnd)
  38. ON_WM_PAINT()
  39. ON_WM_SHOWWINDOW()
  40. ON_WM_LBUTTONDOWN()
  41. ON_WM_MOUSEMOVE()
  42. ON_WM_LBUTTONUP()
  43. ON_WM_DESTROY()
  44. ON_WM_KILLFOCUS()
  45. ON_WM_KEYDOWN()
  46. ON_WM_GETDLGCODE()
  47. END_MESSAGE_MAP()
  48. //
  49. // creation
  50. //
  51. BOOL CPropertyGridCombo::Create(DWORD dwStyle, CRect& rc, CWnd* pParent, int nId)
  52. {
  53. pParent->ClientToScreen(&rc);
  54. BOOL ret = CWnd::CreateEx(0, AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW), "", dwStyle|WS_POPUP, rc, pParent->GetParent(), nId);
  55. if (ret) SetOwner(pParent);
  56. return ret;
  57. }
  58. void CPropertyGridCombo::SetFont(CFont* pFont, BOOL bRedraw)
  59. {
  60. m_pFont = pFont;
  61. CWnd::SetFont(pFont, bRedraw);
  62. }
  63. void CPropertyGridCombo::SetColors(COLORREF clrBack, COLORREF clrText, COLORREF clrFocus, COLORREF clrHilite)
  64. {
  65. m_clrBack = clrBack;
  66. m_clrText = clrText;
  67. m_clrFocus = clrFocus;
  68. m_clrHilite = clrHilite;
  69. }
  70. void CPropertyGridCombo::OnShowWindow(BOOL bShow, UINT nStatus)
  71. {
  72. if (bShow)
  73. {
  74. // get line height
  75. CDC* pDC = GetDC();
  76. int save = pDC->SaveDC();
  77. pDC->SelectObject(m_pFont?m_pFont:GetFont());
  78. m_line_height = pDC->GetTextExtent("Gg").cy + 2*margin;
  79. pDC->RestoreDC(save);
  80. ReleaseDC(pDC);
  81. // size control
  82. CRect rc;
  83. GetWindowRect(&rc);
  84. SetWindowPos(NULL, 0, 0, rc.Width(), int(m_Items.size())*m_line_height+2, SWP_NOOWNERZORDER|SWP_NOZORDER|SWP_NOMOVE);
  85. SetFocus();
  86. }
  87. CWnd::OnShowWindow(bShow, nStatus);
  88. }
  89. void CPropertyGridCombo::OnDestroy()
  90. {
  91. CWnd::OnDestroy();
  92. }
  93. void CPropertyGridCombo::OnKillFocus(CWnd* pNewWnd)
  94. {
  95. CWnd::OnKillFocus(pNewWnd);
  96. DestroyWindow();
  97. }
  98. //
  99. // painting
  100. //
  101. void CPropertyGridCombo::OnPaint()
  102. {
  103. // check
  104. if (m_nSelected<0) m_nSelected = 0;
  105. if (m_nSelected>int(m_Items.size())-1) m_nSelected = int(m_Items.size())-1;
  106. // client rect
  107. CRect rc;
  108. GetClientRect(&rc);
  109. // brush
  110. CBrush brush;
  111. brush.CreateSolidBrush(m_clrBack);
  112. // pen
  113. CPen pen;
  114. pen.CreatePen(PS_SOLID, 1, m_clrText);
  115. // the dc
  116. CPaintDC dc(this);
  117. CBrush* pOldBrush = dc.SelectObject(&brush);
  118. CPen* pOldPen = dc.SelectObject(&pen);
  119. CFont* pOldFont = dc.SelectObject(m_pFont);
  120. // draw
  121. dc.SelectObject(&brush);
  122. dc.SelectObject(&pen);
  123. dc.Rectangle(rc);
  124. // put items
  125. int i = 0;
  126. int y = 1;
  127. dc.SelectObject(m_pFont);
  128. dc.SetBkMode(TRANSPARENT);
  129. for (vector<string>::iterator it = m_Items.begin(); it != m_Items.end(); ++it)
  130. {
  131. CRect rcItem(0, y, rc.Width(), y+m_line_height);
  132. rcItem.DeflateRect(1,0,1,0);
  133. if (i == m_nSelected)
  134. {
  135. dc.DrawFocusRect(rcItem);
  136. dc.SetTextColor(m_clrHilite);
  137. CRect rc = rcItem;
  138. rc.DeflateRect(1,1);
  139. dc.FillSolidRect(rc, m_clrFocus);
  140. }
  141. else
  142. {
  143. dc.SetTextColor(m_clrText);
  144. }
  145. // do it
  146. rcItem.left += 2*margin;
  147. dc.DrawText(it->c_str(), rcItem, DT_SINGLELINE|DT_VCENTER|DT_LEFT|DT_NOPREFIX);
  148. y += m_line_height;
  149. i++;
  150. }
  151. // clean up
  152. dc.SelectObject(pOldFont);
  153. dc.SelectObject(pOldPen);
  154. dc.SelectObject(pOldBrush);
  155. }
  156. //
  157. // mouse interaction
  158. //
  159. void CPropertyGridCombo::OnLButtonDown(UINT nFlags, CPoint point)
  160. {
  161. m_nSelected = point.y/m_line_height;
  162. m_bTracking = true;
  163. SetCapture();
  164. Invalidate();
  165. CWnd::OnLButtonDown(nFlags, point);
  166. }
  167. void CPropertyGridCombo::OnMouseMove(UINT nFlags, CPoint point)
  168. {
  169. if (m_bTracking)
  170. {
  171. m_nSelected = point.y/m_line_height;
  172. Invalidate();
  173. }
  174. CWnd::OnMouseMove(nFlags, point);
  175. }
  176. void CPropertyGridCombo::OnLButtonUp(UINT nFlags, CPoint point)
  177. {
  178. if (m_bTracking)
  179. {
  180. ReleaseCapture();
  181. m_bTracking = false;
  182. Invalidate();
  183. }
  184. GetOwner()->SendMessage(WM_PG_COMBOSELCHANGED, m_nSelected, 0);
  185. }
  186. //
  187. // keyboard interaction
  188. //
  189. UINT CPropertyGridCombo::OnGetDlgCode()
  190. {
  191. return DLGC_WANTALLKEYS;
  192. }
  193. void CPropertyGridCombo::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  194. {
  195. if (nChar == VK_LEFT || nChar == VK_UP)
  196. {
  197. m_nSelected = max(0, m_nSelected-1);
  198. Invalidate();
  199. }
  200. else if (nChar == VK_RIGHT || nChar == VK_DOWN)
  201. {
  202. m_nSelected = min(int(m_Items.size())-1, m_nSelected+1);
  203. Invalidate();
  204. }
  205. else if (nChar == VK_ESCAPE)
  206. {
  207. DestroyWindow();
  208. return;
  209. }
  210. else if (nChar == VK_RETURN || nChar == VK_EXECUTE)
  211. {
  212. GetOwner()->SendMessage(WM_PG_COMBOSELCHANGED, m_nSelected, 0);
  213. return;
  214. }
  215. CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  216. }