效果圖:html
.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: // 關聯的CImageList CImageList *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); };
/********************************************************** ComboBoxXI.cpp : implementation file Written by WangYao (wangyao1052@163.com) Version: V1.0 2014-06-07 **********************************************************/ #include "stdafx.h" #include "ComboBoxXI.h" #define CBXI_CX_BORDER 2 #define CBXI_CY_BORDER 2 // CComboBoxXI IMPLEMENT_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()); } // 繪製ICON CRect 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); } } // 繪製Text if (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; // 檢測是不是DropList if (-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
spa