Author: kagula@20150401
环境: vs2013sp1
自定义行高、字体、颜色。
如何引用的示例代码
初始化
BOOL CTestListCtrlDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon { DWORD dwStyle = m_list.GetExtendedStyle(); //添加列表框的网格线!!! dwStyle |= LVS_EX_FULLROWSELECT; dwStyle |= LVS_EX_GRIDLINES; m_list.SetExtendedStyle(dwStyle); m_list.InsertColumn(0,L"编号",LVCFMT_LEFT,32); //添加列标题!!!! 这里的80,40,90用以设置列的宽度。!!!LVCFMT_LEFT用来设置对齐方式!!! m_list.InsertColumn(1,L"商品名称",LVCFMT_LEFT,256); m_list.InsertColumn(2,L"颜色",LVCFMT_CENTER,32); m_list.InsertColumn(3,L"尺码",LVCFMT_CENTER,32); m_list.InsertColumn(4,L"数量",LVCFMT_CENTER,32); InitList(); } //m_list.SetFontSelf(15,L"黑体");//设定表体中的字体 int nRow = m_list.InsertItem(0,L""); m_list.SetItemText(nRow,0,L"编号"); m_list.SetItemText(nRow,1,L"商品名称"); m_list.SetItemText(nRow,2,L"颜色"); m_list.SetItemText(nRow,3,L"尺码"); m_list.SetItemText(nRow,4,L"数量"); nRow = m_list.InsertItem(1,L""); m_list.SetItemText(nRow,0,L"编号2"); m_list.SetItemText(nRow,1,L"商品名称2"); m_list.SetItemText(nRow,2,L"颜色2"); m_list.SetItemText(nRow,3,L"尺码2"); m_list.SetItemText(nRow,4,L"数量2"); return TRUE; // return TRUE unless you set the focus to a control }
void CRFI_CHECK_DLG::InitList() { static bool bFirst = true; if (bFirst) { bFirst=FALSE; CHeaderCtrl *pHeader = NULL; pHeader = m_list.GetHeaderCtrl(); if(pHeader) { TRACE("header item count:%d/n", pHeader->GetItemCount()); int iColumn=pHeader->GetItemCount(); for (int i=0; i<iColumn; i++) { HDITEM hdItem; BOOL bResult = FALSE; bResult=pHeader->GetItem(i, &hdItem); //直接在OnInitDialog中调用,程序会挂掉。 hdItem.fmt |= HDF_OWNERDRAW; bResult=pHeader->SetItem(i, &hdItem); } //pHeader->Invalidate(); } } }
缩放
void CTestListCtrlDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); CRect rectClient; GetClientRect(&rectClient); { int left = 0; int top = 39; int columnWidth = 52; int widthProductName = (rectClient.Width()-columnWidth*4)<128?128:(rectClient.Width()-columnWidth*4); CRect rect(left,top,left+rectClient.Width(),rectClient.Height()-64); GetDlgItem(IDC_LIST2)->MoveWindow(&rect); m_list.SetColumnWidth(0,columnWidth); m_list.SetColumnWidth(1,widthProductName); m_list.SetColumnWidth(2,columnWidth); m_list.SetColumnWidth(3,columnWidth); m_list.SetColumnWidth(4,columnWidth); } }
依赖文件
C8637ListCtrl.h
#pragma once #include "C8637HeaderCtrl.h" // C8637ListCtrl class C8637ListCtrl : public CListCtrl { DECLARE_DYNAMIC(C8637ListCtrl) public: C8637ListCtrl(); virtual ~C8637ListCtrl(); C8637HeaderCtrl m_headerCtrl; protected: DECLARE_MESSAGE_MAP() virtual void PreSubclassWindow(); public: CFont* m_font; void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct); void SetFontSelf(int nHeight, LPCTSTR lpszFacename); afx_msg void OnNcPaint(); afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct); virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); };
C8637ListCtrl.cpp
// C8637ListCtrl.cpp : implementation file // #include "stdafx.h" #include "C8637ListCtrl.h" /* [1]《如何重绘CListCtrl的表头》 http://qiusuoge.com/9200.html [2]《CListCtrl的Report风格自绘》 http://jingyan.baidu.com/article/5bbb5a1b38af1113eaa17910.html [3]《CListCtrl插入多列(REPORT样式)》 http://blog.sina.com.cn/s/blog_6392417a0100gxmj.html */ // C8637ListCtrl IMPLEMENT_DYNAMIC(C8637ListCtrl, CListCtrl) C8637ListCtrl::C8637ListCtrl() { m_font = nullptr; } C8637ListCtrl::~C8637ListCtrl() { if (m_font != nullptr) { delete m_font; m_font = nullptr; } } BEGIN_MESSAGE_MAP(C8637ListCtrl, CListCtrl) ON_WM_NCPAINT() ON_WM_MEASUREITEM_REFLECT() END_MESSAGE_MAP() // C8637ListCtrl message handlers void C8637ListCtrl::PreSubclassWindow() { //use our custom CHeaderCtrl as long as there //is a headerctrl object to subclass if(GetHeaderCtrl()) { m_headerCtrl.SubclassWindow(GetHeaderCtrl()->m_hWnd); } CRect rcwin; GetWindowRect(rcwin); WINDOWPOS wp; wp.hwnd=GetSafeHwnd(); wp.cx=rcwin.Width(); wp.cy=rcwin.Height(); wp.flags=SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER; SendMessage(WM_WINDOWPOSCHANGED,0,(LPARAM)&wp); CListCtrl::PreSubclassWindow(); } void C8637ListCtrl::OnNcPaint() { // TODO: Add your message handler code here // Do not call CListCtrl::OnNcPaint() for painting messages } void C8637ListCtrl::MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct ) { lpMeasureItemStruct->itemHeight = 28; } void C8637ListCtrl::SetFontSelf( int nHeight, LPCTSTR lpszFacename ) { //先删除原有字体 if(m_font != NULL) delete m_font; m_font = new CFont; //创建字体 m_font->CreateFont( nHeight, // nHeight 0, // nWidth 0, // nEscapement 0, // nOrientation FW_NORMAL, // nWeight FALSE, // bItalic FALSE, // bUnderline 0, // cStrikeOut ANSI_CHARSET, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily lpszFacename); // lpszFacename //设置字体 SetFont(m_font, TRUE); } void C8637ListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { ASSERT(lpDrawItemStruct->CtlType == ODT_LISTVIEW); CDC dc; dc.Attach(lpDrawItemStruct->hDC); ASSERT(NULL != dc.GetSafeHdc()); // Save these value to restore them when done drawing. COLORREF crOldTextColor = dc.GetTextColor(); COLORREF crOldBkColor = dc.GetBkColor(); // If this item is selected, set the background color // and the text color to appropriate values. Also, erase // rect by filling it with the background color. if ((lpDrawItemStruct->itemAction | ODA_SELECT) && (lpDrawItemStruct->itemState & ODS_SELECTED)) { dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); dc.FillSolidRect(&lpDrawItemStruct->rcItem, ::GetSysColor(COLOR_HIGHLIGHT)); } else { if(lpDrawItemStruct->itemID%2) dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,255,250)); else dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,255,255)); } // If this item has the focus, draw a red frame around the // item's rect. if ((lpDrawItemStruct->itemAction | ODA_FOCUS) && (lpDrawItemStruct->itemState & ODS_FOCUS)) { CBrush br(RGB(0, 0, 128)); dc.FrameRect(&lpDrawItemStruct->rcItem, &br); } // Draw the text. CString strText(_T("")); CRect rcItem; for(int i=0; i<GetHeaderCtrl()->GetItemCount(); i++) { strText = GetItemText(lpDrawItemStruct->itemID, i); GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem); rcItem.left += 5; if (i<2) { dc.DrawText( strText, strText.GetLength(), &rcItem, DT_LEFT|DT_SINGLELINE|DT_VCENTER); } else { dc.DrawText( strText, strText.GetLength(), &rcItem, DT_CENTER|DT_SINGLELINE|DT_VCENTER); } } // Reset the background color and the text color back to their // original values. dc.SetTextColor(crOldTextColor); dc.SetBkColor(crOldBkColor); dc.Detach(); }
C8637HeaderCtrl.h
#pragma once // C8637HeaderCtrl class C8637HeaderCtrl : public CHeaderCtrl { DECLARE_DYNAMIC(C8637HeaderCtrl) public: C8637HeaderCtrl(); virtual ~C8637HeaderCtrl(); protected: DECLARE_MESSAGE_MAP() public: LRESULT OnLayout( WPARAM wParam, LPARAM lParam); virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); };
// C8637HeaderCtrl.cpp : implementation file // #include "stdafx.h" #include "C8637HeaderCtrl.h" // C8637HeaderCtrl IMPLEMENT_DYNAMIC(C8637HeaderCtrl, CHeaderCtrl) C8637HeaderCtrl::C8637HeaderCtrl() { } C8637HeaderCtrl::~C8637HeaderCtrl() { } BEGIN_MESSAGE_MAP(C8637HeaderCtrl, CHeaderCtrl) ON_MESSAGE(HDM_LAYOUT, OnLayout) END_MESSAGE_MAP() // C8637HeaderCtrl message handlers void C8637HeaderCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { ASSERT(lpDrawItemStruct-> CtlType == ODT_HEADER); HDITEM hdi; TCHAR lpBuffer[256]; hdi.mask = HDI_TEXT; hdi.pszText = lpBuffer; hdi.cchTextMax = 256; GetItem(lpDrawItemStruct-> itemID,&hdi); CDC* pDC; CPen pen, *pOldPen; pDC = CDC::FromHandle(lpDrawItemStruct-> hDC); pDC-> SetTextColor(RGB(0,0,0)); pDC-> SetBkColor(RGB(235,239,245)); CBrush brush; brush.CreateSolidBrush(RGB(235,239,245)); CRect rect = lpDrawItemStruct-> rcItem; //THIS FONT IS ONLY FOR DRAWING AS LONG AS WE DON'T DO A SetFont(...) CBrush *pOldBrush=pDC-> SelectObject(&brush); rect.top-=0,rect.right+=1; pDC-> FillRect(&rect,&brush); pen.CreatePen(PS_SOLID, 1, RGB(220,220,220)); pOldPen = pDC->SelectObject(&pen); pDC->Rectangle(&rect);//Draw border pDC->SelectObject(pOldPen); pDC-> SelectObject(pOldBrush); pDC-> SelectObject(GetStockObject(DEFAULT_GUI_FONT)); //DRAW THE TEXT CFont font; font.CreatePointFont(116,L"黑体",pDC); CFont *pFont = pDC->SelectObject(&font); lpDrawItemStruct-> rcItem.top += 8; ::DrawText(lpDrawItemStruct->hDC,lpBuffer, wcslen(lpBuffer), &lpDrawItemStruct->rcItem,DT_VCENTER|DT_CENTER); pDC->SelectObject(pFont); //pDC-> SelectStockObject(SYSTEM_FONT); } LRESULT C8637HeaderCtrl::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; int nHeight = 32; pwpos->cy = nHeight; prc->top = nHeight; return lResult; }