ComboBoxExt.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. // ComboBoxExt.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "HJHomework.h"
  5. #include "ComboBoxExt.h"
  6. #include "CacheDC.h"
  7. extern void LoadImageFromResID(int id, CImageEx*& pImage);
  8. IMPLEMENT_DYNAMIC(CComboBoxExt, CWnd)
  9. CComboBoxExt::CComboBoxExt()
  10. {
  11. m_dwStyle = WS_CHILD | SS_NOTIFY;
  12. m_dwConfig = NULL;
  13. m_lpszIcon = L"res\\skin\\icon-drop.png";
  14. m_font.CreatePointFont(100,L"微软雅黑");
  15. m_lpszText = L"";
  16. m_bError = FALSE;
  17. }
  18. CComboBoxExt::~CComboBoxExt()
  19. {
  20. }
  21. BEGIN_MESSAGE_MAP(CComboBoxExt, CWnd)
  22. ON_WM_PAINT()
  23. ON_WM_CREATE()
  24. END_MESSAGE_MAP()
  25. // CComboBoxExt 消息处理程序
  26. BOOL CComboBoxExt::Create(
  27. CWnd* pParentWnd
  28. , UINT nID
  29. , CRect& rect
  30. , LPCTSTR lpszText/* = NULL*/
  31. , DWORD dwStyle/* = NULL*/
  32. , ENUM_COMBOBOX_TYPE combo_type/* = COMBOBOX_SELECT*/
  33. )
  34. {
  35. // TODO: 在此添加专用代码和/或调用基类
  36. m_lpszDefault = lpszText;
  37. m_dwStyle |= dwStyle;
  38. m_combo_type = combo_type;
  39. return CWnd::Create(L"STATIC", NULL, m_dwStyle, rect, pParentWnd, nID);
  40. }
  41. BOOL CComboBoxExt::Create(
  42. CWnd* pParentWnd
  43. , UINT nID
  44. , CPoint& point
  45. , CSize& size
  46. , LPCTSTR lpszText/* = NULL*/
  47. , DWORD dwStyle/* = NULL*/
  48. , ENUM_COMBOBOX_TYPE combo_type/* = COMBOBOX_SELECT*/
  49. )
  50. {
  51. // TODO: 在此添加专用代码和/或调用基类
  52. return Create(pParentWnd, nID, CRect(point.x, point.y, point.x + size.cx, point.y + size.cy), lpszText, dwStyle,combo_type);
  53. }
  54. void CComboBoxExt::PreSubclassWindow()
  55. {
  56. // TODO: 在此添加专用代码和/或调用基类
  57. CWnd::PreSubclassWindow();
  58. }
  59. void SelectFolder(HWND hwnd, CString& lpszFolder)
  60. {
  61. TCHAR szFolderPath[MAX_PATH];
  62. szFolderPath[0] = 0;
  63. BROWSEINFO sInfo;
  64. ::ZeroMemory(&sInfo, sizeof(BROWSEINFO));
  65. sInfo.pidlRoot = 0;
  66. sInfo.lpszTitle = _T("请选择一个文件夹");
  67. sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
  68. sInfo.lpfn = NULL;
  69. sInfo.hwndOwner = hwnd;
  70. LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo);
  71. if (lpidlBrowse != NULL){
  72. if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath)){
  73. lpszFolder = szFolderPath;
  74. lpszFolder.Replace('\\', '/');
  75. }
  76. ::CoTaskMemFree(lpidlBrowse);
  77. }
  78. }
  79. LRESULT CComboBoxExt::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  80. {
  81. // TODO: 在此添加专用代码和/或调用基类
  82. switch(message)
  83. {
  84. case WM_LBUTTONDOWN:
  85. case WM_LBUTTONUP:
  86. case WM_LBUTTONDBLCLK:
  87. case WM_MOUSEMOVE:
  88. {
  89. CPoint point(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam));
  90. if(m_rcIconAction.PtInRect(point))
  91. ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND));
  92. if(message == WM_LBUTTONDOWN)
  93. {
  94. switch(m_combo_type)
  95. {
  96. case COMBOBOX_FOLDER:
  97. SelectFolder(this->GetSafeHwnd(),m_lpszText);
  98. m_bError = m_lpszText.GetLength() < 1;
  99. InvalidateRect(m_rcText,FALSE);
  100. break;
  101. case COMBOBOX_SELECT:
  102. if(GetCount() > 0)
  103. ShowDropDown(!GetDroppedState());
  104. break;
  105. }
  106. };
  107. }
  108. return 0L;
  109. case WM_COMBOBOX_SELCHANGE:
  110. OnCbnSelchange();
  111. return 0L;
  112. }
  113. return CWnd::WindowProc(message, wParam, lParam);
  114. }
  115. void CComboBoxExt::OnPaint()
  116. {
  117. CPaintDC dc(this);
  118. GetClientRect(m_rcClient);
  119. CCacheDC pCacheDC(&dc,m_rcClient);
  120. pCacheDC->FillSolidRect(m_rcClient,RGB(255,255,255)); // 画背景
  121. pCacheDC->FrameRect(m_rcClient,&CBrush(RGB(201,201,201))); // 画边框
  122. // 绘制标准图标框和图标
  123. CPen pen(PS_SOLID, 1, RGB(201,201,201)); // 创建一个画笔
  124. CPen* pOldPen=pCacheDC->SelectObject(&pen); // 保存原始的CPen.
  125. pCacheDC->MoveTo(m_rcIconAction.left - 1, m_rcClient.top); // 移动到指定位置
  126. pCacheDC->LineTo(m_rcIconAction.left - 1, m_rcClient.bottom); // 画直接到指定位置
  127. m_pIcon->DrawImage(pCacheDC,m_rcIcon.left,m_rcIcon.top, m_rcIcon.Width(),m_rcIcon.Height(),0, 0);
  128. // 画文本
  129. m_rcClient.left += 5;
  130. pCacheDC->SelectObject(m_font);
  131. pCacheDC->SetBkMode(TRANSPARENT);
  132. if(m_bError)
  133. {
  134. pCacheDC->SetTextColor(RGB(224,27,90));
  135. pCacheDC->DrawText(m_lpszDefault,m_rcText,DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
  136. }
  137. else
  138. {
  139. //pCacheDC->SetTextColor(RGB(150,150,150));
  140. pCacheDC->SetTextColor(RGB(51,51,51));
  141. if(m_lpszText.GetLength() < 1)
  142. pCacheDC->DrawText(m_lpszDefault,m_rcText,DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
  143. else
  144. pCacheDC->DrawText(m_lpszText,m_rcText,DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS);
  145. }
  146. this->OnPaint(pCacheDC);
  147. }
  148. int CComboBoxExt::OnCreate(LPCREATESTRUCT lpCreateStruct)
  149. {
  150. if (CWnd::OnCreate(lpCreateStruct) == -1)
  151. return -1;
  152. m_combobox.Create(this, 0x0010, CRect(0,0,lpCreateStruct->cx, lpCreateStruct->cy));
  153. if(m_combo_type == COMBOBOX_FOLDER)
  154. LoadImageFromResID(IDB_PNG_ICON_SELECT, m_pIcon);
  155. else
  156. LoadImageFromResID(IDB_PNG_ICON_DROP, m_pIcon);
  157. GetClientRect(m_rcClient); // 获取控件大小
  158. //m_pIcon = new CImageEx(m_lpszIcon); // 加载图标
  159. UINT nIconHeight = m_pIcon->GetHeight(); // 图标高度
  160. UINT nIconWidth = m_pIcon->GetWidth(); // 图标高度
  161. UINT nIconMargins = (m_rcClient.Height() - nIconHeight) / 2; // 边距大小
  162. // 设置图标位置
  163. m_rcIcon.SetRect(m_rcClient.right - nIconMargins - nIconHeight , nIconMargins , m_rcClient.right - nIconMargins, nIconMargins + nIconHeight);
  164. m_rcIconAction.CopyRect(m_rcIcon);
  165. m_rcIconAction.InflateRect(nIconMargins,nIconMargins,nIconMargins,nIconMargins);
  166. // 设置文本的位置
  167. m_rcText.SetRect(nIconMargins * 2, nIconMargins, m_rcIconAction.left - nIconMargins, m_rcClient.bottom - nIconMargins);
  168. // TODO: 在此添加您专用的创建代码
  169. if(!InitComboBox())
  170. return -1;
  171. return 0;
  172. }
  173. BOOL CComboBoxExt::InitComboBox()
  174. {
  175. return TRUE;
  176. }
  177. void CComboBoxExt::OnCbnSelchange()
  178. {
  179. if(m_combo_type != COMBOBOX_SELECT)
  180. return ;
  181. m_bError = FALSE;
  182. m_combobox.GetWindowText(m_lpszText);
  183. Invalidate(FALSE);
  184. int nSel = GetCurSel();
  185. int nData = -1;
  186. if (nSel >=0 )
  187. {
  188. nData = m_combobox.GetItemData(nSel);
  189. }
  190. GetParent()->PostMessage(WM_COMBOBOX_SELCHANGE, nData, (LPARAM)GetSafeHwnd());
  191. }
  192. BOOL CComboBoxExt::GetValidate()
  193. {
  194. if(m_combo_type == COMBOBOX_FOLDER)
  195. m_bError = m_lpszText.GetLength() < 1;
  196. else
  197. m_bError = GetCount() <= 0;
  198. Invalidate(FALSE);
  199. return !m_bError;
  200. }
  201. void CComboBoxExt::GetWindowText(CString& rString)
  202. {
  203. rString = m_lpszText;
  204. }
  205. void CComboBoxExt::SetWindowText(CString rString)
  206. {
  207. m_lpszText = rString;
  208. }
  209. void CComboBoxExt::ResetContent()
  210. {
  211. if(m_combo_type != COMBOBOX_SELECT)
  212. return ;
  213. return m_combobox.ResetContent();
  214. };
  215. int CComboBoxExt::AddString(LPCTSTR lpszString)
  216. {
  217. if(m_combo_type != COMBOBOX_SELECT)
  218. return -1;
  219. return m_combobox.AddString(lpszString);
  220. };
  221. void CComboBoxExt::Clear()
  222. {
  223. m_combobox.Clear();
  224. }
  225. int CComboBoxExt::InsertString(int nIndex, LPCTSTR lpszString)
  226. {
  227. if(m_combo_type != COMBOBOX_SELECT)
  228. return -1;
  229. return m_combobox.InsertString(nIndex,lpszString);
  230. }
  231. int CComboBoxExt::SetItemDataPtr(int nIndex, void* pData)
  232. {
  233. if(m_combo_type != COMBOBOX_SELECT)
  234. return -1;
  235. return m_combobox.SetItemDataPtr(nIndex,pData);
  236. };
  237. void* CComboBoxExt::GetItemDataPtr(int nIndex) const
  238. {
  239. if(m_combo_type != COMBOBOX_SELECT)
  240. return nullptr;
  241. return m_combobox.GetItemDataPtr(nIndex);
  242. };
  243. int CComboBoxExt::SetItemData(int nIndex, DWORD_PTR dwItemData)
  244. {
  245. if(m_combo_type != COMBOBOX_SELECT)
  246. return -1;
  247. return m_combobox.SetItemData(nIndex,dwItemData);
  248. }
  249. DWORD_PTR CComboBoxExt::GetItemData(int nIndex)
  250. {
  251. if(m_combo_type != COMBOBOX_SELECT)
  252. return -1;
  253. return m_combobox.GetItemData(nIndex);
  254. }
  255. int CComboBoxExt::GetCount() const
  256. {
  257. if(m_combo_type != COMBOBOX_SELECT)
  258. return -1;
  259. return m_combobox.GetCount();
  260. };
  261. int CComboBoxExt::GetCurSel() const
  262. {
  263. if(m_combo_type != COMBOBOX_SELECT)
  264. return -1;
  265. return m_combobox.GetCurSel();
  266. };
  267. int CComboBoxExt::SetCurSel(int nSelect)
  268. {
  269. if(m_combo_type != COMBOBOX_SELECT)
  270. return -1;
  271. int index = m_combobox.SetCurSel(nSelect);
  272. m_combobox.GetWindowText(m_lpszText);
  273. InvalidateRect(m_rcText,FALSE);
  274. return index;
  275. }
  276. void CComboBoxExt::ShowDropDown(BOOL bShowIt/* = TRUE*/)
  277. {
  278. if(m_combo_type != COMBOBOX_SELECT)
  279. return ;
  280. m_combobox.ShowDropDown(bShowIt);
  281. }
  282. BOOL CComboBoxExt::GetDroppedState() const
  283. {
  284. if(m_combo_type != COMBOBOX_SELECT)
  285. return TRUE;
  286. return m_combobox.GetDroppedState();
  287. }