MFC 自绘ComboBox
来源:互联网 发布:电脑桌面软件太多 编辑:程序博客网 时间:2024/06/08 00:08
效果图:
.h文件
#pragma once#include"stdafx.h"class CComboBoxXI : public CComboBox{DECLARE_DYNAMIC(CComboBoxXI)public:CComboBoxXI();virtual ~CComboBoxXI();void SetImageList(CImageList* pImageList);CImageList* GetImageList() const;int GetItemImage(int nIndex);int SetItemImage(int nIndex, int nImageIndex, BOOL bRepaint = TRUE);int AddString(LPCTSTR lpszString, int nImageIndex = -1);int DeleteString(UINT nIndex);int InsertString(int nIndex, LPCTSTR lpszString, int nImageIndex);void ResetContent();DWORD_PTR GetItemData(int nIndex) const;int SetItemData(int nIndex, DWORD_PTR dwItemData);void* GetItemDataPtr(int nIndex) const;int SetItemDataPtr(int nIndex, void* pData);protected:virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);DECLARE_MESSAGE_MAP()private:// 关联的CImageListCImageList *m_pImageList;CSize m_imageSize;// EditCtrl的高度unsigned int m_nEditHeight;// 是否是DropList:// -1(待定,未检测), 1(Yes), 0(No)// 只对DropList设置EditCtrl的高度,对DropDown和Simple则采用默认高度int m_iIsDropList;struct CBDataXI{// 图像序号,如果为-1,则表示无图像int iImageIndex;// 关联数据的指针LPVOID pData;CBDataXI(){iImageIndex = -1;pData = NULL;}};void DeleteItemData(int nIndex);};
.cpp 文件
/********************************************************** ComboBoxXI.cpp : implementation file Written by WangYao (wangyao1052@163.com) Version: V1.0 2014-06-07**********************************************************/#include "stdafx.h"#include "ComboBoxXI.h"#defineCBXI_CX_BORDER 2#defineCBXI_CY_BORDER 2// CComboBoxXIIMPLEMENT_DYNAMIC(CComboBoxXI, CComboBox)CComboBoxXI::CComboBoxXI(){m_pImageList = NULL;m_imageSize.cx = 0;m_imageSize.cy = 0;m_nEditHeight = 0;m_iIsDropList = -1;}CComboBoxXI::~CComboBoxXI(){}//---------------------------------------------------------// 函数: SetImageList// 功能: 设置关联的ImageList// 参数: // pImageList --- ImageList的指针// 返回: 无//---------------------------------------------------------void CComboBoxXI::SetImageList(CImageList* pImageList){m_pImageList = pImageList;if (m_pImageList){int cx;int cy;ImageList_GetIconSize(*m_pImageList, &cx, &cy);m_imageSize.cx = cx;m_imageSize.cy = cy;}else{m_imageSize.cx = 0;m_imageSize.cy = 0;}Invalidate();}//---------------------------------------------------------// 函数: GetImageList// 功能: 获取关联ImageList的指针// 参数: 无// 返回: 关联ImageList的指针,若没有关联ImageList返回NULL//---------------------------------------------------------CImageList* CComboBoxXI::GetImageList() const{return m_pImageList;}//---------------------------------------------------------// 函数: GetItemImage// 功能: 获取项的图片索引// 参数: // nIndex --- 项索引(以0为起点)// 返回:// 以0为起始的图片序号// 若存在错误,如nIndex超出范围,返回-1// 若组合框项没有关联图片则返回-1//---------------------------------------------------------int CComboBoxXI::GetItemImage(int nIndex){CBDataXI* pCBData = (CBDataXI*)CComboBox::GetItemData(nIndex);if (pCBData == (CBDataXI*)CB_ERR || pCBData == NULL){return -1;}return pCBData->iImageIndex;}//---------------------------------------------------------// 函数: SetItemImage// 功能: 设置项的图片索引// 参数: // nIndex --- 项索引(以0为起点)// nImageIndex --- 图片索引(以0为起点)// bRepaint --- 是否重绘// 返回:// 成功返回0,失败返回-1//---------------------------------------------------------int CComboBoxXI::SetItemImage(int nIndex, int nImageIndex, BOOL bRepaint){CBDataXI* pCBData = (CBDataXI*)CComboBox::GetItemData(nIndex);if (pCBData == (CBDataXI*)CB_ERR || pCBData == NULL){return -1;}pCBData->iImageIndex = nImageIndex;if (bRepaint){Invalidate();}return 0;}//---------------------------------------------------------// 函数: AddString// 功能: 添加项// 参数: lpszString --- 字符串指针// nImageIndex --- 图片索引(以0为起点)// 返回: 新增项的索引值// 失败则返回CB_ERR或CB_ERRSPACE//---------------------------------------------------------int CComboBoxXI::AddString(LPCTSTR lpszString, int nImageIndex){int nIndex = CComboBox::AddString(lpszString);if (nIndex != CB_ERR && nIndex != CB_ERRSPACE){CBDataXI *pData = new CBDataXI();pData->iImageIndex = nImageIndex;pData->pData = NULL;CComboBox::SetItemData(nIndex, (DWORD_PTR)pData);}return nIndex;}//---------------------------------------------------------// 函数: InsertString// 功能: 在指定位置插入项// 参数: // nIndex --- 指定位置// lpszString --- 字符串指针// nImageIndex --- 图片索引(以0为起点)// 返回: // 插入项索引值// 失败则返回CB_ERR或CB_ERRSPACE//---------------------------------------------------------int CComboBoxXI::InsertString(int nIndex, LPCTSTR lpszString, int nImageIndex){int nRet = CComboBox::InsertString(nIndex, lpszString);if (nRet != CB_ERR && nRet != CB_ERRSPACE){CBDataXI *pData = new CBDataXI();pData->iImageIndex = nImageIndex;pData->pData = NULL;CComboBox::SetItemData(nIndex, (DWORD_PTR)pData);}return nRet;}//---------------------------------------------------------// 函数: DeleteString// 功能: 删除项// 参数: // nIndex --- 索引// 返回: // 成功则返回当前还剩的项数// 失败则返回CB_ERR//---------------------------------------------------------int CComboBoxXI::DeleteString(UINT nIndex){DeleteItemData(nIndex);return CComboBox::DeleteString(nIndex);}//---------------------------------------------------------// 函数: ResetContent// 功能: 清空内容//---------------------------------------------------------void CComboBoxXI::ResetContent(){int nCnt = CComboBox::GetCount();for (int i = 0; i < nCnt; ++i){DeleteItemData(i);}CComboBox::ResetContent();}//---------------------------------------------------------// 函数: GetItemData// 功能: 获取项关联的数据// 参数:// nIndex --- 索引// 返回:// 关联的数据,失败则返回CB_ERR//---------------------------------------------------------DWORD_PTR CComboBoxXI::GetItemData(int nIndex) const{CBDataXI* pCBData = (CBDataXI*)CComboBox::GetItemData(nIndex);if (pCBData == (CBDataXI*)CB_ERR || pCBData == NULL){return CB_ERR;}return (DWORD_PTR)pCBData->pData;}//---------------------------------------------------------// 函数: SetItemData// 功能: 设置项关联的数据// 参数:// nIndex --- 索引// dwItemData --- 关联的数据 // 返回:// 成功返回CB_OKAY, 失败返回CB_ERR//---------------------------------------------------------int CComboBoxXI::SetItemData(int nIndex, DWORD_PTR dwItemData){CBDataXI* pCBData = (CBDataXI*)CComboBox::GetItemData(nIndex);if (pCBData == (CBDataXI*)CB_ERR || pCBData == NULL){return CB_ERR;}pCBData->pData = (LPVOID)dwItemData;return CB_OKAY;}//---------------------------------------------------------// 函数: GetItemDataPtr// 功能: 获取项关联的数据// 参数:// nIndex --- 索引// 返回:// 关联的数据,失败则返回CB_ERR//---------------------------------------------------------void* CComboBoxXI::GetItemDataPtr(int nIndex) const{CBDataXI* pCBData = (CBDataXI*)CComboBox::GetItemDataPtr(nIndex);if (pCBData == (CBDataXI*)CB_ERR || pCBData == NULL){return (void*)CB_ERR;}return pCBData->pData;}//---------------------------------------------------------// 函数: SetItemDataPtr// 功能: 设置项关联的数据// 参数:// nIndex --- 索引// pData --- 关联的数据// 返回:// 成功返回CB_OKAY, 失败则返回CB_ERR//---------------------------------------------------------int CComboBoxXI::SetItemDataPtr(int nIndex, void* pData){CBDataXI* pCBData = (CBDataXI*)CComboBox::GetItemDataPtr(nIndex);if (pCBData == (CBDataXI*)CB_ERR || pCBData == NULL){return CB_ERR;}pCBData->pData = pData;return CB_OKAY;}void CComboBoxXI::DeleteItemData(int nIndex){CBDataXI* pCBData = (CBDataXI*)CComboBox::GetItemData(nIndex);if (pCBData != (CBDataXI*)CB_ERR){delete pCBData;CComboBox::SetItemData(nIndex, (DWORD_PTR)NULL);}}void CComboBoxXI::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){if (lpDrawItemStruct->itemID == -1){return;}CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);pDC->SetBkMode(TRANSPARENT);RECT& rcItem = lpDrawItemStruct->rcItem;CString cstrItemText;CComboBox::GetLBText(lpDrawItemStruct->itemID, cstrItemText);CBDataXI* pData = (CBDataXI*)CComboBox::GetItemDataPtr(lpDrawItemStruct->itemID);if (NULL == pData){return;}// 是否处于选中状态BOOL bIsSelected = (lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED);// 是否处于焦点状态BOOL bIsFocused = (lpDrawItemStruct->itemAction | ODA_FOCUS) && (lpDrawItemStruct->itemState & ODS_FOCUS);// 绘制背景if (bIsSelected){COLORREF oldColor = pDC->GetBkColor();pDC->FillSolidRect(&rcItem, ::GetSysColor(COLOR_HIGHLIGHT));pDC->SetBkColor(oldColor);}else{pDC->FillSolidRect(&rcItem, pDC->GetBkColor());}// 绘制ICONCRect rcIcon(rcItem.left, rcItem.top, rcItem.left, rcItem.top);if (m_pImageList){HICON hIcon = m_pImageList->ExtractIcon(pData->iImageIndex);if (hIcon){rcIcon.right = rcItem.left + m_imageSize.cx + 2 * CBXI_CX_BORDER;rcIcon.bottom = rcItem.top + m_imageSize.cy + 2 * CBXI_CY_BORDER;CPoint pos(rcIcon.left + CBXI_CX_BORDER, rcIcon.top + CBXI_CY_BORDER);pDC->DrawState(pos, m_imageSize, hIcon, DSS_NORMAL, (CBrush*)NULL);::DestroyIcon(hIcon);}}// 绘制Textif (bIsSelected){pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));}else{pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));}CRect rcText(rcItem);rcText.left = rcIcon.right;rcText.top = rcIcon.top;pDC->DrawText(cstrItemText, rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK);}void CComboBoxXI::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct){CDC *pDC = GetDC();LPCTSTR lpszText = (LPCTSTR)lpMeasureItemStruct->itemData;CSize szText = pDC->GetTextExtent(lpszText);ReleaseDC(pDC);lpMeasureItemStruct->itemHeight = szText.cy > m_imageSize.cy + 2 * CBXI_CY_BORDER ? szText.cy : m_imageSize.cy + 2 * CBXI_CY_BORDER;// 检测是否是DropListif (-1 == m_iIsDropList){DWORD dwStyle = GetStyle();if (DWORD(CBS_DROPDOWNLIST & dwStyle) == (DWORD)CBS_DROPDOWNLIST){m_iIsDropList = 1;}else{m_iIsDropList = 0;}}// 设置EditCtrl的高度if (m_iIsDropList == 1 && lpMeasureItemStruct->itemHeight > m_nEditHeight){m_nEditHeight = lpMeasureItemStruct->itemHeight;SetItemHeight(-1, m_nEditHeight);}}BEGIN_MESSAGE_MAP(CComboBoxXI, CComboBox)END_MESSAGE_MAP()// CComboBoxXI message handlers
说明:
=============== 提供了如下接口 ===============================
void SetImageList(CImageList* pImageList);
CImageList* GetImageList() const;
int GetItemImage(int nIndex);
int SetItemImage(int nIndex, int nImageIndex, BOOL bRepaint = TRUE);
int AddString(LPCTSTR lpszString, int nImageIndex = -1);
int DeleteString(UINT nIndex);
int InsertString(int nIndex, LPCTSTR lpszString, int nImageIndex);
void ResetContent();
DWORD_PTR GetItemData(int nIndex) const;
int SetItemData(int nIndex, DWORD_PTR dwItemData);
void* GetItemDataPtr(int nIndex) const;
int SetItemDataPtr(int nIndex, void* pData);
================= 示例 =================================
OnInitialDialog()
{
...........
m_imglist1.Create(32,32, ILC_COLOR32 | ILC_MASK, 2, 1);
m_imglist1.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_imglist1.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_combo.SetImageList(&m_imglist1);
m_combo.AddString(_T("123"), 0);
m_combo.AddString(_T("456"), 1);
m_combo.SetCurSel(0);
}
注:ComboBox要设置两个属性
HasStrings: True
Owner Draw: Variable
- MFC 自绘ComboBox
- combobox自绘问题
- 【自绘ComboBox】带图标的ComboBox
- 【Browser】combobox自绘问题
- [C#] 简单自绘 ComboBox
- ComboBox控件自绘操作
- MFC 自绘listbox , 自绘ComboBox 下拉列表框 如何设置其列表项的高度和宽度?
- MFC ComboBox
- MFC ComboBox
- MFC ComboBox
- 实现自绘 ComboBox 源代码 (C#)
- 自绘ComboBox改变颜色和大小
- Combobox的简单自绘实现
- 【MFC】自绘
- MFC自绘标题
- MFC 自绘进度条
- MFC 自绘
- MFC 自绘控件
- PL/SQL exception(例外)
- ROS实战之人脸检测
- su、sudo命令使用及区别
- 丑数
- Android版 Sokect服务端和客户端
- MFC 自绘ComboBox
- Noip2015提高组Day1 “神奇的幻方”题解
- 用 ThreadLocal 管理用户session
- NKOI 3748 玩具取名
- 迷宫问题解法汇总
- C#入门10.5——抽象类与抽象方法声明
- python
- switch off light
- 演讲如何克服紧张情绪