Click here to Skip to main content
15,860,844 members
Articles / Desktop Programming / MFC

Changing Row Height in an owner drawn Control

Rate me:
Please Sign up or sign in to vote.
4.89/5 (25 votes)
8 Nov 2001CPOL4 min read 358.1K   6.7K   88   41
Changing the Row Height in an owner drawn List View Control

Table of Contents

History

2001-10-10 Inserted example "multiline.zip" from Danielle.

2001-09-27 Created article

Preface

This article is a close adaption of the article "Changing row height in owner drawn control" at Codeguru. I've enhanced as much as I can while trying to keep as much original content as possible. I also included a summary of the article's comments.

Introduction

When you change the font of a list view control, the control or its parent window does not get a chance to respecify the height of the rows. No

<a href="http://msdn.microsoft.com/library/en-us/winui/combobox_85d9.asp">WM_MEASUREITEM</a>
message is sent to the controls parent window. The net effect is that when the font is changed for the control, the row height is no longer valid.

Here's a work around that forces the WM_MEASUREITEM message to be generated

Step-By-Step

The code in the following steps uses MFC and its class CListCtrl.

Step 1: Add handler for WM_SETFONT

The WM_MEASUREITEM message is sent when the control is created. Fortunately this message is also sent whenever the control is resized. Since we want the row height to be adjusted when the font changes, what better place to do thin than in the

<a href="http://msdn.microsoft.com/library/en-us/winui/windows_7v90.asp">WM_SETFONT</a>
handler. In
<a href="http://msdn.microsoft.com/library/en-us/vcmfc98/html/_mfc_cwnd.3a3a.setfont.asp">OnSetFont()</a>
we fool Windows into thinking that the window size of the control has changed.

We do this by sending the

<a href="http://msdn.microsoft.com/library/en-us/winui/windows_5q90.asp">WM_WINDOWPOSCHANGED</a>
message to the control which then gets handled by the default window procedure for the control. Note that we haven't specified the SWP_NOSIZE flag and we set the width and height field in the
<a href="http://msdn.microsoft.com/library/en-us/winui/windows_8oz6.asp">WINDOWPOS</a>
structure equal to the existing dimension.

In the header file:

//{{AFX_MSG(CMyListCtrl)
:
:
//}}AFX_MSG
afx_msg LRESULT OnSetFont(WPARAM wParam, LPARAM);
afx_msg void MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct );
DECLARE_MESSAGE_MAP()

In the CPP file:

BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
    //{{AFX_MSG_MAP(CMyListCtrl)
    :
    :
    //}}AFX_MSG_MAP
    ON_MESSAGE(WM_SETFONT, OnSetFont)
    ON_WM_MEASUREITEM_REFLECT()
END_MESSAGE_MAP()

LRESULT CMyListCtrl::OnSetFont(WPARAM wParam, LPARAM)
{
    LRESULT res = Default();

    CRect rc;
    GetWindowRect( &rc );

    WINDOWPOS wp;
    wp.hwnd  = m_hWnd;
    wp.cx    = rc.Width();
    wp.cy    = rc.Height();
    wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
    SendMessage( WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp );

    return res;
}

Step 2: Add handler for WM_MEASUREITEM

Since we want our CListCtrl derived class to be modular, we will handle the WM_MEASUREITEM message within this class. The message however, is sent to the parent window, so we use message reflection. Again, the Class Wizard is not much help. We have to manually add the entry in the message map and update the header file. See the code snippet in step one for this.

void CMyListCtrl::MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
    LOGFONT lf;
    GetFont()->GetLogFont( &lf );
    
    if ( lf.lfHeight < 0 )
        lpMeasureItemStruct->itemHeight = -lf.lfHeight; 
    else
        lpMeasureItemStruct->itemHeight = lf.lfHeight; 
}

Conclusion

