先看看效果
頭文件:
#pragma once #include <atlimage.h> // CAddressComboBox class CAddressComboBox : public CComboBox { DECLARE_DYNAMIC(CAddressComboBox) public: CAddressComboBox(); virtual ~CAddressComboBox(); protected: DECLARE_MESSAGE_MAP() afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnPaint(); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam); afx_msg void OnCbnSelchange(); public: virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); virtual void MeasureItem(LPMEASUREITEMSTRUCT /*lpMeasureItemStruct*/); public: int AddString(LPCTSTR lpszString, HICON hIcon); private: CImage m_imgComboBox; CImage m_imgComboBoxThump; CImage m_imgMinClose; BOOL m_bIsThumpHover; BOOL m_bIsThumpDown; CListBox* m_pListBox; HICON m_hIcon; };
源文件:
// AddressComboBox.cpp : 實現文件 // #include "stdafx.h" #include "Frame.h" #include "AddressComboBox.h" #include "resource.h" // CAddressComboBox IMPLEMENT_DYNAMIC(CAddressComboBox, CComboBox) CAddressComboBox::CAddressComboBox() { m_bIsThumpHover = FALSE; m_bIsThumpDown = FALSE; } CAddressComboBox::~CAddressComboBox() { } BEGIN_MESSAGE_MAP(CAddressComboBox, CComboBox) ON_WM_SIZE() ON_WM_CREATE() ON_WM_PAINT() ON_WM_MOUSEMOVE() ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover) ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) ON_CONTROL_REFLECT(CBN_SELCHANGE, &CAddressComboBox::OnCbnSelchange) END_MESSAGE_MAP() // CAddressComboBox 消息處理程序 void CAddressComboBox::OnSize(UINT nType, int cx, int cy) { CComboBox::OnSize(nType, cx, cy); COMBOBOXINFO comboBoxInfo; comboBoxInfo.cbSize = sizeof(COMBOBOXINFO); GetComboBoxInfo(&comboBoxInfo); CRect rcEdit; rcEdit.left = 22; rcEdit.right = comboBoxInfo.rcItem.right; rcEdit.top = 5; rcEdit.bottom = 23; ::MoveWindow(comboBoxInfo.hwndItem, rcEdit.left, rcEdit.top, rcEdit.Width(), rcEdit.Height(), TRUE); } void CAddressComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { HDC hDC = lpDrawItemStruct->hDC; int nItem = lpDrawItemStruct->itemID; CRect rcItem = lpDrawItemStruct->rcItem; HICON hIcon = (HICON)lpDrawItemStruct->itemData; if (hIcon) { DrawIconEx(hDC, 1, rcItem.top, hIcon, 16, 16, 0, 0, DI_NORMAL); } if (nItem != CB_ERR) { COLORREF clrBackground; COLORREF clrText; CRect rcText = rcItem; rcText.left = 18; if (lpDrawItemStruct->itemState & ODS_SELECTED) //如果當前項被選中 { clrBackground = ::GetSysColor(COLOR_HIGHLIGHT); clrText = ~::GetSysColor(COLOR_WINDOWTEXT) & 0x00FFFFFF; } else { clrBackground = ::GetSysColor(COLOR_WINDOW); clrText = ::GetSysColor(COLOR_WINDOWTEXT); } ::SetTextColor(hDC, clrText); ::SetBkColor(hDC, clrBackground); ::ExtTextOut(hDC, 0, 0, ETO_OPAQUE, rcText, NULL, 0, NULL); CString strItem; GetLBText(nItem, strItem); DrawText(hDC, strItem, strItem.GetLength(), rcText, DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_WORD_ELLIPSIS); } } void CAddressComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { lpMeasureItemStruct->itemHeight = 18; } int CAddressComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CComboBox::OnCreate(lpCreateStruct) == -1) return -1; SetItemHeight(-1, 22); if (!m_imgComboBox.IsNull()) return 0; if (!m_imgComboBoxThump.IsNull()) return 0; m_imgComboBox.LoadFromResource(AfxGetInstanceHandle(), IDB_COMBOBOX); m_imgComboBoxThump.LoadFromResource(AfxGetInstanceHandle(), IDB_COMBOBOX_THUMP); return 0; } void CAddressComboBox::OnPaint() { CPaintDC dc(this); // device context for painting if (m_imgComboBox.IsNull()) return; if (m_imgComboBoxThump.IsNull()) return; CRect rcComboBox; GetClientRect(&rcComboBox); // 畫左邊 CRect rcComboLeft = rcComboBox; rcComboLeft.right = 10; m_imgComboBox.Draw(dc.m_hDC, rcComboLeft, CRect(0,0,10,28)); // 畫上邊 CRect rcComboTop = rcComboBox; rcComboTop.left = 10; rcComboTop.top = 0; rcComboTop.bottom = 4; m_imgComboBox.Draw(dc.m_hDC, rcComboTop, CRect(10,0,20,4)); // 畫下邊 CRect rcComboBottom = rcComboBox; rcComboBottom.left = 10; rcComboBottom.top = 24; rcComboBottom.bottom = 28; m_imgComboBox.Draw(dc.m_hDC, rcComboBottom, CRect(10,24,20,28)); // 繪制右邊的箭頭 COMBOBOXINFO comboBoxInfo; comboBoxInfo.cbSize = sizeof(COMBOBOXINFO); GetComboBoxInfo(&comboBoxInfo); CRect rcComboThump = comboBoxInfo.rcButton; rcComboThump = comboBoxInfo.rcButton; rcComboThump.left -= 4; rcComboThump.right = rcComboThump.left + 18; rcComboThump.top = 4; rcComboThump.bottom = 22; if (m_bIsThumpHover) { if (m_bIsThumpDown) { m_imgComboBoxThump.Draw(dc.m_hDC, rcComboThump, CRect(44,2,63,20)); } else { m_imgComboBoxThump.Draw(dc.m_hDC, rcComboThump, CRect(23,2,42,20)); } } else { m_imgComboBoxThump.Draw(dc.m_hDC, rcComboThump, CRect(2,2,20,20)); } HBRUSH hBrush = (HBRUSH)::GetStockObject(WHITE_BRUSH); FillRect(dc.m_hDC, CRect(5, 5, 24, 23), hBrush); if (m_hIcon) { DrawIconEx(dc.m_hDC, 5, 5, m_hIcon, 16, 16, 0, 0, DI_NORMAL); } } void CAddressComboBox::OnMouseMove(UINT nFlags, CPoint point) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_HOVER | TME_LEAVE; tme.dwHoverTime = 1;//HOVER_DEFAULT; TrackMouseEvent(&tme); CComboBox::OnMouseMove(nFlags, point); } LRESULT CAddressComboBox::OnMouseHover( WPARAM wParam, LPARAM lParam ) { if (!m_bIsThumpHover) { COMBOBOXINFO comboBoxInfo; comboBoxInfo.cbSize = sizeof(COMBOBOXINFO); GetComboBoxInfo(&comboBoxInfo); CRect rcEdit; ::GetClientRect(comboBoxInfo.hwndItem, &rcEdit); CRect rcComboThump = comboBoxInfo.rcButton; rcComboThump.left = 22 + rcEdit.Width(); rcComboThump.top = 5; rcComboThump.bottom = 23; CPoint pt; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); if (rcComboThump.PtInRect(pt)) { m_bIsThumpHover = TRUE; m_bIsThumpDown = wParam == MK_LBUTTON; Invalidate(); } } return 0; } LRESULT CAddressComboBox::OnMouseLeave( WPARAM wParam, LPARAM lParam ) { m_bIsThumpHover = FALSE; m_bIsThumpDown = FALSE; Invalidate(); return 0; } int CAddressComboBox::AddString( LPCTSTR lpszString, HICON hIcon ) { int nItem = CComboBox::AddString(lpszString); SetItemData(nItem, (DWORD)hIcon); return nItem; } void CAddressComboBox::OnCbnSelchange() { int nItem = GetCurSel(); if (nItem == -1) return; m_hIcon = (HICON)GetItemData(nItem); if (m_hIcon) { Invalidate(); } }