【MFC】控件自绘之CListCtrl

来源:互联网 发布:电磁波 知乎 编辑:程序博客网 时间:2024/05/22 09:00

一:

   国际惯例,直接上代码

 

二:

.h头文件

// CSkinHeaderCtrlclass CSkinHeaderCtrl : public CHeaderCtrl{DECLARE_DYNAMIC(CSkinHeaderCtrl)public:CSkinHeaderCtrl();virtual ~CSkinHeaderCtrl();void SetHeaderBk(CString strBkImage);protected:DECLARE_MESSAGE_MAP()afx_msg void OnPaint();afx_msg void OnSize(UINT nType, int cx, int cy);afx_msg LRESULT OnLayout( WPARAM wParam, LPARAM lParam );virtual void PreSubclassWindow();void DrawColumn(CDC* pDC, int nIndex);void DrawBackGnd(CDC* pDC);private:Image*m_pBkImage;};// CSkinListCtrlclass CSkinListCtrl : public CListCtrl{DECLARE_DYNAMIC(CSkinListCtrl)public:CSkinListCtrl();virtual ~CSkinListCtrl();void SetRowHeight(int nHeight);virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);protected:DECLARE_MESSAGE_MAP()afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);virtual void PreSubclassWindow();void DrawEveryone(CDC* pDC, int nItem, int nSubItem);private:enum{TEXT_ALIGN_LEFT = 0,TEXT_ALIGN_CENTER,TEXT_ALIGN_RIGHT};enum{ITEM_UNKNOWN = 0,ITEM_SELECTED,ITEM_FOCUSED,};int GetTextAlign(int nColumn);int GetItemState(int nItem, int nSubItem);private:CSkinHeaderCtrl      m_HeaderCtrl;              //列表头控件int                  m_nCurSelItem;             //当前选中项int m_nRowHeight;              //行高};


 

.cpp源文件

