// ComboBoxExt.cpp : 实现文件 // #include "stdafx.h" #include "HJHomework.h" #include "ComboBoxExt.h" #include "CacheDC.h" extern void LoadImageFromResID(int id, CImageEx*& pImage); IMPLEMENT_DYNAMIC(CComboBoxExt, CWnd) CComboBoxExt::CComboBoxExt() { m_dwStyle = WS_CHILD | SS_NOTIFY; m_dwConfig = NULL; m_lpszIcon = L"res\\skin\\icon-drop.png"; m_font.CreatePointFont(100,L"微软雅黑"); m_lpszText = L""; m_bError = FALSE; } CComboBoxExt::~CComboBoxExt() { } BEGIN_MESSAGE_MAP(CComboBoxExt, CWnd) ON_WM_PAINT() ON_WM_CREATE() END_MESSAGE_MAP() // CComboBoxExt 消息处理程序 BOOL CComboBoxExt::Create( CWnd* pParentWnd , UINT nID , CRect& rect , LPCTSTR lpszText/* = NULL*/ , DWORD dwStyle/* = NULL*/ , ENUM_COMBOBOX_TYPE combo_type/* = COMBOBOX_SELECT*/ ) { // TODO: 在此添加专用代码和/或调用基类 m_lpszDefault = lpszText; m_dwStyle |= dwStyle; m_combo_type = combo_type; return CWnd::Create(L"STATIC", NULL, m_dwStyle, rect, pParentWnd, nID); } BOOL CComboBoxExt::Create( CWnd* pParentWnd , UINT nID , CPoint& point , CSize& size , LPCTSTR lpszText/* = NULL*/ , DWORD dwStyle/* = NULL*/ , ENUM_COMBOBOX_TYPE combo_type/* = COMBOBOX_SELECT*/ ) { // TODO: 在此添加专用代码和/或调用基类 return Create(pParentWnd, nID, CRect(point.x, point.y, point.x + size.cx, point.y + size.cy), lpszText, dwStyle,combo_type); } void CComboBoxExt::PreSubclassWindow() { // TODO: 在此添加专用代码和/或调用基类 CWnd::PreSubclassWindow(); } void SelectFolder(HWND hwnd, CString& lpszFolder) { TCHAR szFolderPath[MAX_PATH]; szFolderPath[0] = 0; BROWSEINFO sInfo; ::ZeroMemory(&sInfo, sizeof(BROWSEINFO)); sInfo.pidlRoot = 0; sInfo.lpszTitle = _T("请选择一个文件夹"); sInfo.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX; sInfo.lpfn = NULL; sInfo.hwndOwner = hwnd; LPITEMIDLIST lpidlBrowse = ::SHBrowseForFolder(&sInfo); if (lpidlBrowse != NULL){ if (::SHGetPathFromIDList(lpidlBrowse, szFolderPath)){ lpszFolder = szFolderPath; lpszFolder.Replace('\\', '/'); } ::CoTaskMemFree(lpidlBrowse); } } LRESULT CComboBoxExt::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: 在此添加专用代码和/或调用基类 switch(message) { case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_MOUSEMOVE: { CPoint point(GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam)); if(m_rcIconAction.PtInRect(point)) ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND)); if(message == WM_LBUTTONDOWN) { switch(m_combo_type) { case COMBOBOX_FOLDER: SelectFolder(this->GetSafeHwnd(),m_lpszText); m_bError = m_lpszText.GetLength() < 1; InvalidateRect(m_rcText,FALSE); break; case COMBOBOX_SELECT: if(GetCount() > 0) ShowDropDown(!GetDroppedState()); break; } }; } return 0L; case WM_COMBOBOX_SELCHANGE: OnCbnSelchange(); return 0L; } return CWnd::WindowProc(message, wParam, lParam); } void CComboBoxExt::OnPaint() { CPaintDC dc(this); GetClientRect(m_rcClient); CCacheDC pCacheDC(&dc,m_rcClient); pCacheDC->FillSolidRect(m_rcClient,RGB(255,255,255)); // 画背景 pCacheDC->FrameRect(m_rcClient,&CBrush(RGB(201,201,201))); // 画边框 // 绘制标准图标框和图标 CPen pen(PS_SOLID, 1, RGB(201,201,201)); // 创建一个画笔 CPen* pOldPen=pCacheDC->SelectObject(&pen); // 保存原始的CPen. pCacheDC->MoveTo(m_rcIconAction.left - 1, m_rcClient.top); // 移动到指定位置 pCacheDC->LineTo(m_rcIconAction.left - 1, m_rcClient.bottom); // 画直接到指定位置 m_pIcon->DrawImage(pCacheDC,m_rcIcon.left,m_rcIcon.top, m_rcIcon.Width(),m_rcIcon.Height(),0, 0); // 画文本 m_rcClient.left += 5; pCacheDC->SelectObject(m_font); pCacheDC->SetBkMode(TRANSPARENT); if(m_bError) { pCacheDC->SetTextColor(RGB(224,27,90)); pCacheDC->DrawText(m_lpszDefault,m_rcText,DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); } else { //pCacheDC->SetTextColor(RGB(150,150,150)); pCacheDC->SetTextColor(RGB(51,51,51)); if(m_lpszText.GetLength() < 1) pCacheDC->DrawText(m_lpszDefault,m_rcText,DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); else pCacheDC->DrawText(m_lpszText,m_rcText,DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS); } this->OnPaint(pCacheDC); } int CComboBoxExt::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; m_combobox.Create(this, 0x0010, CRect(0,0,lpCreateStruct->cx, lpCreateStruct->cy)); if(m_combo_type == COMBOBOX_FOLDER) LoadImageFromResID(IDB_PNG_ICON_SELECT, m_pIcon); else LoadImageFromResID(IDB_PNG_ICON_DROP, m_pIcon); GetClientRect(m_rcClient); // 获取控件大小 //m_pIcon = new CImageEx(m_lpszIcon); // 加载图标 UINT nIconHeight = m_pIcon->GetHeight(); // 图标高度 UINT nIconWidth = m_pIcon->GetWidth(); // 图标高度 UINT nIconMargins = (m_rcClient.Height() - nIconHeight) / 2; // 边距大小 // 设置图标位置 m_rcIcon.SetRect(m_rcClient.right - nIconMargins - nIconHeight , nIconMargins , m_rcClient.right - nIconMargins, nIconMargins + nIconHeight); m_rcIconAction.CopyRect(m_rcIcon); m_rcIconAction.InflateRect(nIconMargins,nIconMargins,nIconMargins,nIconMargins); // 设置文本的位置 m_rcText.SetRect(nIconMargins * 2, nIconMargins, m_rcIconAction.left - nIconMargins, m_rcClient.bottom - nIconMargins); // TODO: 在此添加您专用的创建代码 if(!InitComboBox()) return -1; return 0; } BOOL CComboBoxExt::InitComboBox() { return TRUE; } void CComboBoxExt::OnCbnSelchange() { if(m_combo_type != COMBOBOX_SELECT) return ; m_bError = FALSE; m_combobox.GetWindowText(m_lpszText); Invalidate(FALSE); int nSel = GetCurSel(); int nData = -1; if (nSel >=0 ) { nData = m_combobox.GetItemData(nSel); } GetParent()->PostMessage(WM_COMBOBOX_SELCHANGE, nData, (LPARAM)GetSafeHwnd()); } BOOL CComboBoxExt::GetValidate() { if(m_combo_type == COMBOBOX_FOLDER) m_bError = m_lpszText.GetLength() < 1; else m_bError = GetCount() <= 0; Invalidate(FALSE); return !m_bError; } void CComboBoxExt::GetWindowText(CString& rString) { rString = m_lpszText; } void CComboBoxExt::SetWindowText(CString rString) { m_lpszText = rString; } void CComboBoxExt::ResetContent() { if(m_combo_type != COMBOBOX_SELECT) return ; return m_combobox.ResetContent(); }; int CComboBoxExt::AddString(LPCTSTR lpszString) { if(m_combo_type != COMBOBOX_SELECT) return -1; return m_combobox.AddString(lpszString); }; void CComboBoxExt::Clear() { m_combobox.Clear(); } int CComboBoxExt::InsertString(int nIndex, LPCTSTR lpszString) { if(m_combo_type != COMBOBOX_SELECT) return -1; return m_combobox.InsertString(nIndex,lpszString); } int CComboBoxExt::SetItemDataPtr(int nIndex, void* pData) { if(m_combo_type != COMBOBOX_SELECT) return -1; return m_combobox.SetItemDataPtr(nIndex,pData); }; void* CComboBoxExt::GetItemDataPtr(int nIndex) const { if(m_combo_type != COMBOBOX_SELECT) return nullptr; return m_combobox.GetItemDataPtr(nIndex); }; int CComboBoxExt::SetItemData(int nIndex, DWORD_PTR dwItemData) { if(m_combo_type != COMBOBOX_SELECT) return -1; return m_combobox.SetItemData(nIndex,dwItemData); } DWORD_PTR CComboBoxExt::GetItemData(int nIndex) { if(m_combo_type != COMBOBOX_SELECT) return -1; return m_combobox.GetItemData(nIndex); } int CComboBoxExt::GetCount() const { if(m_combo_type != COMBOBOX_SELECT) return -1; return m_combobox.GetCount(); }; int CComboBoxExt::GetCurSel() const { if(m_combo_type != COMBOBOX_SELECT) return -1; return m_combobox.GetCurSel(); }; int CComboBoxExt::SetCurSel(int nSelect) { if(m_combo_type != COMBOBOX_SELECT) return -1; int index = m_combobox.SetCurSel(nSelect); m_combobox.GetWindowText(m_lpszText); InvalidateRect(m_rcText,FALSE); return index; } void CComboBoxExt::ShowDropDown(BOOL bShowIt/* = TRUE*/) { if(m_combo_type != COMBOBOX_SELECT) return ; m_combobox.ShowDropDown(bShowIt); } BOOL CComboBoxExt::GetDroppedState() const { if(m_combo_type != COMBOBOX_SELECT) return TRUE; return m_combobox.GetDroppedState(); }