Changing row height of a list control/CListCtrl

I’ve seen in forums numerous times people asking this query: How to change the row height of list control? Answers vary from , owner drawing to adding a fake image list with tall images. 🙂

Well so I decided to find out a way to do this in a proper way.  So here is a way to do this. This works both ways through a dialog resource and through dynamic creation. Note that this method uses owner drawing “for a moment”. 😉

Here is a screen shot before applying this method…

CListCtrl before changing row height

Well so follow these steps if you are using a dialog resource with a CListCtrl

  1. Add a list control to this resource
  2. Change the style of this list control to “owner draw fixed” style!
  3. Now override OnMeasureItem method of your dialog class, note that this method is not to be overridden in you CListCtrl class, you need not have a derived class of CListCtrl.
    OnMeasureItem prototype:
    afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
  4. Now inside OnMeasureItem add this piece of code, this is how mine looks… [sourcecode language=’cpp’]void CDialogGuineaPig::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
    {
    // If this is our list control then increase height
       if( nIDCtl == IDC_ROWLIST )
       {
    // Increase height by 20
          lpMeasureItemStruct->itemHeight += 20;
       }
    }[/sourcecode]
  5. Now goto OnInitDialog, this is how my OnInitDialog section for implementing this behavior looks… [sourcecode language=’cpp’]BOOL CDialogGuineaPig::OnInitDialog()
    {
    // Insert two columns and two rows…
        m_RowList.InsertColumn( 1, TEXT( “First column” ), LVCFMT_LEFT, 200, 0 );
        m_RowList.InsertColumn( 2, TEXT( “Second column” ), LVCFMT_LEFT, 200, 1 );
        m_RowList.InsertItem( 0, _T( “Row1 Column1” ), 0 );
        m_RowList.SetItemText( 0, 1, _T( “Row1 Column2” ));
        m_RowList.InsertItem( 1, _T( “Row2 Column1” ), 0 );
        m_RowList.SetItemText( 1, 1, _T( “Row2 Column2” ));

    // Remove owner drawn style, our job is done,
    // we’re tricking the framework into thinking that
    // we wanna owner draw this control so that we get
    // a call to OnMeasureItem.
       m_RowList.ModifyStyle( LVS_OWNERDRAWFIXED, 0, 0 );

    // Just to show the change in row height
       m_RowList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );

        return FALSE;  // return TRUE  unless you set the focus to a control
    }[/sourcecode]

  6. That’s it, we now have a list control with rows having bigger height. Here is a screen shot of the resultant list control…CListCtrl after changing row height

Now with dynamic creation, make sure specify LVS_OWNERDRAWFIXED style while creating so that OnMeasureItem is called by the framework, after the remove this style. Similar to dialog resource method.

So to summarize in one line what we’ve done… we turned on owner drawn style temporarily so that window framework calls OnMeasureItem, so that we can pass our own height value and then we’ve turned off this style so that the windowing framework does the drawing stuff instead of us.

Have fun programming…

17 thoughts on “Changing row height of a list control/CListCtrl

  1. turned off this style so that the windowing framework does the drawing stuff instead of us

    this is the first time I’ve heard of this trick. Does it apply to any other circumstance?

  2. your blog is full of useful information, most of them low level and i do my software in assembler and C/C++ so its always nice to read about some cool tips&tricks

  3. Nice write up.

    I would put the calls to parent class in OnInitDialog and OnMeasureItem so that the user knows that the calls to those methods needs to be made. You would be surprised how many people make that mistake and wonder why the get asserts.

Appreciate your comments...