// CSkinHeaderCtrlIMPLEMENT_DYNAMIC(CSkinHeaderCtrl, CHeaderCtrl)CSkinHeaderCtrl::CSkinHeaderCtrl():m_pBkImage(NULL){SetHeaderBk(_T("..//Skin//ListHeaderBK.png"));}CSkinHeaderCtrl::~CSkinHeaderCtrl(){if(m_pBkImage){delete m_pBkImage;m_pBkImage = NULL;}}BEGIN_MESSAGE_MAP(CSkinHeaderCtrl, CHeaderCtrl)ON_WM_SIZE()ON_WM_PAINT()ON_MESSAGE(HDM_LAYOUT, OnLayout)END_MESSAGE_MAP()void CSkinHeaderCtrl::SetHeaderBk(CString strBkImage){ASSERT(m_pBkImage == NULL);m_pBkImage = Image::FromFile(strBkImage);}void CSkinHeaderCtrl::DrawColumn(CDC* pDC, int nIndex){CRect                    rect;//获取区域小矩形GetItemRect(nIndex, &rect);HDITEM hdi;const int c_cchBuffer = 256;TCHAR  lpBuffer[c_cchBuffer];hdi.mask = HDI_TEXT;hdi.pszText = lpBuffer;hdi.cchTextMax = c_cchBuffer;VERIFY(GetItem(nIndex, &hdi));CString                  strItemText(lpBuffer);Graphics                 graph(pDC->m_hDC);RectF                    rectF(rect.left, rect.top, rect.Width(), rect.Height());TextureBrush texBrush(m_pBkImage);graph.FillRectangle(&texBrush, rectF);graph.DrawRectangle(&Pen(Color::White), rectF);FontFamily fontFamily(L"微软雅黑");Gdiplus::Font       font(&fontFamily, 10, FontStyleBold, UnitPoint);SolidBrush solidBrush(Color::Black);StringFormat stringFormat;stringFormat.SetLineAlignment(StringAlignmentCenter);stringFormat.SetAlignment(StringAlignmentNear);stringFormat.SetFormatFlags(StringFormatFlagsLineLimit ); //限制一行rectF.X += 10.0f;  //不要完全靠左 不好看//画文字和按钮graph.DrawString(strItemText, strItemText.GetLength(), &font, rectF, &stringFormat, &solidBrush);}void CSkinHeaderCtrl::DrawBackGnd(CDC* pDC){CRect rect;GetClientRect(&rect);Graphics                 graph(pDC->m_hDC);RectF                    rectF(rect.left, rect.top, rect.Width(), rect.Height());TextureBrush texBrush(m_pBkImage);graph.FillRectangle(&texBrush, rectF);}void CSkinHeaderCtrl::OnPaint(){CPaintDC dc(this);CRect    rect;GetClientRect(&rect);CMemDCC  DCMemory(&dc, &rect);DrawBackGnd(&DCMemory);//计算一共有多少列,绘制每一列int nCount = GetItemCount();for(int i= 0; i<nCount; i++){DrawColumn(&DCMemory, i);}}LRESULT CSkinHeaderCtrl::OnLayout( WPARAM wParam, LPARAM lParam ){LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam); HD_LAYOUT &hdl = *( HD_LAYOUT * ) lParam; RECT *prc = hdl.prc; WINDOWPOS *pwpos = hdl.pwpos; pwpos->cy = m_pBkImage->GetHeight(); prc->top = m_pBkImage->GetHeight(); return lResult; }void CSkinHeaderCtrl::PreSubclassWindow(){CHeaderCtrl::PreSubclassWindow();}void CSkinHeaderCtrl::OnSize(UINT nType, int cx, int cy){CHeaderCtrl::OnSize(nType, cx, cy);Invalidate();}// CSkinListCtrlIMPLEMENT_DYNAMIC(CSkinListCtrl, CListCtrl)CSkinListCtrl::CSkinListCtrl(){m_nCurSelItem = -1;SetRowHeight(30);}CSkinListCtrl::~CSkinListCtrl(){}BEGIN_MESSAGE_MAP(CSkinListCtrl, CListCtrl)ON_WM_LBUTTONDOWN()ON_WM_CREATE()ON_WM_MEASUREITEM_REFLECT()END_MESSAGE_MAP()// CSkinListCtrl message handlersvoid CSkinListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);ASSERT(pDC != NULL);int nColumn = m_HeaderCtrl.GetItemCount();for(int i=0; i<nColumn; i++){DrawEveryone(pDC, lpDrawItemStruct->itemID, i);}}int CSkinListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CListCtrl::OnCreate(lpCreateStruct) == -1)return -1;CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();//用我们自己的headctrl去子类化系统的if(pHeaderCtrl){m_HeaderCtrl.SubclassWindow(pHeaderCtrl->m_hWnd);}SetBkColor(RGB(174, 183, 193));return 1;}void CSkinListCtrl::PreSubclassWindow(){CListCtrl::PreSubclassWindow();ModifyStyle(NULL, LVS_OWNERDRAWFIXED);CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();//用我们自己的headctrl去子类化系统的if(pHeaderCtrl){m_HeaderCtrl.SubclassWindow(pHeaderCtrl->m_hWnd);}SetBkColor(RGB(174, 183, 193));}void CSkinListCtrl::DrawEveryone(CDC* pDC, int nItem, int nSubItem){CRect rectItem;int   nTextAlign;CString strItem;int   nItemState;nItemState = GetItemState(nItem, nSubItem);strItem = GetItemText(nItem, nSubItem);nTextAlign = GetTextAlign(nSubItem);VERIFY(GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rectItem));RectF        rectF(rectItem.left, rectItem.top, rectItem.Width(), rectItem.Height());Graphics     graph(pDC->m_hDC);//根据选中状态填充背景switch(nItemState){case ITEM_SELECTED:{graph.FillRectangle(&SolidBrush(Color(203, 209, 216)), rectF);break;}default:{graph.FillRectangle(&SolidBrush(Color(174, 183, 193)), rectF);break;}}//根据文本排列方向 画文字FontFamily fontFamily(L"微软雅黑");Gdiplus::Font       font(&fontFamily, 10, FontStyleRegular, UnitPoint);SolidBrush solidBrush(Color::Black);StringFormat stringFormat;stringFormat.SetLineAlignment(StringAlignmentCenter);switch(nTextAlign){case TEXT_ALIGN_CENTER:{stringFormat.SetAlignment(StringAlignmentCenter);break;}case TEXT_ALIGN_RIGHT:{stringFormat.SetAlignment(StringAlignmentFar);break;}default:{ASSERT(nTextAlign == TEXT_ALIGN_LEFT);stringFormat.SetAlignment(StringAlignmentNear);rectF.X += 10.0f;  //不要完全靠左 不好看break;}}graph.DrawString(strItem, strItem.GetLength(), &font, rectF, &stringFormat, &solidBrush);}int CSkinListCtrl::GetTextAlign(int nColumn){LVCOLUMN col;col.mask = LVCF_WIDTH | LVCF_FMT;VERIFY(GetColumn(nColumn, &col));//获得文字是要居中还是要左右if(col.fmt & LVCFMT_LEFT)return TEXT_ALIGN_LEFT;else if(col.fmt & LVCFMT_CENTER)return TEXT_ALIGN_CENTER;else if(col.fmt & LVCFMT_RIGHT)return TEXT_ALIGN_RIGHT;//默认左边return TEXT_ALIGN_LEFT;}int CSkinListCtrl::GetItemState(int nItem, int nSubItem){if(nItem == m_nCurSelItem)return ITEM_SELECTED;elsereturn ITEM_UNKNOWN;//LVITEM  item;//item.mask = LVIF_STATE;//item.iItem = nItem;//item.iSubItem = nSubItem;//VERIFY(GetItem(&item));//if(item.state & LVIS_SELECTED)//return ITEM_SELECTED;//else if(item.state & LVIS_FOCUSED)//return ITEM_FOCUSED;//else//return ITEM_UNKNOWN;}void CSkinListCtrl::OnLButtonDown(UINT nFlags, CPoint point){UINT uFlags;int nItem = HitTest(point, &uFlags);if (uFlags & LVHT_ONITEMLABEL){if(m_nCurSelItem != nItem){//刷新之前的CRect rect;GetItemRect(m_nCurSelItem, &rect, LVIR_BOUNDS);InvalidateRect(&rect);//重置m_nCurSelItem = nItem;}}CListCtrl::OnLButtonDown(nFlags, point);}void CSkinListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct){if (m_nRowHeight>0){lpMeasureItemStruct->itemHeight = m_nRowHeight;}}void CSkinListCtrl::SetRowHeight(int nHeight){m_nRowHeight = nHeight;}


 

原创粉丝点击