ListBox控件自绘

来源:互联网 发布:js 显示div 编辑:程序博客网 时间:2024/06/05 14:52

原理和步骤和前面控件相差无几,这里就不讲了,只贴完整代码:

主对话框类:

#pragma once#include "MyListBox.h"// CListBox自绘Dlg 对话框class CListBox自绘Dlg : public CDialogEx{// 构造public:CListBox自绘Dlg(CWnd* pParent = NULL);// 标准构造函数// 对话框数据enum { IDD = IDD_LISTBOX_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持// 实现protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()public:CMyListBox m_ListBox;CImageList m_ImgList;afx_msg void OnBnClickedBtn();};

// ListBox自绘Dlg.cpp : 实现文件//#include "stdafx.h"#include "ListBox自绘.h"#include "ListBox自绘Dlg.h"#include "afxdialogex.h"#ifdef _DEBUG#define new DEBUG_NEW#endif// CListBox自绘Dlg 对话框CListBox自绘Dlg::CListBox自绘Dlg(CWnd* pParent /*=NULL*/): CDialogEx(CListBox自绘Dlg::IDD, pParent){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CListBox自绘Dlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST, m_ListBox);}BEGIN_MESSAGE_MAP(CListBox自绘Dlg, CDialogEx)ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BTN, &CListBox自绘Dlg::OnBnClickedBtn)END_MESSAGE_MAP()BOOL CListBox自绘Dlg::OnInitDialog(){CDialogEx::OnInitDialog();SetIcon(m_hIcon, TRUE);// 设置大图标SetIcon(m_hIcon, FALSE);// 设置小图标m_ImgList.Create(32,32,ILC_COLOR32|ILC_MASK,3,3);m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));m_ImgList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));m_ListBox.SetImageList(&m_ImgList);m_ListBox.AddString("北京",0);m_ListBox.AddString("上海",1);m_ListBox.AddString("广州",2);return TRUE;  }void CListBox自绘Dlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}}HCURSOR CListBox自绘Dlg::OnQueryDragIcon(){return static_cast<HCURSOR>(m_hIcon);}void CListBox自绘Dlg::OnBnClickedBtn(){static int nCount = 1;CString strText;strText.Format("Item%d",nCount);m_ListBox.AddString(strText,nCount++ % 3);}

CListBox的派生类:

#pragma once// CMyListBoxclass CMyListBox : public CListBox{DECLARE_DYNAMIC(CMyListBox)public:CMyListBox();virtual ~CMyListBox();protected:DECLARE_MESSAGE_MAP()public:struct SLBData{     //存放文本和图标索引数据CString strText;int nImgIndex;SLBData(){strText.Empty();nImgIndex = -1;}};CImageList* m_ImgList;//接收主对话框类传递过来的CImageList对象virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);//重绘函数CImageList* SetImageList(CImageList* pImgList);//传递CImageList对象到派生类int AddString(CString strText,int nImgIndex);//保存要插入的文本和图标索引int GetText(int nItemIndex,CString& strText);//由当前绘制项的索引获取文本int GetImage(int nItemIndex,int& nImageIndex);//由当前绘制项的索引获取对应图标的索引void ReleaseMemory();//ListBox销毁时释放申请的所有内存virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMIS);afx_msg void OnDestroy();};

// MyListBox.cpp : 实现文件//#include "stdafx.h"#include "ListBox自绘.h"#include "MyListBox.h"// CMyListBoxIMPLEMENT_DYNAMIC(CMyListBox, CListBox)CMyListBox::CMyListBox(){m_ImgList = NULL;}CMyListBox::~CMyListBox(){//内存的销毁不能放在析构函数中,因为此时ListBox对象已经销毁//在ReleaseMemory()中调用GetCount()函数等已经没有意义,会报错:/*ASSERT(::IsWindow(m_hWnd));*///ReleaseMemory();}BEGIN_MESSAGE_MAP(CMyListBox, CListBox)ON_WM_DESTROY()END_MESSAGE_MAP()// CMyListBox 消息处理程序void CMyListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS){CDC dc;dc.Attach(lpDIS->hDC);CRect ListBRect = lpDIS->rcItem;int nCurItemIndex = lpDIS->itemID;if(nCurItemIndex == -1) return;  dc.SetBkMode(TRANSPARENT);  if (lpDIS->itemState & ODS_SELECTED)//选中项设置  {  dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));  dc.FillSolidRect(&ListBRect,GetSysColor(COLOR_HIGHLIGHT));  if(lpDIS->itemAction & ODA_FOCUS) dc.DrawFocusRect(&ListBRect);  }   else//非选中项设置  {  dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));if(nCurItemIndex % 2) dc.FillSolidRect(&ListBRect,RGB(0,192,192));  else dc.FillSolidRect(&ListBRect,RGB(192,192,0));}  //画文字  CRect TextRect = ListBRect;  CString strText;  GetText(nCurItemIndex,strText);//获取正在自绘项的文字  //TRACE("nItem = %d\r\n",nCurItemIndex);  CSize TempSize;ImageList_GetIconSize(m_ImgList->m_hImageList, (int*)&TempSize.cx, (int*)&TempSize.cy);TextRect.left = TextRect.left + TempSize.cx + 4;  dc.DrawText(strText,&TextRect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);  //画图标  CRect IconRect = ListBRect;  int nImageIndex;  GetImage(nCurItemIndex,nImageIndex);   m_ImgList->Draw(&dc,nImageIndex,IconRect.TopLeft(),ILD_NORMAL); dc.Detach();}CImageList* CMyListBox::SetImageList(CImageList* pImgList){CImageList* pOldImgList = m_ImgList;m_ImgList = pImgList;return pOldImgList;}int CMyListBox::AddString(CString strText,int nImgIndex){int nIndex = CListBox::AddString(strText);SLBData* pLBData = new SLBData;if(pLBData == NULL) return -1;pLBData->strText = strText;pLBData->nImgIndex = nImgIndex;CListBox::SetItemData(nIndex,(DWORD_PTR)pLBData);return nIndex;}int CMyListBox::GetText(int nItemIndex,CString& strText){SLBData* pData = (SLBData*)CListBox::GetItemData(nItemIndex);if(pData == NULL) return 0;strText = pData->strText;return 1;}int CMyListBox::GetImage(int nItemIndex,int& nImageIndex){SLBData* pData = (SLBData*)CListBox::GetItemData(nItemIndex);    if(pData == NULL) return 0;nImageIndex = pData->nImgIndex;return 1;}void CMyListBox::ReleaseMemory(){int nItemCount = CListBox::GetCount();for (int i = 0;i < nItemCount;i++){SLBData* pData = (SLBData*)CListBox::GetItemData(i);if (pData){delete pData;pData = NULL;}}CListBox::ResetContent();}void CMyListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMIS){CSize TempSize;ImageList_GetIconSize(m_ImgList->m_hImageList, (int*)&TempSize.cx, (int*)&TempSize.cy);lpMIS->itemHeight = TempSize.cy;/*int nItem = lpMIS->itemID;if(nItem % 2) lpMIS->itemHeight = 100;*///lpMIS->itemHeight = 20;}void CMyListBox::OnDestroy(){CListBox::OnDestroy();ReleaseMemory();}