So far the steps, adapted from the original article. Following is a summary of the most interesting comments at the original article. The comments include fixes and corrections to the previous steps. Since I want to leave the article as it is, I decided to not include suggested fixes in the code fragments above. It's up to you to use or not to use them. Another reason is, that I don't know whether all suggested fixes are correct. Please drop a comment here so that I can remove/adjust any errors.

Readers Comments

Proper implementation of MeasureItem() routine

Problem/Solution:
When setting the row height for the CListCtrl derived object in the MeasureItem() routine, you shouldn't use the lfHeight member of the LOGFONT structure. This value is a logical point size value, not a physical pixels value. With different screen resolutions and larger font values, the row height will still be wrong. The following code shows an example for implementing the MeasureItem() routine that should work for all of these cases, and produces the exact same height as the default implementation.

void CMyListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
    TEXTMETRIC tm;
    HDC hDC = ::GetDC(NULL);
    CFont* pFont = GetFont();
    HFONT hFontOld = (HFONT)SelectObject(hDC, pFont->GetSafeHandle());
    GetTextMetrics(hDC, &tm);
    lpMeasureItemStruct->itemHeight = tm.tmHeight + tm.tmExternalLeading + 1;
    SelectObject(hDC, hFontOld);
    ::ReleaseDC(NULL, hDC);
}

(Paul Geringer, 1999-04-06 )

I don't receive a WM_SETFONT or WM_MEASUREITEM message

Problem:
I don't receive a WM_SETFONT or WM_MEASUREITEM message.

(Damian Williams, 1999-10-18)

Solution:

  1. Modify the style of the list control to "owner draw fixed" (LVS_OWNERDRAWFIXED).
  2. Overload CListCtrlEx::DrawItem().
  3. A WM_MEASUREITEM message will be sent to a parent window of list control.

(Chung Hyun, Lee, 2000-05-25)

Solution 2:
Class Wizard does not show you the =WM_MEASUREITEM reflected message. If you use Class Wizard to get WM_MEASUREITEMS, it can only be handled by a class other than the list view control, i.e. a parent window. This is not satisfactory. To get a reflected message you must add the following in the message map in your .CPP file:

ON_WM_MEASUREITEM_REFLECT()

Then you must add the following in your header file message map:

afx_msg void MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct );

then add the following function in your .CPP file:

void CMyListCtrl::MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
    // this should happen when the control is created.
    AfxMessageBox("You just received a WM_MEASUREITEM message");
}

(Dominic Gamble, 2000-01-13)

Solution 3:
First you must create the list view control with the style LVS_OWNERDRAWFIXED. Then, change the control's size, using the CWnd::MoveWindow() or CWnd::SetWindowPos() function.

It works both with hand-made-controls (using call a call to CListCtrl::Create()) and template-made-controls (using the resource editor)

(Gon (Jung-gon, Kim), 2000-08-09)

Changing the height of a row without using LVS_OWNERDRAWFIXED

Problem/Solution:
You can easily change the row height by making the image list icon size to your desired size (and fool the user by drawing your icon not to the actual size). E.g.:

imagelist.Create( 24, 24, ILC_COLOR4, 10, 10 ); 
m_cList.SetImageList( &imageList, LVSIL_SMALL ); 

If your icon has 16x16, you make your row height 50% bigger. This seems awkward, but it works with ease.

(Allan Gallano, 2000-11-17)

See also/References

  1. Changing row height in owner drawn control, Zafir Anjum, 1998-08-06, www.codeguru.com.
  2. Selection Highlighting of an Entire Row, Uwe Keim, 2001-09-26, www.codeproject.com.
  3. Neat Stuff to do in List Controls Using Custom Draw, Michael Dunn, 1999-11-30, www.codeproject.com.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer Zeta Software GmbH
Germany Germany
Uwe does programming since 1989 with experiences in Assembler, C++, MFC and lots of web- and database stuff and now uses ASP.NET and C# extensively, too. He has also teached programming to students at the local university.

➡️ Give me a tip 🙂

