How to add Horizontal Extent handling for a CListBox

Download Source Code

The following code illustrates how to implement Horizonal Extent handling
for a CListBox. For more information you can look at Q66370.
This class implements a derived CListBox which automatically sets the
horizontal extent.

CListBoxEx.h


//
// CListBoxEx.h v1.1
//

#ifndef _LISTBOX_EX_H
#define _LISTBOX_EX_H

#include

class CListBoxEx : public CListBox
{
public:
//virtual functions
virtual int AddString( LPCTSTR sString );
virtual int DeleteString( UINT nIndex );
virtual int InsertString( int nIndex, LPCTSTR lpszItem );
virtual void ResetContent();
virtual int Dir( UINT attr, LPCTSTR lpszWildCard );

private:
//helpers
LONG GetExtentForString( LPCTSTR sText );
long GetExtentForEntireControl();
};

#endif

CListBoxEx.cpp


// CListBoxEx.cpp   v1.0
//

#include "stdafx.h"
#include "listboxex.h"


//
// see Q66370 for more information
//

///////////////////////////////////////////////////////////////////////////
///////
//
//override functions
///////////////////////////////////////////////////////////////////////////
///////

int CListBoxEx::AddString(LPCTSTR lpszItem)
{

     LONG lStringExtent = GetExtentForString(lpszItem);
     if(GetHorizontalExtent() < lStringExtent)
        SetHorizontalExtent(lStringExtent);

     return CListBox::AddString(lpszItem);
}

int CListBoxEx::DeleteString( UINT nIndex )
{
     int nCountLeft=CListBox::DeleteString(nIndex);
     if (nCountLeft== LB_ERR)
         return LB_ERR;

      LONG lMaxExtent=GetExtentForEntireControl();
      SetHorizontalExtent(lMaxExtent);

      return nCountLeft;
}

int CListBoxEx::InsertString( int nIndex, LPCTSTR lpszItem )
{
      int nInsertPos=InsertString(nIndex, lpszItem);
      if (nInsertPos== LB_ERR)
           return LB_ERR;

      LONG lStringExtent=GetExtentForString(lpszItem);
      if(GetHorizontalExtent() < lStringExtent)
           SetHorizontalExtent(lStringExtent);

      return nInsertPos;
}

void CListBoxEx::ResetContent()
{
      SetHorizontalExtent(0);
      CListBox::ResetContent(); return;
}

int CListBoxEx::Dir( UINT attr, LPCTSTR lpszWildCard )
{
     int nReturn=Dir(attr, lpszWildCard );
     if (nReturn== LB_ERR || nReturn== LB_ERRSPACE)
         return nReturn;

     LONG lMaxExtent=GetExtentForEntireControl();
     SetHorizontalExtent(lMaxExtent);
     return nReturn;
}
////////////////////////////////////////////////////////////////////////////////// 
//helper functions 
////////////////////////////////////////////////////////////////////////////////// 

LONG CListBoxEx::GetExtentForString(LPCTSTR lpszItem)
{
    CDC* cdc=this->GetDC();
    CFont* font = this->GetFont();
    CFont* pOldFont;

    if (font)
     {
        pOldFont = cdc->SelectObject(font);

          TEXTMETRIC tm;
          cdc->GetTextMetrics(&tm);

          CSize size = cdc->GetTextExtent(lpszItem, lstrlen(lpszItem) );
          size.cx += tm.tmAveCharWidth;

          cdc->SelectObject(pOldFont);
          this->ReleaseDC(cdc);

          return (LONG) size.cx;
     }

     this->ReleaseDC(cdc);

     return 0L;
}

long CListBoxEx::GetExtentForEntireControl()
{
	CDC* cdc = this->GetDC();
	CFont* font = this->GetFont();
	CFont* pOldFont;
	if (font)
	{
		pOldFont = cdc->SelectObject(font);
		TEXTMETRIC tm;
		cdc->GetTextMetrics(&tm);
		CString sText;
		LONG max_cx = 0;

/****----------------C H A N G E---REY--8/29/98----------****
 ****		for(int n = 0; n<=GetCount(); n++)
 ****----------------------------------------------------****/
		for(int n = 0; n<GetCount(); n++)
/****--------------------END CHANGE----------------------****/
		{
			this->GetText(n, sText);
			if (sText == "")
				continue;
			CSize size = cdc->GetTextExtent(sText, sText.GetLength());
			size.cx += tm.tmAveCharWidth;
			if(max_cx <= size.cx)
				max_cx = size.cx;
		}
		cdc->SelectObject(pOldFont);
		this->ReleaseDC(cdc);
		return max_cx;
	}
	this->ReleaseDC(cdc);
	return 0L;
}

BUGFIX (28 June 1998): In function GetExtentForEntireControl()
changed SText = "" ro SText == "".

BUGFIX (4 Oct. 1998): In function GetExtentForEntireControl()
modify for loop statement to fix Assertion error that occurs when
you delete a string from the listbox.

Last updated: 11 November 1998

Comments:

More by Author

Must Read