第一步:在窗口中拖拽一个CComboBox控件,设置如下属性:
注意:
第二步:选中CComboBox控件的下拉箭头,弹出下拉框,拖住拉大到至少能显示5个item的大小
注意:如果不拉大下拉框大于5个item的大小,则运行时下拉框不会显示出来。
第三步:选中CComboBox鼠标右键为其添加变量
第四步:定义CMyComboBox类,并使用CMyComboBox类名替换刚才生成的CComboBox类型的变量的类型
CMyComboBox.h
#pragma once
#include
#include
class CMyComboBox : public CComboBox
{
public:
CMyComboBox();
void SetItem(std::vector text);
void SetTextColor(COLORREF rgb);
void SetFont(const std::string& name, int size, bool bold = false);
void SetBkColor(COLORREF color);
virtual void PreSubclassWindow() override;
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
virtual int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct);
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP();
private:
CString m_text;
COLORREF m_text_color;
std::string m_font;
int m_font_size;
bool m_bold;
COLORREF m_bk_color;
};
CMyComboBox.cpp
#include "pch.h"
#include "CMyComboBox.h"
CMyComboBox::CMyComboBox()
: m_text(_T("请选择"))
, m_text_color(RGB(0,0,0)
, m_font("Microsoft YaHei UI")
, m_bold(false)
, m_font_size(14)
, m_bk_color(TRANSPARENT)
{
}
BEGIN_MESSAGE_MAP(CMyComboBox, CComboBox)
ON_WM_PAINT()
END_MESSAGE_MAP()
void CMyComboBox::SetItemText(std::vector text)
{
InsertString(GetCount(), m_text);
for (auto item : text) {
InsertString(GetCount(), item);
}
SetCurSel(0);
}
void CMyComboBox::SetTextColor(COLORREF rgb)
{
m_text_color = rgb;
}
void CMyComboBox::SetFontName(const std::string& font, bool bold/* = false*/)
{
m_font_name = font;
m_bold = bold;
}
void CMyComboBox::SetFontSize(int size)
{
m_font_size = size;
}
void CMyComboBox::SetBkColor(COLORREF color)
{
m_bk_color= color;
SendMessage(CB_SETITEMHEIGHT, -1, 37);
}
void CMyComboBox::PreSubclassWindow()
{
ModifyStyle(0, BS_OWNERDRAW);
CComboBox::PreSubclassWindow();
}
void CMyComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CString text;
if (-1 != lpDrawItemStruct->itemID) {
GetLBText(lpDrawItemStruct->itemID, text);
}
else {
return;
}
TEXTMETRIC text_metric;
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
if (pDC) {
CFont font;
font.CreateFontW(m_font_size - 5, 0, 0, 0, (m_bold ? FW_BOLD : FW_NORMAL), FALSE, FALSE, FALSE, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS,to_wstring(m_font_name).c_str());
pDC->SelectObject(&font);
pDC->GetTextMetrics(&text_metric);
CRect rc;
GetClientRect(&rc);
if ((lpDrawItemStruct->itemState & ODS_SELECTED) &&
(lpDrawItemStruct->itemAction & (ODA_DRAWENTIRE | ODA_SELECT))) {
pDC->FillSolidRect(&lpDrawItemStruct->rcItem, m_bk_color);
pDC->SetBkColor(m_bk_color);
pDC->SetTextColor(m_text_color);
pDC->TextOutW(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top, text);
}
else if (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) {
pDC->FillSolidRect(&lpDrawItemStruct->rcItem, m_bk_color);
pDC->SetBkColor(m_bk_color);
pDC->SetTextColor(m_text_color);
pDC->TextOutW(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top, text);
}
ReleaseDC(pDC);
font.DeleteObject();
}
}
void CMyComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
CRect rc;
GetClientRect(&rc);
lpMeasureItemStruct->itemHeight = 20;
}
int CMyComboBox::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
{
return 1;
}
void CMyComboBox::OnPaint()
{
CRect rect;
GetClientRect(&rect);
CPaintDC pDC(this);
pDC.SetBkMode(TRANSPARENT);
pDC.SelectStockObject(NULL_BRUSH);
CPen pen;
pen.CreatePen(PS_SOLID, 1, m_bk_color);
pDC.SelectObject(&pen);
CFont font;
font.CreateFontW(m_font_size - 5, 0, 0, 0, (m_bold ? FW_BOLD : FW_NORMAL), FALSE, FALSE, FALSE, ANSI_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS,to_wstring(m_font_name).c_str());
pDC.SelectObject(&font);
CBrush brush;
CBrush brush_flag;
CBrush brush_angle;
CRgn rgn;
if (m_back_color != TRANSPARENT) {
brush.CreateSolidBrush(m_bk_color);
pDC.SelectObject(&brush);
pDC.Rectangle(&rect);
CRect rc(rect);
rc.left = rect.right - 20;
brush_flag.CreateSolidBrush(m_bk_color);
pDC.SelectObject(&brush_flag);
pDC.Rectangle(rc);
int angleSideWidth = 10;
CPoint ptAngle[3];
ptAngle[0].x = rc.left + rc.Width() / 2 - angleSideWidth / 2;
ptAngle[0].y = rc.top + rc.Height() / 2 - 2;
ptAngle[1].x = ptAngle[0].x + angleSideWidth;
ptAngle[1].y = ptAngle[0].y;
ptAngle[2].x = rc.left + rc.Width() / 2;
ptAngle[2].y = ptAngle[0].y + 5;
rgn.CreatePolygonRgn(ptAngle, 3, ALTERNATE);
brush_angle.CreateSolidBrush(RGB(123,123,123));
pDC.FillRgn(&rgn, &brush_angle);
}
CString text;
GetWindowTextW(text);
if (0 == text.GetLength()) {
text = m_text;
}
int len = text.GetLength();
if (0 < len) {
TEXTMETRIC text_metric;
pDC.GetTextMetrics(&text_metric);
int offset_move = ((text_metric.tmPitchAndFamily & 0x0F) * (len - 1) + text_metric.tmAveCharWidth * len);
if (0 < offset_move) {
pDC.MoveTo((len <= 6 ? offset_move + text_metric.tmAveCharWidth : offset_move), 0);
}
rect.top += (rect.Height() - text_metric.tmHeight) / 2;
pDC.SetTextColor(m_text_color);
pDC.DrawText(text.GetBuffer(), &rect, DT_CENTER | DT_SINGLELINE);
}
pen.DeleteObject();
font.DeleteObject();
if (m_back_color != TRANSPARENT) {
brush.DeleteObject();
brush_flag.DeleteObject();
brush_angle.DeleteObject();
rgn.DeleteObject();
}
ReleaseDC(&pDC);
CComboBox::OnPaint();
}