分享
 
 
 

创建一个带有项目样式的ClistCtrl(ClistCtrlStyled)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Creating a CListCtrl Class with Item Style Features (CListCtrlStyled Class)

创建一个带有项目样式的ClistCtrl(ClistCtrlStyled)

http://www.codeguru.com/Cpp/controls/listview/article.php/c4189/可以找到英文和代码。

Overview(概览)

This class derives from the "CListCtrl" class and allows the user to define a style for an item or subitem. My goal was to be able to do the entire job transparently to allow the same behaviour of all existing methods from its base class CListCtrl.

这个class是从ClistCtrl继承而来的,他可以让用户自定义一个项(Item)或子项(subitem)的样式,同是还具有他的父类ClistCtrl所具有的所有行为特性.

In fact, the usage of this class is the same than the CListCtrl class except for a few new methods that let you define a style for an item.

事实上,该类(ClistCtrlStyled)的用法除了几个新添加让用户定义项样式的方法外,其他用法和ClistCtrl的用法是一样的.

These NEW methods to customize an item or subitem are:

用来自定义项和子项的方法是:

void SetItemStyle(int nItem,int nSubItem,DWORD Style,

bool redraw = true);

void SetItemTxtColor(int nItem,int nSubItem,

COLORREF txtColor,bool redraw = true);

void SetItemBgColor(int nItem,int nSubItem,

COLORREF txtBgColor,bool redraw = true);

void SetItemFont(int nItem,int nSubItem,CFont * pFont,

bool redraw = true);

This applies to a style on an entire Row, use this code:

用于修改整行的的样式可以使用如下的代码:

void SetRowStyle(int nRow,DWORD Style,bool redraw = true);

void SetRowTxtColor(int nRow,COLORREF txtColor,

bool redraw = true);

void SetRowBgColor(int nRow,COLORREF txtBgColor,

bool redraw =true);

void SetRowFont(int nRow,CFont * pFont,bool redraw = true);

And now, to apply a style on a entire Column, use this code:

好了,修改一整列的样式可以使用如下的代码:

void SetColStyle(int nCol,DWORD Style,bool redraw = true);

void SetColTxtColor(int nCol,COLORREF txtColor,

bool redraw = true);

void SetColBgColor(int nCol,COLORREF txtBgColor,

bool redraw = true);

void SetColFont(int nCol,CFont * pFont,bool redraw = true);

Theses methods are pretty easy to use, but a little knowledge about the "DWORD Style" parameter is needed. It's a flag that can hold a combination of these values:

这些方法真的很容易使用,不过使用前了解一下”DWORD Style”这个参数的意义还是有必要的.他是一个标志(Flag)用来合并如下的一些值:

LIS_BOLD // Bold Style

LIS_ITALIC // Italic Style

LIS_UNDERLINE // Underline Style

LIS_STROKE // StrikeOut Style

LIS_TXTCOLOR // The Text Color value is valid

LIS_BGCOLOR // The Background Color value is valid

LIS_NO_COL_STYLE // The Column Style has no effect on this

// item/subitem

LIS_NO_ROW_STYLE // The Row Style has no effect on this

// item/subitem

LIS_FIXED_STYLE // The Row and Column Styles have no effect

// on this item/subitem

Required: If you want to set a text color or background color, you must do it with two steps:

Required:如果你想设置一个文本颜色和背景色,你可以通过两步来达到效果.

1. Set the desired color with a Set....TxtColor() or Set.....BgColor() method

2. Enable its use with a Set....Style() method and LIS_BGCOLOR or LIS_TXTCOLOR attribute values.

调用Set…TextColor或Set…BgColor方法来设置你想要的文本或背景色.

用Set…Style()方法带上LIS_BGCOLOR or LIS_TXTCOLOR属性来使你设置的颜色生效

In addition, a few complementary methods allow you to define the style of items/subitems, rows, and also columns when they are selected.

另外还有一些附加的方法允许你来定义被选中时项、子项、行和列的样式。

void SetItemSelectedStyle(int nItem,int nSubItem,

DWORD Style,bool Redraw = true);

void SetItemSelectedTxtColor(int nItem,int nSubItem,

COLORREF txtColor,bool redraw = true);

void SetItemSelectedBgColor(int nItem,int nSubItem,

COLORREF txtBgColor,bool redraw = true);