In his free time, he does climbing, running and mountain biking. In 2012 he became a father of a cute boy and in 2014 of an awesome girl.

Some cool, free software from us:

Windows 10 Ereignisanzeige  
German Developer Community  
Free Test Management Software - Intuitive, competitive, Test Plans.  
Homepage erstellen - Intuitive, very easy to use.  
Offline-Homepage-Baukasten

Comments and Discussions

 
QuestionCodeProject has changed it's formatting Pin
adrian_h6-Sep-19 6:08
professionaladrian_h6-Sep-19 6:08 
GeneralMy vote of 5 Pin
Member 1107406617-Sep-14 5:25
Member 1107406617-Sep-14 5:25 
GeneralMy vote of 5 Pin
breakwind9-Jun-11 18:03
breakwind9-Jun-11 18:03 
GeneralChange CListCtrl Row Height with OWNERDRAWFIXED & LVS_EX_CHECKBOXES Style.... Pin
AmitSharma123420-Apr-11 19:00
AmitSharma123420-Apr-11 19:00 
GeneralMy vote of 5 Pin
zyqhml28-Feb-11 21:06
zyqhml28-Feb-11 21:06 
QuestionHow can change row height when using checkbox option in listctrl? Pin
Le@rner21-Dec-10 19:43
Le@rner21-Dec-10 19:43 
JokeThis is a good aritical! Pin
zhanbin250@yahoo.com.cn13-Jun-08 0:00
zhanbin250@yahoo.com.cn13-Jun-08 0:00 
GeneralSetting row height without owner drawing itmes (for LVS_REPORT list control). Pin
LioLick11-Jul-07 4:35
LioLick11-Jul-07 4:35 
GeneralCant catch WM_WINDOWPOSCHANGED message! Pin
bosfan18-Apr-07 2:44
bosfan18-Apr-07 2:44 
QuestionSet different row heights in a list control? Pin
bosfan17-Apr-07 3:10
bosfan17-Apr-07 3:10 
General2 listboxes in a screen Pin
gayilc14-Mar-07 7:15
gayilc14-Mar-07 7:15 
GeneralMultiLine ListBox Pin
DILLIPPARHI4-Nov-06 14:00
DILLIPPARHI4-Nov-06 14:00 
GeneralList box view Pin
J51219826-Mar-06 2:05
J51219826-Mar-06 2:05 
GeneralConceptual question Pin
digwizfox22-Apr-05 14:09
digwizfox22-Apr-05 14:09 
GeneralRe: Conceptual question Pin
Gregory Morse19-Aug-06 10:23
Gregory Morse19-Aug-06 10:23 
GeneralProblems with WM_MEASUREITEM Pin
digwizfox22-Apr-05 14:06
digwizfox22-Apr-05 14:06 
QuestionHow to implement this in large icon view Pin
shashikura13-Jan-05 6:53
shashikura13-Jan-05 6:53 
GeneralHelp wanted Pin
Vikash Dubey4-Oct-04 20:41
Vikash Dubey4-Oct-04 20:41 
GeneralRe: Help wanted Pin
Al Forno13-Oct-04 8:28
Al Forno13-Oct-04 8:28 
GeneralAbout dynamically row height Pin
mickaxel26-May-04 23:48
mickaxel26-May-04 23:48 
GeneralRe: About dynamically row height Pin
Uwe Keim26-May-04 23:55
sitebuilderUwe Keim26-May-04 23:55 
GeneralRe: About dynamically row height Pin
mickaxel27-May-04 0:15
mickaxel27-May-04 0:15 
GeneralAnfrage Pin
Petrow16-Feb-04 23:22
Petrow16-Feb-04 23:22 
GeneralRe: Anfrage Pin
Petrow16-Feb-04 23:23
Petrow16-Feb-04 23:23 
GeneralRe: Anfrage Pin
Uwe Keim16-Feb-04 23:29
sitebuilderUwe Keim16-Feb-04 23:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.