2
votes

I have a C++ MFC CComboBox (VS 2010) which users can enter text and click a "save" button, which inserts their text into the dropdown list for later recall/use. When text is too long for the box I need to have a scrollbar, so I set WS_HSCROLL in the resource file and use m_Combo.SetHorizontalExtent(x), which works just fine.

The problem I have is that where there's a horizontal scroll, one line is covered by it and a vertical scroll bar appears to scroll to that one item. I have tried

m_Combo.MoveWindow(&rctDropDown) //rctDropDown was first pulled out and modified
::SetWindowPos() //called after modifying values from ::GetWindowRect()
r.OffsetRect() //where r is from m_Combo.GetDroppedControlRect(&r)

and probably more the past few days but nothing seems to override the automatic sizing of the dropdown which doesn't account for the horizontal scroll. I'm new to MFC and found these suggested online during desperate Google searches.

In short, is there a way to override the auto-height or extend it? I know how to resize it in the resource editor but I want to resize in code during runtime and everything seems to be ignored. Here are my functions from a test project that reproduced the error:

void CtestDlg::StoreClicked()
{
    CString l;
    m_Combo.GetWindowText(l);
    m_Combo.InsertString(0, l);
    m_Combo.SetCurSel(0);
    UpdateList();
}

void CtestDlg::UpdateList()
{
    // Find the longest string in the list box.
    CString     str;
    CSize       sz;
    TEXTMETRIC  tm;
    CDC*        pDC = m_Combo.GetDC();
    CFont*      pFont = m_Combo.GetFont();

    int         x = 0;
    int         y = 0;

    // Select the listbox font, save the old font
    CFont* pOldFont = pDC->SelectObject(pFont);
    // Get the text metrics for avg char width
    pDC->GetTextMetrics(&tm); 

    for(int i = 0; i < m_Combo.GetCount(); i++)
    {
        m_Combo.GetLBText(i, str);
        sz = pDC->GetTextExtent(str);

        // Add the avg width to prevent clipping
        sz.cx += tm.tmMaxCharWidth;

        m_Combo.SetItemHeight(i, sz.cy);

        if (sz.cx > x)
            x = sz.cx;

        y += sz.cy;
    }
    // Select the old font back into the DC
    pDC->SelectObject(pOldFont);
    m_Combo.ReleaseDC(pDC);
    m_Combo.SetHorizontalExtent(x);

    ////////////////////////////////
    //manually change height here?//
    ////////////////////////////////
}
1
Hi mwilliams, did you ever get it work as you want?SevenWow
No, I believe it's a limitation of MFC.mwilliams

1 Answers

1
votes

Instead of adding a horizontal scrollbar and allowing scrolling if the dropped listbox is not wide enough, you can rather just set the width of the dropped listbox accordingly.

Replace

m_Combo.SetHorizontalExtent(x);

with

m_Combo.SetDroppedWidth(x);