void SetItemSelectedFont(int nItem,int nSubItem,

CFont * pFont,bool redraw = true);

void SetRowSelectedStyle(int nRow,DWORD Style,

bool redraw = true);

void SetRowSelectedTxtColor(int nRow,COLORREF txtColor,

bool redraw = true);

void SetRowSelectedBgColor(int nRow,COLORREF txtBgColor,

bool redraw = true);

void SetRowSelectedFont(int nRow,CFont * pFont,

bool redraw = true);

void SetColSelectedStyle(int nCol,DWORD Style,

bool redraw = true);

void SetColSelectedTxtColor(int nCol,COLORREF txtColor,

bool redraw = true);

void SetColSelectedBgColor(int nCol,COLORREF txtBgColor,

bool redraw = true);

void SetColSelectedFont(int nCol,CFont * pFont,

bool redraw = true);

And to let the user to define highlight colors to use by default for selection appearence:

或者让用户来定义高亮的颜色来作为默认的选中时的外观。

void SetHighlightTextColor(COLORREF Color);

void SetHighlightColor(COLORREF Color);

You have special methods that let the programmer set "user fonts;" then, you use these methods. You must know that the memory management will not be performed by the class. You must do the creation, storing, and destruction of theses fonts yourself! But all internal fonts created by the class are completely managed by it.

用户还可以使用特殊的方法来设置“用户字体”(User fonts),然后你就可以使用这些方法了。你必须了解的一点就是该类中没有对内存进行管理。你必须自己创建,存储,释放这些字体。但是所有的内嵌的字体是由该类本身管理的。

The style properties for an item/subitems can be a merging result, as in the following example.

项和子项样式属性可以合并成一个,如下面的例子演示。

Example of Styles Combination

By example, this CListCtrlStyled scheme (called m_list) has the following attributes:

例如:一个ClistCtrlStyled 图表 (叫m_list)有如下属性

0

1

2

3

0

SpiderMan

Matrix

Shrek

Gladiator

1

Terminator

Alien IV

BraveHeart

Monsters, Inc.

2

Apollo 13

Armageddon

Usual Suspects

Code Quantum

If we set styles like this:

如果我们用如下的代码设置样式:

m_list.SetRowStyle(0,LIS_BOLD);

m_list.SetColStyle(2,LIS_ITALIC);

m_list.SetItemTxtColor(1,1,RGB(0,0,255),false);

m_list.SetItemStyle(1,1,LIS_TXTCOLOR);

You will have a list with this apearance:

我们就可以看到如下的显示:

0

1

2

3

0

SpiderMan

Matrix

Shrek

Gladiator

1

Terminator

Alien IV

BraveHeart

Monsters, Inc.

2

Apollo 13

Armageddon

Usual Suspects

Code Quantum

The CListCtrlStyled class is managed entirely by the item drawing and CFont objects (except for user-CFont objects).

ClistCtrlStyled类

How to Use This Class

如何使用该类

You have nothing special to do!! It's exactly the same as using a CListCtrl Object except for setting a custom style. But if you create a new class that derives from CListCtrlStyled, you must verify that your MESSAGE MAP management is correctly defined like it in your .cpp file:

你不需要做任何额外的事情。他就和ClistCtrl的使用方法一样,除了设置样式的部分。但是如果你要创建一个从ClistCtrlStyled继承的新类的话,你就必须检查一下在你的.cpp文件中的MESSAGE MAP是否正确定义了。

BEGIN_MESSAGE_MAP(##YOURCLASS##, CListCtrlStyled)

//{{AFX_MSG_MAP(##YOURCLASS##)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

An existing application should be accepted to use CListCtrlStyled instead of CListCtrl without any changes except for the declarations type. If it's not the case, maybe I forgot something. If you find a problem or bug, you can report it to me at maximus@oreka.com.

对一个已经存在的应用想ClistCtrlStyled来代替ClistCtrl,你所要做的事情只是把声明该一下就好了。不如不可以的话,我可能忘记了一些什么事情。如果你发现了什么问题或者bug,你可以给我发个mail maximus@oreka.com(译如果可以的话也发一份给我jetgeng@hotmail.com,谢谢!)。

Required: If you change an existing derivate class of CListCtrl into a derivative class of CListCtrlStyled, don't forget to see the MESSAGE MAP declaration, as shown below.

Required:如果你想把一个ClistCtrl的子类,该成从ClistCtrlStyled继承的话不要忘了按照下面的样子来修改MESSAGE MAP(消息映射)声明。

In the available sample application, the code that set this CListCtrlStyled uses this code in the OnInitDialog method:

在示例应用中,我们将操作ClistCtrlStyled的代码放在了OnInitDialog 方法中。

// Set a Global Style

//

m_list.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FLATSB |

LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );

// Columns Creation

//

LPTSTR lpszCols[] = {_T("Column 0"),_T(>"Column 1"),

_T("Column 2"),_T("Column 3"),0};

LV_COLUMN lvColumn;

lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

lvColumn.fmt = LVCFMT_LEFT;

lvColumn.cx = 110;

for(int x = 0; lpszCols[x] != NULL; x++)

{ lvColumn.pszText = lpszCols[x];

m_list.InsertColumn(x,&lvColumn);

}

// Create some rows

//

LVITEM itemData;

char* lpszRow[]={_T("SpiderMan"),_T("Matrix"),_T("Shrek"),

_T("Gladiator"),_T("Terminator"),_T("Alien IV"),

_T("BraveHeart"),_T("Monsters, Inc."),

_T("Apollo 13"),_T("Armageddon"),_T("Usual Suspects"),

_T("Code Quantum"),_T("Die Hard 1"),

_T("Coyote Ugly"),_T("Final Fantasy"),_T("Ninja Scroll"),

_T("Pearl Harbor"),_T("Titan AE"),_T("Scary Movie 2"),

_T("Lord of the Rings"),_T("The One"),_T("Tarzan"),

_T("StalinGrad"),_T("Cube")};

int strIndex = -1;

for(int nRow = 0; nRow < 6 ; nRow++)

{

for(int nSubItem = 0; nSubItem < 4; nSubItem++)

{

strIndex++;

LPTSTR lpszItem = lpszRow[strIndex];

itemData.iItem = nRow;

itemData.iSubItem = nSubItem;

itemData.state = LVIS_SELECTED;

itemData.stateMask = LVIS_SELECTED;

itemData.pszText = (char*)lpszItem;

itemData.cchTextMax = strlen(itemData.pszText);

itemData.iImage = 0;

itemData.lParam = 1;

itemData.iIndent = 0;

if(nSubItem == 0)

{ itemData.mask = LVIF_TEXT | LVIF_PARAM;

m_list.InsertItem( &itemData );

}

else

{ itemData.mask = LVIF_TEXT;

m_list.SetItem( &itemData );

}

}

}

// Set a BackGround color

//

m_list.SetTextBkColor( RGB(217,245,245) );

// ******************************************

// START SPECIFIC CListCtrlStyled methods

// ******************************************

// Row 0 will draw in bold

//

m_list.SetRowStyle(0,LIS_BOLD);

// Set the Text color of an item

//

m_list.SetItemTxtColor(1,1,RGB(0,0,255),false);

m_list.SetItemStyle(1,1,LIS_TXTCOLOR);

// Column 2 will draw with a

// background color and all items will be strikeout

//

m_list.SetColBgColor(2, RGB(220,180,180) ,false);

m_list.SetColStyle(2, LIS_BGCOLOR | LIS_STROKE );

// Row 4 will use Text and Background color,

// and items will be underlined

//

m_list.SetRowBgColor(4, RGB(240,240,170) ,false);

m_list.SetRowTxtColor(4, RGB(0,0,192) ,false);

m_list.SetRowStyle(4,

LIS_UNDERLINE | LIS_TXTCOLOR | LIS_BGCOLOR);

// Set a subitem style, and we specify with

// LIS_FIXED_STYLE that it not use Column or Row style.

//

m_list.SetItemBgColor(0,2, RGB(0,0,168) ,false);

m_list.SetItemTxtColor(0,2, RGB(255,255,255) ,false);

m_list.SetItemStyle(0,2, LIS_TXTCOLOR | LIS_BGCOLOR | LIS_BOLD

| LIS_FIXED_STYLE );

// ---------------------------------

// -- Selection style definition --

// ---------------------------------

// General HIGHLIGHT Colors when selection

//

m_list.SetHighlightColor( RGB(160,210,210) );

m_list.SetHighlightTextColor( RGB(0,0,0) );

// Selected style for Column 2

//

