分类:
2008-10-14 14:51:33
修改一个完全颜色的CListCtrl类
作者:
在使用CListCtrl控件的过程中,我们会发现使用及其不方便,特别是在使用“report"显示模式时,
想给指定条目添加背景颜色,CListCtrl控件所提供的设置颜色函数只能使得控件的界面变得好看一些,根本不能满足我们的要求,我们无法把特定的一项或几项添加上不同的颜色以示区别。
幸运的是很多VC的使用者在改造CListCtrl类,使之更加功能强大上做了很多工作,开发出了各种各样的继承类来实现这个功能,Sven
Freitag 就是其中的一员。他开发出了CListCtrl的继承类CColorListCtrl来实现给指定的条目加背景色的功能,并无偿的在网上公布给VC的使用者,我在源代码中收集了他的源程序,各位读者可以先阅读学习一下。
CColorListCtrl类示例代码运行效果如下图所示:
怎样使用CColorListCtrl类:
1、把下面的文件加入你的工程中去:
color.h color.cpp ColorListCtrl.h ColorListCtrl.cpp
2、在对话框头文件中加入ColorListCtrl.h的说明,然后用CColorListCtrl代替CListCtrl声明成员变量。
3、具体的使用方法,请看示例代码中的ColoredListCtrlDlg.cpp文件。
CColorListCtrl类存在的不足:
在使用CColorListCtrl类的过程中,我体会到了随意添加条目颜色的乐趣,但同时也发现它存在的一些不足之处。下面我列出color.h和color.cpp文件代码来进行分析。color.h源代码如下所示:
// Author: SFr frydaysoft@gmx.de #ifndef AFX_COLOR_H__9FC7D36B_FC88_42FD_8DAA_2F70016038BA__INCLUDED_ #define AFX_COLOR_H__9FC7D36B_FC88_42FD_8DAA_2F70016038BA__INCLUDED_ #include "windows.h" typedef enum { DEF_BACKGROUND=0, DEF_TEXT, DEF_SELBACKGROUND, DEF_SELTEXT, DEF_DESELBACKGROUND, DEF_DESELTEXT, BLACK,BLUE,GREEN,CYAN,RED, MANGENTA,YELLOW,WHITE,DARKBLUE,DARKGREEN, BLUEGREEN,BROWN,PURPUR,OLIV,DARKGRAY, LIGHTGRAY,LIGHTBLUE,DARKWHITE,MIDDLEGRAY } ITEM_COLOR; typedef struct { char str[50]; ITEM_COLOR col; }ColorList; #define COLLIST_MAX 25 extern ColorList colList[COLLIST_MAX]; COLORREF GetColorRef(ITEM_COLOR lParam); #endif color.cpp源代码如下所示: // Author: SFr frydaysoft@gmx.de #include "stdafx.h" #include "color.h" ColorList colList[COLLIST_MAX]= { {"DEF_BACKGROUND",DEF_BACKGROUND}, {"DEF_TEXT",DEF_TEXT}, {"DEF_SELBACKGROUND",DEF_SELBACKGROUND}, {"DEF_SELTEXT",DEF_SELTEXT}, {"DEF_DESELBACKGROUND",DEF_DESELBACKGROUND}, {"DEF_DESELTEXT",DEF_DESELTEXT}, {"BLACK",BLACK}, {"BLUE",BLUE}, {"GREEN",GREEN}, {"CYAN",CYAN}, {"RED",RED}, {"MANGENTA",MANGENTA}, {"YELLOW",YELLOW}, {"WHITE",WHITE}, {"DARKBLUE",DARKBLUE}, {"DARKGREEN",DARKGREEN}, {"BLUEGREEN",BLUEGREEN}, {"BROWN",BROWN}, {"PURPUR",PURPUR}, {"OLIV",OLIV}, {"DARKGRAY",DARKGRAY}, {"LIGHTGRAY",LIGHTGRAY}, {"LIGHTBLUE",LIGHTBLUE}, {"DARKWHITE",DARKWHITE}, {"MIDDLEGRAY",MIDDLEGRAY} }; COLORREF GetColorRef(ITEM_COLOR lParam) { switch (lParam) { case DEF_BACKGROUND: return ::GetSysColor(COLOR_WINDOW); break; case DEF_TEXT: return ::GetSysColor(COLOR_WINDOWTEXT); break; case DEF_SELBACKGROUND: return ::GetSysColor(COLOR_ACTIVECAPTION); break; case DEF_SELTEXT: return ::GetSysColor(COLOR_HIGHLIGHTTEXT); break; case DEF_DESELBACKGROUND: return ::GetSysColor(COLOR_INACTIVECAPTION); break; case DEF_DESELTEXT: return ::GetSysColor(COLOR_INACTIVECAPTIONTEXT ); break; case BLACK: return RGB(0,0,0); break; //black case BLUE: return RGB(0,0,255); break; //blue case GREEN: return RGB(0,255,0); break; //green case CYAN: return RGB(0,255,255); break; //cyan case RED: return RGB(255,0,0); break; //red case MANGENTA: return RGB(255,0,255); break; //mangenta case YELLOW: return RGB(255,255,0); break; //yellow case WHITE: return RGB(255,255,255);break; //white case DARKBLUE: return RGB(0,0,128); break; //dark-blue case DARKGREEN: return RGB(0,128,0); break; //dark-green case BLUEGREEN: return RGB(0,128,128); break; //blue-green case BROWN: return RGB(128,0,0); break; //brown case PURPUR: return RGB(128,0,128); break; //purpur case OLIV: return RGB(128,128,0); break; //oliv case DARKGRAY: return RGB(128,128,128);break; //dark-gray case LIGHTGRAY: return RGB(192,192,192);break; //light-gray case LIGHTBLUE: return RGB(166,202,240);break; //light-blue case DARKWHITE: return RGB(255,251,240);break; //dark-white case MIDDLEGRAY: return RGB(160,160,164);break; //middle-gray default: return RGB(0,128,0); break; //dark-green } }由上述源代码可以看出,CColorListCtrl类给我们提供的可供填充的颜色数量十分有限,只有BLACK,BLUE,GREEN,CYAN,RED,MANGENTA,YELLOW,WHITE,DARKBLUE,DARKGREEN,BLUEGREEN,BROWN,PURPUR,
ITEM_COLOR *m_pBackColor; ITEM_COLOR *m_pTextColor; m_pBackColor=new ITEM_COLOR[column_count]; m_pTextColor=new ITEM_COLOR[column_count]; BOOL SetBackColor(ITEM_COLOR color, int iSub) { if (iSub修改后的代码: COLORREF *m_pBackColor; COLORREF *m_pTextColor; m_pBackColor=new COLORREF[column_count]; m_pTextColor=new COLORREF[column_count]; BOOL SetBackColor(COLORREF color, int iSub) { if (iSub4、在类CColorListCtrl的定义和函数说明中进行如下修改: 源代码: BOOL SetItemTextColor(ITEM_COLOR color, int Index, int iSub); BOOL SetItemBackgndColor(ITEM_COLOR color, int Index, int iSub); BOOL CColorListCtrl::SetItemBackgndColor(ITEM_COLOR color, int Index, int iSub) BOOL CColorListCtrl::SetItemTextColor(ITEM_COLOR color, int Index, int iSub)修改后的代码:BOOL SetItemTextColor(COLORREF color, int Index, int iSub); BOOL SetItemBackgndColor(COLORREF color, int Index, int iSub); BOOL CColorListCtrl::SetItemBackgndColor(COLORREF color, int Index, int iSub) BOOL CColorListCtrl::SetItemTextColor(COLORREF color, int Index, int iSub)删除的源代码:// only for TEST if (ret_index<3) { p->SetBackColor(ITEM_COLOR(ret_index+BLUE),0); p->SetTextColor(ITEM_COLOR(ret_index+RED ),0); } else if (ret_index<=6) { p->SetBackColor(ITEM_COLOR(ret_index+BLUE),1); p->SetTextColor(ITEM_COLOR(ret_index+RED ),1); } else { p->SetBackColor(ITEM_COLOR((ret_index+BLUE)&0xF),2); p->SetTextColor(ITEM_COLOR((ret_index+RED )&0xF),2); } // end: only for TEST5、替换如下所示的代码:DEF_BACKGROUND替换成::GetSysColor(COLOR_WINDOW); DEF_TEXT替换成::GetSysColor(COLOR_WINDOWTEXT); GetColorRef(DEF_DESELTEXT)替换成::GetSysColor(COLOR_HIGHLIGHTTEXT); GetColorRef(DEF_SELBACKGROUND)替换成::GetSysColor(COLOR_ACTIVECAPTION); GetColorRef(DEF_SELTEXT)替换成::GetSysColor(COLOR_HIGHLIGHTTEXT); GetColorRef(DEF_DESELBACKGROUND)替换成::GetSysColor(COLOR_INACTIVECAPTION); pDC->SetTextColor(pMyLParam->GetTextColor(DEF_DESELTEXT))替换成pDC->SetTextColor(pMyLParam->GetTextColor(5));修改后的示例程序如下图所示,基本功能与原来的程序一样。
本来我还计划把对CListCtrl类的排序功能加入其中,可是到实现的时候才发现异常复杂,因为在CListCtrl控件的“More Style”属性中已选中“Owner draw fixed”选项,对CListCtrl控件颜色的修改实际上是通过自画来实现的,导致了CListCtrl控件某些函数的不可使用,例如InsertItem()等等,我尝试做了一下排序,总是会出现一些无法理解的错误,照我的理解只能把项全部存进列表中,然后对列表进行排序,再清空CListCtrl控件的所有项罗列出已排序的项。如果哪位高手有独到的解决方法,请不吝指教!
--------------------next---------------------
没解决标头拖动后的问题 ( T爱佳T 发表于 2007-11-26 9:02:00)
排序问题其实比较容易,只需要使用CListCtrl::SortItems就可以很好的实现,不过lParam必须预先定义好与排序相关的数据结构指针 ( jetricy 发表于 2006-9-7 10:36:00)
使用Custom Draw技术而已 ( zyl910 发表于 2005-7-10 17:24:00)
感觉ListCtrl怎么改,用起来都不太顺手 ( tmman 发表于 2005-6-9 22:34:00)
总要写出原文的出处吧!
这个东东,不错,我刚参加工作就是用了这个东东!
很怀念! ( bm1408 发表于 2005-6-9 15:53:00)
你可以参考一下知识库中关于CListCtrl的文章,已经有人做过类似您的工作,也实现了排序功能。 ( sflash2000 发表于 2005-6-8 8:56:00)
.......................................................
--------------------next---------------------