先看看效果

頭文件:
#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();
}
}