m_list.SetColSelectedBgColor(2,RGB(185,160,160),false);

m_list.SetColSelectedStyle(2,LIS_BGCOLOR);

// Selected style for Row 4

//

m_list.SetRowSelectedBgColor(4, RGB(210,210,180) , false);

m_list.SetRowSelectedStyle(4, LIS_BGCOLOR);

// Specific style for an item (0,2)

//

m_list.SetItemSelectedBgColor(0,2,RGB(165,165,240),false);

m_list.SetItemSelectedTxtColor(0,2,RGB(240,230,230),false);

m_list.SetItemSelectedStyle(0,2,LIS_BGCOLOR | LIS_TXTCOLOR);

Why I Created This Class

我为什么创建该Class

I'm a newbie in an MFC/GUI way. I don't know how to create an owner-draw control and I'm currently managing a personal development that needs to use CListCtrl objects. These controls should be able to display a specific row's cells in bold or italic; then I was hurt by a lot of problems when I tried do do that. Some people asked me to define an owner-draw control!!! Urghh!! Just to draw a bold item??? It's boring to re-invent the wheel!!! I started to search someone else's stuff!!! I found on CodeGuru some nice and very powerful stuff!! But in all cases, these things had an owner interface and my wish is to have just a best "CListCtrl" with the same behaviours and uses!! At the same time, I found some really nice articles from CodeGuru on how use the "Custom Draw" capabilities by Roger Onslow!! His articles can be found here: Part I and Part II.

我是一个MFC/GUI新手.我不知道如何创建一个用户自绘控件(owner-draw)并且我现在管理的一个个人开发需要用到ClistCtrl控件。这些控件需要对特定的行进行加粗或用斜体。在我实现这个的时候被这些问题打击的不行了。有些人建议我用自绘控件!!哦,天那。自己去画一个加粗的Item??那不就是重新去发明轮子吗!!!!我开始搜索其他人的做法!!我在CodeGuru上找到了一些很漂亮并强大的素材!!但是所有的东西都有他们自己的接口而我想要的只是想要一个最好的“ClistCtrl”并且要和ClistCtrl有相同的行为和用法!!就在此同时,我在CodeGuru上发现了Roger Onslow写一些关于如何使用“Custom Draw”特性很好的文章。

After a few roll eyes, I think that it's the best way to have a nice CListCtrl that allows the programmer to customize any styles for any item/subitem!!! But the design of his job doesn't match my need. Then I decided to write my own class and try to do a useful class.

在我眨了几下眼后,我想那是创建一个让程序员设置任何Item/SubItem的最好的方法。但是他的设计和我的需求有点区别。所有我就决定自己写一个我自己的类并尽力把他打造成一个有用的类。

How This Class Works

该类的工作原理

Now you know that for drawing items/subitems, I use the Custom Draw feature. This part is well described in Roger Onslow's articles, but now I will describe my way of storing the style of an item/subitem.

假设你已经知道,我用了自绘特性。这一部分在Roger Onslow的文章中有很好的描述(译:关于Roger Onslow的文章我会争取在年前翻译出来。)但是我在此描述一下我时如何保存这些样式的。

All items (no subitems) have an application value that Microsoft calls the "lParam" member; it's a 32-bit value. It's the only "easy" way to link a value to an item entry on the CListCtrl!! For this reason, I decided to use it! I store into the lParam of an item, and the pointer to its structure style. This structure style holds and wraps the "user-lParam" for all methods' transparancy. The item structure style also stores into a list of all subitems' structures' styles (because subitems haven't their own lParam members). With this design, the main job is to do all methods' transparancy for the user (especially for the user-lParam access), because the user must be able to use his lParam for his own application.

所有项(不包括子项)有一个应用级值(application value )Microsoft叫他为“lParam”;他是一个32为的值。他只是连接到一个Item的简单方法(译:是不是指向Item实体的指针,有代证实)。就因为如此,我就决定使用他了,用它来存储一个指向Style结构体的指针。该结构体保存并封装了该“user-lParam”。该结构体还保存了所有子项的Style到一个List中(译:其实是一个数组,用Carray类来实现)(那是以为子项没有他们自己的lParam成员)。使用了这中设计,大多数的方法对用户来说时透明的,因为用户必须能够在他们自己的程序中使用的lParam。

All components that need to store a style use the same structure, as the one that follows:

