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:



Comments

  • Here You Will Find The Fashion Mbt Lami In Cheap Price

    Posted by mbt shoes on 12/01/2012 07:36pm

    can help you lose weight, it has been recognized by everyone, then is worn on the feet instantly see weight loss results? Of course not, it is a process, and now a look at how products are put on the experience of MBT process it.

    Reply
  • Strange

    Posted by siavoshkc on 06/05/2010 04:16pm

    Thank you. I thought we can use GetTextExtent directly and because DC knows the font there should be no problem calculating text width.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Lenovo recommends Windows 8 Pro. "I dropped my laptop getting out of the taxi." This probably sounds familiar to most IT professionals. If your employees are traveling, you know their devices are in for a rough go. Whether it's a trip to the conference room or a convention out of town, any time equipment leaves a user's desk it is at risk of being put into harm's way. Stay connected at all times, whether at the office or on the go, with agile, durable, and flexible devices like the Lenovo® …

  • On-demand Event Event Date: August 27, 2015 With the cloud enabling companies to spin up servers and stand up data stores more quickly, mobile apps can be created faster, reducing the time-to-value. But three major obstacles stand in the way for many organizations: The backlog of app project requests confronting every enterprise regardless of their internal app development capabilities Finding and employing better, faster tools to speed and simplify the process of developing those apps. The emergence of …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date