void CResizableComboBox::PreSubclassWindow()
{
    ASSERT(GetStyle() & CBS_NOINTEGRALHEIGHT);

    InitHorizontalExtent();

    GetDroppedControlRect(&m_rectDropDown);
    ::MapWindowPoints(NULL, GetSafeHwnd(),
        (LPPOINT)&m_rectDropDown, 2);

    CComboBox::PreSubclassWindow();
}
//------------------------------------------------------------------------
//! CBN_DROPDOWN message handler called when the CComboBox control
//! is expanded into a dropdown list. Used to restrict the width of
//! the dropdown list to the max width.
//------------------------------------------------------------------------
void CGridEditorComboBox::OnDropDown()
{
	int itemHeight = GetItemHeight(-1);
	int nNumEntries = GetCount();

	// Resize combobox according to actual element count
	int visibleItemCount = 	m_MaxHeightItems < nNumEntries ? m_MaxHeightItems : nNumEntries; // min(m_MaxHeightItems, nNumEntries);
	CRect rectExpanded;
	GetClientRect(rectExpanded);
	rectExpanded.bottom += visibleItemCount * GetItemHeight(0);
	rectExpanded.bottom += GetSystemMetrics(SM_CYEDGE) * 2; // top & bottom edges
	SetWindowPos(NULL,		// not relative to any other windows
				0, 0,		// TopLeft corner doesn't change
				rectExpanded.Width(), rectExpanded.Height(),   // existing width, new height
				SWP_NOMOVE | SWP_NOZORDER	// don't move box or change z-ordering.
				);

	// Resize combo-box width to fit contents
	int nMaxItemWidth = 0;
	CString str;

	// Find max-width of the elements
	CDC*	pDC = GetDC();
	CFont*	pFont = GetFont();
	CFont*	pOldFont = pDC->SelectObject(pFont);

	for (int i = 0; i < nNumEntries; i++)
	{
		GetLBText(i, str);
		int nLength = pDC->GetTextExtent(str).cx;
		nMaxItemWidth = nMaxItemWidth > nLength ? nMaxItemWidth : nLength;	// max(nMaxItemWidth, nLength);
		if (nMaxItemWidth > m_MaxWidthPixels)
		{
			nMaxItemWidth = m_MaxWidthPixels;
			break;
		}
	}

	// Check if there are so many elements that we need space for a vertical scrollbar
	CRect rect;
	GetDroppedControlRect(&rect);
	if (rect.Height() <= nNumEntries*GetItemHeight(0))
		nMaxItemWidth +=::GetSystemMetrics(SM_CXVSCROLL);

	// Add margin space to the calculations
	nMaxItemWidth += pDC->GetTextExtent(_T("0")).cx;

	pDC->SelectObject(pOldFont);
	ReleaseDC(pDC);

	SetDroppedWidth(nMaxItemWidth);
	SetItemHeight(-1, itemHeight);
}
int COXMultiComboBox::AdjustToFitSize()
{
	int nResult;
	if(m_bFitToSize)
	{
		int nTotalWidth=GetTotalWidth()+2*GetSystemMetrics(SM_CXBORDER);

		int nTotalHeight=GetTotalHeight();
		int nBorderHeight=GetSystemMetrics(SM_CYBORDER);
		int nScrollbarHeight=GetSystemMetrics(SM_CYHSCROLL);
		CRect rcDrop;
		GetDroppedControlRect(&rcDrop);
		if((nTotalHeight > rcDrop.Height()-2*nBorderHeight) ||	
			((nTotalWidth > rcDrop.Width()) &&
			(nTotalHeight > rcDrop.Height()-nScrollbarHeight-2*nBorderHeight)))
		{
			nTotalWidth+=::GetSystemMetrics(SM_CXVSCROLL);
		}

		int nScreenWidth=::GetSystemMetrics(SM_CXSCREEN);
		nTotalWidth=nTotalWidth>nScreenWidth ? nScreenWidth : nTotalWidth;

		nResult=SetDroppedWidth(nTotalWidth);
	}
	else
		nResult=SetDroppedWidth(1);

	if(nResult!=CB_ERR)
	{
		// ... To indicate that the scrollbars has to be re-adjusted
		m_fSizeChanged = TRUE; 

		// Redraws the listbox
		if(::IsWindow(m_ComboLBox.m_hWnd))
		{
			m_ComboLBox.RedrawWindow(NULL,NULL,
				RDW_ERASE|RDW_INVALIDATE|RDW_ERASENOW|RDW_UPDATENOW|RDW_FRAME);
		}
	}

	return nResult;
}
// This message is handle to get the HWND of the listbox of the combobox
// as there is no otherway to get it(refer to Q65881, Q131845 in Knowledge Base)
// The listbox handle is needed to set the scrollbar to it if needed, and to 
// handle its WM_HSCROLL message.
HBRUSH COXMultiComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
// --- In  : pDC : device context (See standard help for detaled info)
//			 pWnd : Pointer Cwnd obejct of the window whose background 
//				    has to be painted.
//			 nCtlColor : Type of the control
// --- Out : 
// --- Returns : Brush to supply to paint the background
// --- Effect : The listbox's HWND is got and sunclassed to COXComboLBox 
//				window object. The listbox style is modified to 
//				have WS_HSCROLL. The horizontal extent of the listbox is 
//				set and scrollbars are shown are hided depending on the 
//				width and height. Scroll range for horizantal scrollbar 
//				is set and also m_NumCharsPerPage is set.
{
	HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor); 

	// Handle only if the type of control is Listbox only
	if ((nCtlColor == CTLCOLOR_LISTBOX) && m_fSizeChanged)
	{
		// ... To stop this code run unneccessorily
		m_fSizeChanged = FALSE; 
		if(m_ComboLBox.GetSafeHwnd()==NULL)
		{
			m_ComboLBox.SubclassWindow(pWnd->GetSafeHwnd()); 
			m_ComboLBox.ModifyStyle(0,WS_HSCROLL); 
			TEXTMETRIC tm;
			GetTextMetrics(pDC->m_hDC,&tm); 
			m_nLineWidth = tm.tmAveCharWidth;
		}
		int nTotalWidth = GetTotalWidth();
		// ... Sets horizontal extent to total width
		m_ComboLBox.SetHorizontalExtent(nTotalWidth);

		CRect rcDrop;
		GetDroppedControlRect(&rcDrop);
		int iTotalItemHeight = 0;
		for (int i = 0; i < m_ComboLBox.GetCount(); i++)
			iTotalItemHeight += m_ComboLBox.GetItemHeight(i);
		if (rcDrop.Height() < iTotalItemHeight || m_bFitToSize)
			m_ComboLBox.AdjustHScroll();

		if(GetStyle()&CBS_DROPDOWN)
		{
			CRect rcWnd;
			m_ComboLBox.GetWindowRect(&rcWnd);
			m_ComboLBox.MoveWindow(&rcWnd,TRUE);
		}

		if(m_ComboLBox.m_fHorzScrollVisible)
		{
			CRect rcClient;
			m_ComboLBox.GetClientRect(&rcClient);
			m_nPageWidth = rcClient.Width();

			// setting sroll info
			SCROLLINFO si;
			si.cbSize = sizeof(si);
			si.nPos = 0;
			si.nMin = 0;
			si.nMax = nTotalWidth;
			si.nPage = m_nPageWidth;
			si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS ;
			m_ComboLBox.SetScrollInfo(SB_HORZ,&si,TRUE); 
			m_ComboLBox.SendMessage(WM_HSCROLL,SB_TOP,0L); 
		}

		m_ComboLBox.RedrawWindow(NULL,NULL,RDW_INVALIDATE|RDW_FRAME);
	}
	return hbr; 
}