所有的需要存储样式的组件使用了同样的一个结构体,下面的就时其中一个:

typedef struct iLS_item

{ LPARAM lParam; // The user-32 bits data lParam member

bool mParam; // let you know if the original item has

// a lParam significant member

DWORD StyleFlag; // The style of this item

bool in_use; // Allows you to know if a custom font

// is needed (except colors properties)

COLORREF txtColor; // Text color if LIS_TXTCOLOR style

// (default otherwise)

COLORREF bgColor; // BackGround color if LIS_BGCOLOR style

// (default otherwise)

CArray<struct iLS_item // Allows an individual style for

*,struct iLS_item *> // subitems. (In some cases, this

// member is not significant and

subitems; // has a null size.)

struct iLS_item // Access to the row

* row_style; // style (valid only for the ITEM

// style, for other components this

// member is set to NULL).

struct iLS_item * // Access to the "SELECTED" style for

selected_style; // this component

CFont * cfont; // The CFont object pointer is used

// to draw this item or subitem

bool ifont; // Allows you to know if the CFont

// is an internal or user Cfont object

// and allows you to know if we must

// memory manage it!

CFont * merged_font; // A combination of different fonts is

// needed (significant only for

// Items/SubItems; for other components,

// this member is set to NULL).

} LS_item;

Typically, this is the code for retrieving the Style structure of an item or subitem:

典型的,下面的代码是从一个项或子项中获得一个样式结构体:

int nItem = 2; // Item index

int nSubItem = 1 // Subitem index

// Get the LVItem corresponding to the ITEM ( subitem = 0 )

//

LVITEM pItem;

pItem->mask = LVIF_PARAM;

pItem->iItem = nItem;

pItem->iSubItem = 0;

CListCtrl::GetItem(&pItem); // Now we have access to the lParam

// member that holds the pointer

// to this Structure style

LS_item * lpLS_root = (LS_item*) pItem.lParam;

LS_item * lpLS_item = NULL;

// But if we want a subitem style, we must access it now

//

if(nSubItem > 0)

lpLS_item = lpLS_item->subitems[ nSubItem - 1 ];

else

lpLS_item = lpLS_root;

With the following code, we retrieve the structure style for an item/subitem. Now, to find structures of corresponding row and columns, the following code is enough:

通过上面的代码,我们从项和子项中得到了一个样式结构体。现在,用下面的代码可以一行或类的样式结构体:

LS_item * lpLS_row = lpLS_root->row_style; // It's all

LS_item * lpLS_col = this->columns[ nSubItem ];

// The structure style of columns is stored into a private array

//列的样式结构体是存储在一个是由的数组中的。

// of the CListCtrlStyledClass

After all, we have all structures style needed to manage the style of a particular item. By the way, when the item is selected, we need to do an indirection like ->selected_style on all structures.

好了,我们现在可以得到所有的管理样式的的结构体了。()

To retrieve the user-lParam member, it's always pretty easy; the root item structure stores the user-lParam, as shown in this code:

得到User-lParam 成员,这里有一个很漂亮很简单的方法,在根项的结构体中保存了这个变量。使用如下代码就可以获得:

LPARAM user_lParam = NULL;

if(lpLS_root->mParam)

user_lParam = lpLS_root->lParam;

Now I will explain a little bit more about my CFont management; all structures' style can store a pointer into a CFont object. When the structure is created, this pointer is set to NULL; when an item is being saved to be drawing, the class tests whether we need a special font or not!! If it's no, we have nothing to do.

下面我想解释一下我的Cfont管理。所有的样式结构体可以保存一个指向Cfont对象的指针。在样式结构体被创建时,该指针被设置成NULL;当一个项(Item)被创建将要画出时,类就会去检查我们是否需要一个font。如果不需要,我们就什么也不做。

How to Tell If the Class Knows That an Item/Subitem Needs a Special Font

如何通知类是否需要一个特定的Font

Step 1

第一步

The class must find all significant structures' style for the current item/subitem!!

类必须要找到当前项或子项有用的样式结构体

Item/Subitem Structure style (项样式)

Row Structure style (行样式)

Column Structure Style (列样式)

Required: A little trick to perform when an item is selected. This class takes all structures' style for the selected state. Check colors' values that it needs to be used for this item. But after this, the class checks whether the structure is used for the font style (member in_use); if not, it takes back the normal structure style!!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有