[MFC] Resize CComboBox drop down list based on contents

I had this post in my draft for a long time. This code snippet resizes a combo box’s drop down list. Please note an application sends the CB_SETDROPPEDWIDTH message to set the minimum allowable width, in pixels, of the list box of a combo box with the CBS_DROPDOWN or CBS_DROPDOWNLIST style.

Note: MFC function CComboBox::SetDroppedWidth is just a wrapper for CB_SETDROPPEDWIDTH.

// Fill out combo box with strings of random width, for demo purpose only
void FillCombo(CComboBox& Combo)
	LPCTSTR lpAVeryLongString = _T("This is a very long string, the purpose of which is to test out width calculation of a combo drop down");
	TCHAR Buf[200] = {0};
	const int Len = _tcslen(lpAVeryLongString);
	for(int Index = 0; Index < 100; ++Index)
		const int TrimLen = rand() % Len;
		_stprintf_s(Buf, _T("%.*s"), TrimLen, lpAVeryLongString);
// Resize combo box drop down width based on contents
void AutoAdjustComboWidth(CComboBox& Combo)
	if(!Combo.GetSafeHwnd() || !::IsWindow(Combo.GetSafeHwnd()))
	CDC& ComboDC = *Combo.GetDC();
	const int RestorePoint = ComboDC.SaveDC();
	CFont& ComboFont = *Combo.GetFont();
	int MaxX = -1;
	const UINT ItemCount = Combo.GetCount();
	for(UINT Index = 0; Index < ItemCount; ++Index)
		CString Text;
		Combo.GetLBText(Index, Text);
		// Get width of item string.
		const SIZE sz = ComboDC.GetTextExtent(Text);
		if(sz.cx > MaxX)
			MaxX = sz.cx;
	}// End for
	if(MaxX >  0)
		const int ScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL);
		const int Border = ::GetSystemMetrics(SM_CXEDGE) * 2;
		Combo.SetDroppedWidth(MaxX + ScrollWidth * 2);

Some people might find this inconvenient as the list box width grows bigger. The way to workaround this issue is to use CComboBox::SetHorizontalExtent function as demonstrated here.

If you see bugs let me know, I’ll be glad to fix those.

Appreciate your comments...