Creating a Clistctrl Class with Item Style Features (ClistCtrlstyled Class)
Create a ClistCtrl (ClistCtrlstyle) http://www.codeguru.com/cpp/controls/listview/cpp/controls/listview/thpppp/controls/listview/CPP/Controls/ListView / CPP/CONTROLS/ListView / CPP/C4189 / English and code can be found. Overview (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.
This class is inherited from ClistCtrl, which allows the user to customize one item (ITEM) style, and all the behavior features of his parent class CListCtr.
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
In fact, the usage of this class is the same in addition to several new adds to the user-defined method, other usage and ClistCtrl usage are the same.
Thase New Methods To Customize An Item or Subitem Are:
The method from definition items and children is:
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:
The style used to modify the whole line can use the following 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:
Ok, modify a whole style can use the following 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);
This is needed. It's. It's. .. it's........................................................................... ..
These methods are really easy to use, but it is still necessary for the meaning of "DWord Style" before use. He is a flag (FLAG) used to merge some of the following:
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 / subs
Lis_no_row_style // The Row Style Has No Effect ON THIS
// item / subs
Lis_fixed_style // The Row and Column Styles Have No Effect
// on this item / subs
Required: if you want to set a Text Color or Background Color, You Must Do It with Two Steps:
Required: If you want to set a text color and background color, you can achieve the effect by two steps.
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.
Call Set ... TextColor or Set ... BGColor method to set the text or background color you want.
With the set ... style () method, bring the lis_bgcolor or lis_txtcolor property to make the color you set
In Addition, A Few Complementary Methods Allow You To Define The Style of items / Subitems, Rows, and Also Column When.
There are also some additional methods to allow you to define the style of selected timers, children, rows, and columns.
Void SetItemSelectedStyle (int NITEM, INT NSUBITEM,
DWORD style, BOOL RedRaw = true);
Void SetItemSelectedTxtxTcolor (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 SetrowSelectedTxtxTcolor (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 SetColselectedTxtXtcolor (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:
Or let the user define the highlighted colors to be used as the default selected appearance.
Void STHighlightTextColor (ColorRef Color);
Void SthighlightColor (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.
Users can also use special methods to set User Fonts, and then you can use these methods. What you have to understand is that there is no memory in this class. You must create, store, and release these fonts. However, all embedded fonts are managed by this class itself.
The Style Properties for An Item / Subitems Can Be a Merging Result, AS in The Following Example.
Items and child style properties can be merged into one, as shown in the example below.
EXAMPLE OF Styles Combination
BY EXAMPLE, this ClistCtrlstyled Scheme (Called M_List) HAS The Following Attributes: For example: a clistCtrlStyled chart (called M_List) has the following properties
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:
If we set the style with the following code:
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 aperance:
We can see the following display:
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.
ClistCtrlstyleD class
How to use this class
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:
You don't need to do any extra things. He is the same as the use of ClistCtrl, except for the set of styles. But if you want to create a new class inherited from CListCtrlStyled, you must check if the Message Map in your .cpp file is correctly defined.
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 .
For an existing application wants clistctrlstyled instead of CListCtrl, what you have to do is just a declaration. If it is not as good, I may have forgotten something. If you find any questions or bugs, you can send me mail maximus@oreka.com (translation: if you can also send me Jetgeng@hotmail.com, thank you!). 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 bellow.
Required: If you want to put a CListCtrl subclass, if you are inherited from ClistCtrlStyle, don't forget to modify the Message Map declaration according to the following look.
In The Available Sample Application, The Code That THIS CLISTCTRLStyLED Uses this code in the onInitdialog method:
In the sample application, we put the code of the CListCtrlStyled in the OnInitDialog method.
// set A Global STYLE
//
M_List.sextendedStyle (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 ("Mons, 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 ("Scary Movie 2"), _ T ("Lord of the Rings"), _ T ("THE"), _ 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, BACKGROUND
// and items will be underlined
//
M_List.seRowbgcolor (4, RGB (240, 240, 170), FALSE);
M_List.seRowtxtColor (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 Not Use Column or Row Style.
//
M_List.SetItemBGColor (0, 2, RGB (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.SethightLightColor (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.selectedSelectedBGColor (4, RGB (210, 210, 180), FALSE);
m_list.selectedSTYLE (4, LIS_BGCOLOR);
// specific style for an item (0, 2)
//
M_List.SetItemSelectedBGColor (0, 2, RGB (165, 165, 240), FALSE);
M_List.SetItemSelectedTxtXtcolor (0, 2, RGB (240, 230, 230), FALSE);
M_List.SetItemSelectedStyle (0, 2, Lis_BGCOLOR | LIS_TXTCOLOR);
Why i created this class
Why do I create this class?
I'm a newbie in an MFC / GUI way. I do not 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; the I Was hurt by a lot of problem, some person !! i t i i i i i i i i 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. I am an MFC / GUI newbie. I don't know how to create a user-draw control (Owner-draw) and I have now managing a personal development to use the CListCtrl control. These controls need to be bold or use italics for specific rows. It's not possible to fight by these problems when I realize this. Some people suggest that I use the self-painted control! ! Oh, the sky is. Draw a bold Item yourself? ? That's not to re-invent the wheel! ! ! ! I start to search other people's practices! ! I found some very beautiful and powerful material on CodeGuru! ! But all things have their own interface and I want just want a best "clistctrl" and have the same behavior and usage as CListCtrl! ! At the same time, I found Roger OnSlow written some articles on how to use the "Custom Draw" feature on CodeGuru.
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 does not match my need. Then I decided To Write My OWN CLASS AND TRY to Do a Useful Class.
After I blinked a few eyes, I think that is the best way to create a programmer to set any Item / SUBITEM. But his design is a bit different from my needs. All I decided to write a class my own class and try to create him into a useful class.
How this class works Working principle
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.
Suppose you already know, I use the self-painted feature. This section has a good description in Roger OnSlow's article (Translation: About Roger Onslow) I will strive to translate in the year.) But I will describe how to save these styles.
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 have not 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.
All items (excluding children) have an application value Microsoft called him "lparam"; he is a 32-yet value. He is just a simple way to connect to an item (translation: Is it pointing to the pointer of the Item entity, has a confirmation). Because of this, I decided to use him, use it to store a pointer to the style structure. The structure is stored and encapsulated the "User-LParam". The structure also saves all STYLE to a list (translation: It is actually an array, implemented with the Carray class) (That is to do not have their own LPARAM members). Using this design, most methods are transparent to users because users must be able to use LPARAM used in their own programs.
All Components That Need To Store A Style Use The Same Structure, As The One That Follows:
All components that need to store styles use the same structure, one of them:
Typedef struct ILS_Item
{LPARAM LPARAM; // The user-32 bits data lparam membrams 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 *> // Subitems. (in some case, this //Member is not signific 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 buy // to draw this item or subs Bool ifont; // allows you to know if the cfont // is an intence or user cfont object // and allows you to know if we must //Memory management it! Cfont * merge_font; // a combination of diffrent 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 subs: Typically, the following code is to get a style structure from one item or child: 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-> IIITEM = 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 subsitem 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: Through the above code, we get a style structure from items and children. Now, with the following code, you can or class style structures: 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 // The pattern structure is stored in one 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 Structure. Ok, we can now get the structure of all management style. () To Retrieve The User-LParam Member, It's Always Pretty Easy; The Root Item Structure Stores The User-LParam, AS Shown In this code: Get a member of the user-lparam, where there is a very beautiful and simple way to save this variable in the structure of the roots. Use the following code to get: 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. I would like to explain my cfont management. All style structures can save a pointer to the CFONT object. When the style structure is created, the pointer is set to null; when an item is created, the class will check if we need a font. If we don't need, we don't do anything. How to Tell if The Class Knows That An Item / Subitem Needs A Special Font How to notify whether the class needs a specific FONT STEP 1 first step The Class Must Find All Significant Structures' Style for The Current Item / SubItem !! Category must find the current item or child useful style structure Item / SubItem Structure Style Row Structure Style Column Structure Style (Column 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; if not, It Takes Back The Normal Structure Style !!