自定义的列表控件必须是自绘制的,因此需要在资源编辑器中设置LVS_OWNERDRAWFIXED标志,而且还必须在自定义的控件类中实现DrawItem函数。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
代码如下:
classCListCtrlEx:publicCListCtrl
{
//Construction
public:
CListCtrlEx();
public:
CPalettem_pal;//调色板
CBitmapm_bitmap;//背景位图
intm_cxBitmap,m_cyBitmap;//背景位图高度,宽度信息
intm_nHighlight;//高亮方式
BOOLSetBkImage(LPCTSTRlpszResourceName);//设置背景图片
BOOLSetBkImage(UINTnIDResource);
intGetColumnCount();//获取列数目
voidAdjustColumnWidth();//调整列宽
//Operations
public:
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CListCtrlEx)
//}}AFX_VIRTUAL
//Implementation
public:
virtual~CListCtrlEx();
//Generatedmessagemapfunctions
protected:
//{{AFX_MSG(CListCtrlEx)
afx_msgvoidOnHScroll(UINTnSBCode,UINTnPos,CScrollBar*pScrollBar);//水平滚动
afx_msgvoidOnVScroll(UINTnSBCode,UINTnPos,CScrollBar*pScrollBar);//垂直滚动
afx_msgBOOLOnEraseBkgnd(CDC*pDC);//擦除背景
afx_msgvoidOnPaletteChanged(CWnd*pFocusWnd);//调色板更改
afx_msgBOOLOnQueryNewPalette();//查询新调色板
afx_msgBOOLOnNotify(WPARAMwParam,LPARAMlParam,LRESULT*pResult);
//}}AFX_MSG
virtualvoidDrawItem(LPDRAWITEMSTRUCTlpDrawItemStruct);//画每一行
DECLARE_MESSAGE_MAP()
};
/**////////////////////////////////////////////////////////////////////////////////CListCtrlEx
CListCtrlEx::CListCtrlEx()
{
m_nHighlight=0;
}
CListCtrlEx::~CListCtrlEx()
{
}
BEGIN_MESSAGE_MAP(CListCtrlEx,CListCtrl)
//{{AFX_MSG_MAP(CListCtrlEx)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_ERASEBKGND()
ON_WM_PALETTECHANGED()
ON_WM_QUERYNEWPALETTE()//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/**////////////////////////////////////////////////////////////////////////////////CListCtrlExmessagehandlers
BOOLCListCtrlEx::SetBkImage(UINTnIDResource)
{
returnSetBkImage((LPCTSTR)nIDResource);
}
BOOLCListCtrlEx::SetBkImage(LPCTSTRlpszResourceName)
{
//IfthisisnotthefirstcallthenDeleteGDIobjects
if(m_bitmap.m_hObject!=NULL)
m_bitmap.DeleteObject();
if(m_pal.m_hObject!=NULL)
m_pal.DeleteObject();
HBITMAPhBmp=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),
lpszResourceName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);
if(hBmp==NULL)
returnFALSE;
m_bitmap.Attach(hBmp);
BITMAPbm;
m_bitmap.GetBitmap(&bm);
m_cxBitmap=bm.bmWidth;
m_cyBitmap=bm.bmHeight;
//Createalogicalpaletteforthebitmap
DIBSECTIONds;
BITMAPINFOHEADER&bmInfo=ds.dsBmih;
m_bitmap.GetObject(sizeof(ds),&ds);
intnColors=bmInfo.biClrUsed?bmInfo.biClrUsed:1<<bmInfo.biBitCount;
//Createahalftonepaletteifcolors>256.
CClientDCdc(NULL);//DesktopDC
if(nColors>256)
m_pal.CreateHalftonePalette(&dc);
else
{
//Createthepalette
RGBQUAD*pRGB=newRGBQUAD[nColors];
CDCmemDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(&m_bitmap);
::GetDIBColorTable(memDC,0,nColors,pRGB);
UINTnSize=sizeof(LOGPALETTE)+(sizeof(PALETTEENTRY)*nColors);
LOGPALETTE*pLP=(LOGPALETTE*)newBYTE[nSize];
pLP->palVersion=0x300;
pLP->palNumEntries=nColors;
for(inti=0;i<nColors;i++)
{
pLP->palPalEntry[i].peRed=pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen=pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue=pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags=0;
}
m_pal.CreatePalette(pLP);
delete[]pLP;
delete[]pRGB;
}
Invalidate();
returnTRUE;
}
voidCListCtrlEx::OnHScroll(UINTnSBCode,UINTnPos,CScrollBar*pScrollBar)
{
//TODO:Addyourmessagehandlercodehereand/orcalldefault
if(m_bitmap.m_hObject!=NULL)
InvalidateRect(NULL);
CListCtrl::OnHScroll(nSBCode,nPos,pScrollBar);
}
voidCListCtrlEx::OnVScroll(UINTnSBCode,UINTnPos,CScrollBar*pScrollBar)
{
//TODO:Addyourmessagehandlercodehereand/orcalldefault
if(m_bitmap.m_hObject!=NULL)
InvalidateRect(NULL);
CListCtrl::OnVScroll(nSBCode,nPos,pScrollBar);
}
BOOLCListCtrlEx::OnEraseBkgnd(CDC*pDC)
{
//TODO:Addyourmessagehandlercodehereand/orcalldefault
if(m_bitmap.m_hObject!=NULL)
returnTRUE;
returnCListCtrl::OnEraseBkgnd(pDC);
}
voidCListCtrlEx::OnPaletteChanged(CWnd*pFocusWnd)
{
CListCtrl::OnPaletteChanged(pFocusWnd);
//TODO:Addyourmessagehandlercodehere
if(pFocusWnd==this)
return;
OnQueryNewPalette();
}
BOOLCListCtrlEx::OnQueryNewPalette()
{
//TODO:Addyourmessagehandlercodehereand/orcalldefault
CClientDCdc(this);
if(dc.GetDeviceCaps(RASTERCAPS)&RC_PALETTE&&m_pal.m_hObject!=NULL)
{
dc.SelectPalette(&m_pal,FALSE);
BOOLresult=dc.RealizePalette();
if(result)
Invalidate();
returnresult;
}
returnCListCtrl::OnQueryNewPalette();
}
voidCListCtrlEx::DrawItem(LPDRAWITEMSTRUCTlpDrawItemStruct)
{
CDC*pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
CRectrcItem(lpDrawItemStruct->rcItem);
intnItem=lpDrawItemStruct->itemID;
CImageList*pImageList;
//Savedcstate
intnSavedDC=pDC->SaveDC();
//Getitemimageandstateinfo
LV_ITEMlvi;
lvi.mask=LVIF_IMAGE|LVIF_STATE;
lvi.iItem=nItem;
lvi.iSubItem=0;
lvi.stateMask=0xFFFF;//getallstateflags
GetItem(&lvi);
//Shouldtheitembehighlighted
BOOLbHighlight=((lvi.state&LVIS_DROPHILITED)||((lvi.state&LVIS_SELECTED)&&((GetFocus()==this)||
(GetStyle()&LVS_SHOWSELALWAYS))));
//Getrectanglesfordrawing
CRectrcBounds,rcLabel,rcIcon;
GetItemRect(nItem,rcBounds,LVIR_BOUNDS);
GetItemRect(nItem,rcLabel,LVIR_LABEL);
GetItemRect(nItem,rcIcon,LVIR_ICON);
CRectrcCol(rcBounds);
CStringsLabel=GetItemText(nItem,0);
//Labelsareoffsetbyacertainamount
//Thisoffsetisrelatedtothewidthofaspacecharacter
intoffset=pDC->GetTextExtent(_T(""),1).cx*2;
CRectrcHighlight;
CRectrcClient;
intnExt;
switch(m_nHighlight)
{
case0:
nExt=pDC->GetOutputTextExtent(sLabel).cx+offset;
rcHighlight=rcLabel;
//if(rcLabel.left+nExt
if(m_bitmap.m_hObject!=NULL)
{
CDCtempDC;
tempDC.CreateCompatibleDC(pDC);
tempDC.SelectObject(&m_bitmap);
GetClientRect(&rcClient);
CRgnrgnBitmap;
CRectrcTmpBmp(rcItem);
rcTmpBmp.right=rcClient.right;
//Wealsoneedtocheckwhetheritisthelastitem
//Theupdateregionhastobeextendedtothebottomifitis
if(nItem==GetItemCount()-1)
rcTmpBmp.bottom=rcClient.bottom;
rgnBitmap.CreateRectRgnIndirect(&rcTmpBmp);
pDC->SelectClipRgn(&rgnBitmap);
rgnBitmap.DeleteObject();
if(pDC->GetDeviceCaps(RASTERCAPS)&RC_PALETTE&&m_pal.m_hObject!=NULL)
{
pDC->SelectPalette(&m_pal,FALSE);
pDC->RealizePalette();
}
CRectrcFirstItem;
GetItemRect(0,rcFirstItem,LVIR_BOUNDS);
for(inti=rcFirstItem.left;i<rcTmpBmp.right;i+=m_cxBitmap)
for(intj=rcFirstItem.top;j<rcTmpBmp.bottom;j+=m_cyBitmap)
pDC->BitBlt(i,j,m_cxBitmap,m_cyBitmap,&tempDC,0,0,SRCCOPY);
}
}
//Drawthebackgroundcolor
if(bHighlight)
{
pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(rcHighlight,&CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
}
elseif(m_bitmap.m_hObject==NULL)
pDC->FillRect(rcHighlight,&CBrush(::GetSysColor(COLOR_WINDOW)));
//Setclipregion
rcCol.right=rcCol.left+GetColumnWidth(0);
CRgnrgn;
rgn.CreateRectRgnIndirect(&rcCol);
pDC->SelectClipRgn(&rgn);
rgn.DeleteObject();
//Drawstateicon
if(lvi.state&LVIS_STATEIMAGEMASK)
{
intnImage=((lvi.state&LVIS_STATEIMAGEMASK)>>12)-1;
pImageList=GetImageList(LVSIL_STATE);
if(pImageList)
{
pImageList->Draw(pDC,nImage,
CPoint(rcCol.left,rcCol.top),ILD_TRANSPARENT);
}
}
//Drawnormalandoverlayicon
pImageList=GetImageList(LVSIL_SMALL);
if(pImageList)
{
UINTnOvlImageMask=lvi.state&LVIS_OVERLAYMASK;
pImageList->Draw(pDC,lvi.iImage,
CPoint(rcIcon.left,rcIcon.top),
(bHighlight?ILD_BLEND50:0)|ILD_TRANSPARENT|nOvlImageMask);
}
//Drawitemlabel-Column0
rcLabel.left+=offset/2;
rcLabel.right-=offset;
pDC->DrawText(sLabel,-1,rcLabel,DT_LEFT|DT_SINGLELINE|DT_NOPREFIX|DT_NOCLIP
|DT_VCENTER|DT_END_ELLIPSIS);
//Drawlabelsforremainingcolumns
LV_COLUMNlvc;
lvc.mask=LVCF_FMT|LVCF_WIDTH;
if(m_nHighlight==0)//Highlightonlyfirstcolumn
{
pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
pDC->SetBkColor(::GetSysColor(COLOR_WINDOW));
}
rcBounds.right=rcHighlight.right>rcBounds.right?rcHighlight.right:
rcBounds.right;
rgn.CreateRectRgnIndirect(&rcBounds);
pDC->SelectClipRgn(&rgn);
for(intnColumn=1;GetColumn(nColumn,&lvc);nColumn++)
{
rcCol.left=rcCol.right;
rcCol.right+=lvc.cx;
//Drawthebackgroundifneeded&&m_nHighlight==HIGHLIGHT_NORMAL
if(m_bitmap.m_hObject==NULL)
pDC->FillRect(rcCol,&CBrush(::GetSysColor(COLOR_WINDOW)));
sLabel=GetItemText(nItem,nColumn);
if(sLabel.GetLength()==0)
continue;
//Getthetextjustification
UINTnJustify=DT_LEFT;
switch(lvc.fmt&LVCFMT_JUSTIFYMASK)
{
caseLVCFMT_RIGHT:
nJustify=DT_RIGHT;
break;
caseLVCFMT_CENTER:
nJustify=DT_CENTER;
break;
default:
break;
}
rcLabel=rcCol;
rcLabel.left+=offset;
rcLabel.right-=offset;
pDC->DrawText(sLabel,-1,rcLabel,nJustify|DT_SINGLELINE
|DT_NOPREFIX|DT_VCENTER|DT_END_ELLIPSIS);
}
//Drawfocusrectangleifitemhasfocus
if(lvi.state&LVIS_FOCUSED&&(GetFocus()==this))
pDC->DrawFocusRect(rcHighlight);
//Restoredc
pDC->RestoreDC(nSavedDC);
}
voidCListCtrlEx::AdjustColumnWidth()
{
SetRedraw(FALSE);
intnColumnCount=GetColumnCount();
for(inti=0;i<nColumnCount;i++)
{
SetColumnWidth(i,LVSCW_AUTOSIZE);
intnColumnWidth=GetColumnWidth(i);
SetColumnWidth(i,LVSCW_AUTOSIZE_USEHEADER);
intnHeaderWidth=GetColumnWidth(i);
SetColumnWidth(i,max(nColumnWidth,nHeaderWidth));
}
SetRedraw(TRUE);
}
intCListCtrlEx::GetColumnCount()
{
CHeaderCtrl*pHeaderCtrl=GetHeaderCtrl();
return(pHeaderCtrl->GetItemCount());
}
BOOLCListCtrlEx::OnNotify(WPARAMwParam,LPARAMlParam,LRESULT*pResult)
{
HD_NOTIFY*pHDN=(HD_NOTIFY*)lParam;
//Thiscodeisforusingbitmapinthebackground
//Invalidatetherightsideofthecontrolwhenacolumnisresized
if(pHDN->hdr.code==HDN_ITEMCHANGINGW||pHDN->hdr.code==HDN_ITEMCHANGINGA)
{
if(m_bitmap.m_hObject!=NULL)
{
CRectrcClient;
GetClientRect(&rcClient);
DWORDdwPos=GetMessagePos();
CPointpt(LOWORD(dwPos),HIWORD(dwPos));
ScreenToClient(&pt);
rcClient.left=pt.x;
InvalidateRect(&rcClient);
}
}
returnCListCtrl::OnNotify(wParam,lParam,pResult);
}
BOOLCCdDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//Add"About"menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
m_list.InsertColumn(0,_T("用户编号"));
m_list.InsertColumn(1,_T("用户名称"));
m_list.InsertColumn(2,_T("年龄"));
m_list.InsertColumn(3,_T("性别"));
m_list.InsertColumn(4,_T("用户住址"));
charch[5];
for(intj=1;j<=200;j++)
{
m_list.InsertItem(j,itoa(j,ch,10));
}
for(inti=0;i<200;i++)
{
m_list.SetItemText(i,1,strcat(itoa(i+1,ch,10),"号用户"));
m_list.SetItemText(i,2,itoa((i+100)%100,ch,10));
if(i%2==0)
{
m_list.SetItemText(i,3,"男");
}
else
{
m_list.SetItemText(i,3,"女");
}
m_list.SetItemText(i,4,strcat(itoa(i+1,ch,10),"号大街"));
}
ListView_SetExtendedListViewStyle(m_list.m_hWnd,LVS_EX_FULLROWSELECT|LVS_EX_FLATSB|LVS_EX_HEADERDRAGDROP);
m_list.SetBkImage(IDB_Bless);
m_list.AdjustColumnWidth();
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
效果如图所示:
但是这里还有一个问题,就是当下拉滚动条的时候,如何让背景图片不动,而只是数据行变化,这是接下来要做的工作。
参考资料:
http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/
分享到:
相关推荐
在ListCtrl中插入图片通常通过设置LVS_ICON或LVS_SMALLICON样式来实现,然后使用SetItemState函数设置每行对应的图标。另外,可以使用LVITEM结构体来传递图像索引,并使用ImageList对象管理这些图像。记得在创建...
本篇文章将深入探讨如何在`ListCtrl`中设置单元格颜色以及更改单元格状态,以实现更丰富的视觉效果和用户体验。 首先,我们需要了解`ListCtrl`的基本结构。`ListCtrl`通常用于显示多列数据,每一列可以有不同的数据...
本教程将深入探讨如何在MFC中自定义CListCtrl的字体、颜色以及背景,使其更具个性化和可读性。 首先,了解CListCtrl的基本结构。CListCtrl通常包含多列,每列可以有不同的标题,数据行在各列中显示不同的信息。为了...
标题“改变listctrl 单元格背景及文字颜色(非重写控件)”指的是在不重新定义或重载`CListCtrl`类原有功能的情况下,实现对列表视图控件中单个单元格的背景色和文字颜色的自定义。这通常涉及到低级绘图技术,如消息...
在封装自定义ListCtrl类时,可以按照以上思路进行设计和实现。具体步骤可能包括以下部分: 1. **创建自定义类**:基于`CListCtrl`创建一个新的派生类,例如`CMyListCtrl`。 2. **覆盖OnPaint**:重写`OnPaint`函数...
在Windows编程中,`ListCtrl` 是一个常用的控件,常用于显示列表数据,它可以在对话框、窗口或工具栏中使用。`ListCtrl` 支持多种视图模式,如报告视图、小图标视图、大图标视图和列表视图。在这个特定的情况下,...
在MFC(Microsoft Foundation Classes)框架中,ListCtrl是一个非常常用的控件,它通常用于显示列表数据,可以自定义列头、图标等。然而,仅靠ListCtrl本身的特性,我们无法直接在其中添加按钮。但是,通过一些技巧...
1. **创建ListCtrl控件**:在资源编辑器中添加ListCtrl控件,并设置其视图模式为LV_VIEW_REPORT,以便显示表格样式的数据。 2. **定义列表列头**:使用InsertColumn()函数插入列头,指定列标题和宽度。 3. **添加...
本文将深入探讨MFC中的ListCtrl控件,重点在于自定义绘制(自绘)、项的高度、颜色设置以及如何添加编辑功能。 ListCtrl是MFC中的一个视图类,它继承自CListView,主要用于展示列表数据。它可以显示多列,并且每一...
### wxPython中的ListCtrl控件详解 #### 一、引言 `ListCtrl`是wxPython库中的一个重要组件,用于创建列表控件。它可以展示多种类型的列表格式,如单列表、报表、带图片的列表等,并且具备强大的自定义功能。本文将...
在Windows编程中,ListCtrl和ComboBox是两种常用的控件,它们在GUI应用程序中扮演着重要的角色。ListCtrl常用于显示列表形式的数据,而ComboBox则提供下拉列表供用户选择。本篇文章将深入探讨如何在ListCtrl中进行...
在实际应用中,我们常常需要自定义ListCtrl的显示效果,例如改变行或列的背景颜色,以增强视觉效果或突出特定数据。本篇将详细讲解如何在CListCtrl中设置行和列的背景颜色。 首先,了解CListCtrl的基本结构。...
压缩包中的"MyGrid"可能是这个自定义ListCtrl的实现源码或者编译后的动态链接库(DLL)。通过查看和学习这些代码,你可以深入了解如何扩展MFC的CListCtrl,以及如何根据自己的需求定制控件。如果你正在开发一个需要...
`ListCtrl`是Windows操作系统中常见的控件,通常用于展示带有多个列的列表数据,常用于文件管理器或应用程序设置界面。通过自定义绘制功能,我们可以为`ListCtrl`增添更多个性化的设计,例如调整表头和单元格的样式...
重绘ListCtrl主要涉及两个方面:一是自定义项绘制,二是自定义背景绘制。自定义项绘制可以通过重载OnDrawItem函数来实现,这个函数会在每个列表项需要绘制时被调用。在这里,你可以使用CDC(Device Context)对象来...
在Windows编程中,ListView控件(ListCtrl...通过阅读和理解这些源代码,你可以深入学习如何在MFC环境中自定义ListCtrl控件,实现单行颜色的变化。这是一个很好的实践案例,可以帮助你掌握Windows编程和MFC的相关知识。
本文将深入探讨如何利用MFC中的ListCtrl控件来创建功能丰富的列表表格,包括显示图标、设置背景色、实现列排序以及点击编辑等功能。 ListCtrl是MFC库中的一种视图类,它是Windows标准的ListView控件的包装。这个...
总的来说,为ListCtrl的report模式表头添加背景涉及对Windows消息的响应、自定义绘图以及图形操作。理解这些概念并熟练应用,可以使你的ListCtrl控件更加个性化,提升用户界面的视觉效果。在实际开发过程中,可以...
- 可以通过重绘事件(`OnDraw()`)来自定义`ListCtrl`的外观效果,比如添加背景图片或改变字体颜色。 6. **多线程访问**: - 如果在非UI线程中操作`ListCtrl`,需使用消息队列或`CSingleLock`等同步机制确保线程...
3. 行高调整:ListCtrl默认的行高可能无法满足所有需求,比如要展示多行文本或图片。我们可以使用CListCtrl的SetItemHeight()函数来改变特定行的行高,或者通过重写OnMeasureItem()来动态计算行高。 4. 字体颜色和...