Home.NET List Control and Property Grid with the MF...
List Control and Property Grid with the MFC Feature Pack
Some of the tools and objects around us are good only for their specific purpose. Under any other circumstances these are as useless as a dollar on a deserted island in the middle of nowhere. However, these tools and objects do wonders if you use them for their proper purpose. The list and grid controls are these kinds of classes in the MFC.
Contributed by Gabor Bernat Rating: / 6 October 26, 2009
Therefore the question pops up: is it worth it the time to learn them? Well as long as you do not use them, not really. Nevertheless, if you intend to put them to work in your code source and you already have strong pre-feature pack knowledge of the MFC, this article will definitely be the one to skim through.
If you missed or are interested in the other MFC feature pack controls, you can find them under my profile. I've already written three other articles treating this subject. I will continue to use the project entitled New Controls present on the MSDN here. Anyone who may want to follow along with my work will need Visual Studio 2008 installed with service pack one.
First, add a classic list control item in the resource editor. Then add a new class to your project via the editor. Inside the code source generated, replace the CListCtrl item with a CMFCListControl. If you populate it with a couple of simple items you will have already a working Excel-like list.
Nevertheless, in order to make it a little more interesting we will extend our class a little. Derive from the CMFCListCtrl and we will overwrite three classes, as I show in the following lines:
class CMyListCtrl: public CMFCListCtrl
{
virtual COLORREF OnGetCellTextColor (int nRow, int nColum);
virtual COLORREF OnGetCellBkColor (int nRow, int nColum);
There are two major improvements over the old version. First, you can see what column is sorted by the arrow that is automatically drawn above it, according to what we sort. Second, it is possible now to do the data sorting on multiple columns at the same time.
Moreover, you can use font and color changes to better illustrate this. First we overwrite the function responsible for the text color, then for the cell's background color, and finally the one that will change the font used for text. To keep this simple, we will just make the current font bold.
COLORREF CMyListCtrl::OnGetCellTextColor (int nRow, int nColum)
{// do we set the color or we leave for the def implementation
Finally, I have also implemented a few check boxes so you can turn these options on and off. During this, we just change a bool variable and call for the enable/disable function. The update of the variable is done automatically due to the data bind. The update date command will synchronize what you see on the screen with what you see inside the memory.
{ // Enable/Disable enabling the custom font feature
UpdateData ();
m_wndList.m_bModifyFont = m_bModifyFont;
m_wndList.RedrawWindow ();
}
In the table that follows this paragraph you will see a short description of the other functions you may use. With this, implementing the sort for multiple columns should be child's play. I will leave this task to you.
Function
For what?
EnableMarkSortedColumn
Use a different background color for the marked column.
EnableMultipleSort
Enables the ability of multiple sorts.
GetHeaderCtrl
Returns a reference to the header control.
IsMultipleSort
Checks to see if multiple sorts are activated.
OnCompareItems
Called by the framework to compare two items. Overwrite this for a custom sort.
OnGetCellBkColor
Tells what color to use for the background of a cell.
OnGetCellFont
Tells what font to use for drawing cell's content.
OnGetCellTextColor
Tells what color to use for the cell's text.
RemoveSortColumn
Removes the sort column form the list of sorted columns.
SetSortColumn
Sets the current sorted column and the sort order.
In order to make a grid control we need to invest a little more time. First we need a place to create all this. A CStatic object will suffice for this task. Use one of these in the resource editor. Once you have created the class, you need to add a CMFCPropertyGridCtrl variable. This will be the proper item. In the initialization, get the position of the static item and create the list there:
Creates a control and attaches it to a property grid control object.
DeleteProperty
Deletes a property from the grid control.
EnableDescriptionArea
Enables/disables description area underneath the list properties.
EnableHeaderCtrl
Enables/disables the header control at the top of the grid control.
EnsureVisible
Assures that a given property is visible inside the grid. To do this, it will scroll and expand.
ExpandAll
Expands or collapses all properties inside the grid control.
FindItemByData
Returns the property assigned to the given DWORD value.
GetBkColor
Returns the current background color of the grid control.
GetBoldFont
Returns the current font in bold.
GetCurSel
Retrieves the currently selected property.
GetCustomColors
Finds out the colors used for specific items of the control grid.
GetDescriptionHeight
Retrieves the height of an area.
GetDescriptionRows
Retrieves the number of rows of the current property grid control.
GetHeaderCtrl
References the internal internal CMFCHeaderCtrl that the framework uses to display the grid.
GetHeaderHeight
Gets the height of the property grid.
GetLeftColumnWidth
Gets column width.
GetListRect
Shows bounding rectangle of the grid control.
GetProperty
Points to the property according to the given index.
GetPropertyColumnWidth
Gives current width of the column that contains the property values.
GetPropertyCount
Tells the number of properties you have in the grid control.
GetRowHeight
Tells the height of a property row.
GetScrollBarCtrl
Points to the scroll bar used for the grid.
GetTextColor
Gives the color of the text in the current property.
HitTest
Retrieves the property in the given client coordinates.
InitHeader
Initializes the CMFCHeaderCtrl. This is used by the grid control to display the control.
IsAlphabeticMode
Tells whether or not the property grid is in alphabetic mode.
IsAlwaysShowUserToolTip
IsDescriptionArea
Tells whether the description area displayed.
IsGroupNameFullWidth
Tells whether each group name is displayed across the width of the current property grid.
IsHeaderCtrl
Indicates whether the header control is displayed
IsMarkModifiedProperties
Tells how modified properties are displayed.
IsShowDragContext
Tells whether, on resize, the framework redraws the name and values of the grid control.
IsVSDotNetLook
Tells whether it uses the same style as for the VS.Net.
MarkModifiedProperties
Tells how to display the modified properties.
RemoveAll
Clears out the property grid from the controls.
ResetOriginalValues
Restores the original values for all properties.
SetAlphabeticMode
Sets/resets alphabetical mode.
SetBoolLabels
Tells what text to display for Boolean labels.
SetCurSel
Selects the given property in the grid control.
SetCustomColors
Sets custom colors. These are used to draw the grid.
SetDescriptionRows
Sets the number of rows to display for a description.
SetGroupNameFullWidth
Displays full width of a category name for a group of properties in the current property gird control.
SetListDelimiter
Gives a character to use as delimiter in a list of property values.
SetShowDragContext
Redraws the name/value columns of the grid upon resizing.
SetVSDotNetLook
Sets the look of the VS.Net property grid.
UpdateColor
Sets the color values of the current color property.
Now for this plethora of functions there are four main properties: a general one (CMFCPropertyGridProperty), one used to select a color value (CMFCPropertyGridColorProperty), one that you can use to select a file (CMFCPropertyGridFileProperty) and one that you can use to select a font (CMFCPropertyGridFontProperty).
Naturally, extending any of these and rebuilding them to suit you needs is also an option. During the initialization part we can call many of these functions to configure our grid control to look as we want it to. Now the MSDN example creates one of each type of the four properties.
However, I will not do the same, as this would go beyond the purpose and size of this article. I will present one for the color and custom item. The other properties follow the same template; you just need to provide different contextual data at the time of creation.
A property grid contains multiple groups (or just one), and within that, multiple properties (or just one). Before we add any property, we need to create a group. For this, use the CMFCPropertyGridProperty class. Within this you can add items with the AddSubItem function. You can add a property group to the grid control with the AddProperty function.
//create a new item
CMFCPropertyGridColorProperty* pColorProp =
new CMFCPropertyGridColorProperty(
_T("Window Color"),RGB(210, 192, 254), NULL, _T("Specifies the default dialog color"));
CMFCPropertyGridProperty* pGroup3 = new CMFCPropertyGridProperty(_T("Misc"));
// Add the new item into this
pGroup3->AddSubItem(pColorProp);
// And finally add the end result to the grid control
m_wndPropList.AddProperty(pGroup3);
Creating a custom item is not that hard. You need to know which functions to overwrite and derive from one of the properties. We will create one that will have one accept and one cancel button near an edit box:
//Definition of a class
class CTwoButtonsProp : public CMFCPropertyGridProperty
And I will show you some of the other properties and styles you can create. For now this will be only in pictures:
This will be all for this piece on the MFC Feature Pack. I would like to thank you for reading my article. I hope you have learned a lot and you will rate my article as you think it's worth. If you have any questions feel free to put them up here on the blog or over our friendly community at DevHardware. Live With Passion!