`
dato0123
  • 浏览: 940024 次
文章分类
社区版块
存档分类
最新评论

自定义ListCtrl中设置背景图片的问题

 
阅读更多

自定义的列表控件必须是自绘制的,因此需要在资源编辑器中设置LVS_OWNERDRAWFIXED标志,而且还必须在自定义的控件类中实现DrawItem函数。

200781701.jpg


<?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
}

效果如图所示:
200781702.jpg

但是这里还有一个问题,就是当下拉滚动条的时候,如何让背景图片不动,而只是数据行变化,这是接下来要做的工作。

参考资料:

http://www.codeguru.com/Cpp/controls/listview/backgroundcolorandimage/article.php/c983/

分享到:
评论

相关推荐

    ListCtrl中插入图片,按钮,右键菜单,Edit控件等

    在ListCtrl中插入图片通常通过设置LVS_ICON或LVS_SMALLICON样式来实现,然后使用SetItemState函数设置每行对应的图标。另外,可以使用LVITEM结构体来传递图像索引,并使用ImageList对象管理这些图像。记得在创建...

    ListCtrl设置单元格颜色

    本篇文章将深入探讨如何在`ListCtrl`中设置单元格颜色以及更改单元格状态,以实现更丰富的视觉效果和用户体验。 首先,我们需要了解`ListCtrl`的基本结构。`ListCtrl`通常用于显示多列数据,每一列可以有不同的数据...

    【最新】MFC, CListCtrl 自定义字体、颜色和背景

    本教程将深入探讨如何在MFC中自定义CListCtrl的字体、颜色以及背景,使其更具个性化和可读性。 首先,了解CListCtrl的基本结构。CListCtrl通常包含多列,每列可以有不同的标题,数据行在各列中显示不同的信息。为了...

    改变listctrl 单元格背景及文字颜色(非重写控件)

    标题“改变listctrl 单元格背景及文字颜色(非重写控件)”指的是在不重新定义或重载`CListCtrl`类原有功能的情况下,实现对列表视图控件中单个单元格的背景色和文字颜色的自定义。这通常涉及到低级绘图技术,如消息...

    VC6 自制ListCtrl类 解决闪烁

    在封装自定义ListCtrl类时,可以按照以上思路进行设计和实现。具体步骤可能包括以下部分: 1. **创建自定义类**:基于`CListCtrl`创建一个新的派生类,例如`CMyListCtrl`。 2. **覆盖OnPaint**:重写`OnPaint`函数...

    可设置行高及每行颜色的ListCtrl

    在Windows编程中,`ListCtrl` 是一个常用的控件,常用于显示列表数据,它可以在对话框、窗口或工具栏中使用。`ListCtrl` 支持多种视图模式,如报告视图、小图标视图、大图标视图和列表视图。在这个特定的情况下,...

    MFC在ListCtrl中加入Button

    在MFC(Microsoft Foundation Classes)框架中,ListCtrl是一个非常常用的控件,它通常用于显示列表数据,可以自定义列头、图标等。然而,仅靠ListCtrl本身的特性,我们无法直接在其中添加按钮。但是,通过一些技巧...

    自绘ListCtrl列表控件

    1. **创建ListCtrl控件**:在资源编辑器中添加ListCtrl控件,并设置其视图模式为LV_VIEW_REPORT,以便显示表格样式的数据。 2. **定义列表列头**:使用InsertColumn()函数插入列头,指定列标题和宽度。 3. **添加...

    mfc的listctrl

    本文将深入探讨MFC中的ListCtrl控件,重点在于自定义绘制(自绘)、项的高度、颜色设置以及如何添加编辑功能。 ListCtrl是MFC中的一个视图类,它继承自CListView,主要用于展示列表数据。它可以显示多列,并且每一...

    wxpython控件之Listctrl

    ### wxPython中的ListCtrl控件详解 #### 一、引言 `ListCtrl`是wxPython库中的一个重要组件,用于创建列表控件。它可以展示多种类型的列表格式,如单列表、报表、带图片的列表等,并且具备强大的自定义功能。本文将...

    ListCtrl 数据修改 添加 删除

    在Windows编程中,ListCtrl和ComboBox是两种常用的控件,它们在GUI应用程序中扮演着重要的角色。ListCtrl常用于显示列表形式的数据,而ComboBox则提供下拉列表供用户选择。本篇文章将深入探讨如何在ListCtrl中进行...

    设置ListCtrl空间行列背景颜色

    在实际应用中,我们常常需要自定义ListCtrl的显示效果,例如改变行或列的背景颜色,以增强视觉效果或突出特定数据。本篇将详细讲解如何在CListCtrl中设置行和列的背景颜色。 首先,了解CListCtrl的基本结构。...

    mfc自定义的listctrl 功能类似表格

    压缩包中的"MyGrid"可能是这个自定义ListCtrl的实现源码或者编译后的动态链接库(DLL)。通过查看和学习这些代码,你可以深入了解如何扩展MFC的CListCtrl,以及如何根据自己的需求定制控件。如果你正在开发一个需要...

    ListCtrl内嵌按钮及其响应

    `ListCtrl`是Windows操作系统中常见的控件,通常用于展示带有多个列的列表数据,常用于文件管理器或应用程序设置界面。通过自定义绘制功能,我们可以为`ListCtrl`增添更多个性化的设计,例如调整表头和单元格的样式...

    ListCtrl列表框重绘

    重绘ListCtrl主要涉及两个方面:一是自定义项绘制,二是自定义背景绘制。自定义项绘制可以通过重载OnDrawItem函数来实现,这个函数会在每个列表项需要绘制时被调用。在这里,你可以使用CDC(Device Context)对象来...

    自定义listcontrl单行颜色

    在Windows编程中,ListView控件(ListCtrl...通过阅读和理解这些源代码,你可以深入学习如何在MFC环境中自定义ListCtrl控件,实现单行颜色的变化。这是一个很好的实践案例,可以帮助你掌握Windows编程和MFC的相关知识。

    基于ListCtrl的列表表格

    本文将深入探讨如何利用MFC中的ListCtrl控件来创建功能丰富的列表表格,包括显示图标、设置背景色、实现列排序以及点击编辑等功能。 ListCtrl是MFC库中的一种视图类,它是Windows标准的ListView控件的包装。这个...

    在ListCtrl控件的report方式头上添加背景.rar_List 控件 背景_listctr_listctrl

    总的来说,为ListCtrl的report模式表头添加背景涉及对Windows消息的响应、自定义绘图以及图形操作。理解这些概念并熟练应用,可以使你的ListCtrl控件更加个性化,提升用户界面的视觉效果。在实际开发过程中,可以...

    关于LIstCtrl的一些总结

    - 可以通过重绘事件(`OnDraw()`)来自定义`ListCtrl`的外观效果,比如添加背景图片或改变字体颜色。 6. **多线程访问**: - 如果在非UI线程中操作`ListCtrl`,需使用消息队列或`CSingleLock`等同步机制确保线程...

    Listctrl重绘

    3. 行高调整:ListCtrl默认的行高可能无法满足所有需求,比如要展示多行文本或图片。我们可以使用CListCtrl的SetItemHeight()函数来改变特定行的行高,或者通过重写OnMeasureItem()来动态计算行高。 4. 字体颜色和...

Global site tag (gtag.js) - Google Analytics