As a shareware developer I use a lot of custom controls and stuff to make the application pretty as well as useful. For my last project, I had to build a list control with all sorts of funky stuff happening in the list items and I thought it would be nice to have a list control that could render the individual item's text in HTML.
As we know the changing of row height in
CListCtrl is a real pain, funny methods like using large fonts and stuff exist but they are not pretty and largely of no use to me, so I decided to write the whole thing from scratch.
CHTMLListCtrl is very easy just include the required headers and call
Create when you want to create it (typically in
In the .h file declare a variable:
In the .cpp file:
To insert items in the ListCtrl, use the
InsertItem function. It takes a few arguments:
int InsertItem(CString sText,UINT uiImage,
int nStyle=HTML_TEXT,int nHeight=AUTO);
sText: The item text (it can be a simple text or a text with HTML tags depending on the
uiImage: The image number (if an
ImageList has been attached, otherwise 0).
nStyle: You can specify
SINGLE_LINE_TEXT will end in ellipses if the text too long).
nHeight: You can specify the height of this row or
CHTMLListCtrl will calculate it for you.
An example of
CString sText =
"<font color=#ff0000><b>Red Bold Font are scary</b></font>";
To further customize the control's behaviour, you can use the
HTMLLIST_STYLE_GRIDLINES: Shows/hides gray lines between the items.
HTMLLIST_STYLE_CHECKBOX: Adds checkboxes to the items.
HTMLLIST_STYLE_IMAGES: Adds images to the items (you have to set an
ImageList through the
SetImageList function for this to work).
To receive events, you need to handle the
WM_NOTIFY Windows message.
CHTMLListCtrl supports the following events:
HTMLLIST_SELECTIONCHANGED: Fired when list selection changes.
HTMLLIST_LBUTTONDOWN: Fired when the left mouse button is down.
HTMLLIST_RBUTTONDOWN: Fired when the right mouse button is down.
HTMLLIST_LBUTTONDBLCLICK: Fired when the control is double clicked.
HTMLLIST_ITEMCHECKED: Fired when the check box state changes.
You will not be able to use the class wizard to handle these events, you will have to manually add the entry in the message map.
In the message map write the following:
Now add the function:
void CMyDlg::OnHTMLList_SelectionChanged(NMHDR* pNMHDR,
NM_HTMLLISTCTRL *pListNMHDr =
if(pListNMHDr->nItemNo != NONE_SELECTED)
Extending the control's functionality
DrawItem function is implemented as a
virtual function, so users can derive from
CHTMLListCtrl and draw their own items, for example:
class CMyHTMLListCtrl : public CHTMLListCtrl
void DrawItem(CDC *pDC,CRect rcItem,
HTMLLIST_ITEM *pItem,BOOL bSelected)
The HTML rendering code is taken from Ukkie9's excellent article.
The following points are taken from Ukkie9's article:
- The only supported tags are
<sup>..</sup>. The tags
<strong>..</strong> are equivalent to
<em>..</em> map to
<font> tag is used only for changing the text color. It is also the only tag that can take a parameter, and this parameter should be "
color" with a value in the well known HTML hexadecimal notation. For example, "
- With the exception of tags that take parameters (currently, only the
<font> tag), there can be no spaces in the tags;
<p> is okay, but
<p align='right'> will be considered as two words "<p" and "align='right'>". That's right: when
DrawHTML() considers that something is not a valid HTML tag, it prints it as a word.
- Special characters like
à are not supported, you must type in the correct characters. That is, you can just use the characters "à" and "&" in the text, and "<" too.
CHTMLListCtrl also uses the
CMemDC written by Keith Rules, which can be downloaded from here (it is also included in the zip files above).
- 26th April, 2006
CalculateItemHeight bug fixed.
- WTL version added (thanks to Ernest Laurentin).
SetCursor bug fixed.
- Resizing bug fixed.
- 23rd March, 2006
CFont handle released in
Invalidate(FALSE); added in
GetItemCount function added (DUH).
- 17th March, 2006