Отправляет email-рассылки с помощью сервиса Sendsay

Секреты программирования

  Все выпуски  

Секреты программирования СListBox с переменными свойствами (программирование на MFC).


Понадобился мне СListBox с переменными свойствами (программирование на MFC). 
На странице происходит переключение режима и заполнение ListBox'а новыми данными. 
В зависимости от режима сортировка или есть, или нет. 

Пробуем 
    m_pListBox->ResetContent(); 

    if( m_iMisc == 2 ) 
        m_pListBox->ModifyStyle( 0, LBS_SORT | WS_HSCROLL | WS_VSCROLL ); 
    else m_pListBox->ModifyStyle( LBS_SORT, WS_HSCROLL | WS_VSCROLL ); 

Сортировка не меняется. Что за нафиг? Спрашиваем у гугля, есть статья 
http://www.codeproject.com/combobox/recreatelistbox.asp?df=100&forumid=4402&exp=0&select=367851 

Применяем код, работает, но ListBox сжимается при каждом переключении. Видимо, горизонтальный скроллбар не учитывался.
Пришлось подпорочку коду делать - добавить параметр int iHeight. В итоге 

// recreate the list box by copying styles etc, and list items 
// and applying them to a newly created control 
BOOL RecreateListBox(CListBox* pList, int iHeight=0, LPVOID lpParam=NULL); 
BOOL RecreateListBox(CListBox* pList, int iHeight, LPVOID lpParam ) 
{ 
    if (pList == NULL) 
        return FALSE; 
    if (pList->GetSafeHwnd() == NULL) 
        return FALSE; 

    CWnd* pParent = pList->GetParent(); 
    if (pParent == NULL) 
        return FALSE; 

    // get current attributes 
    DWORD dwstyle="pList-">GetStyle(); 
    DWORD dwStyleEx = pList->GetExStyle(); 
    CRect rc; 
    pList->GetWindowRect(&rc); 
    pParent->ScreenToClient(&rc);    // map to client co-ords 
    UINT nID = pList->GetDlgCtrlID(); 
    CFont* pFont = pList->GetFont(); 
    CWnd* pWndAfter = pList->GetNextWindow(GW_HWNDPREV); 

    if( iHeight ) 
        rc.bottom = rc.top + iHeight; 

    // create the new list box and copy the old list box items 
    // into a new listbox along with each item's data, and selection state 
    CListBox listNew; 
    if (! listNew.CreateEx(dwStyleEx, _T("LISTBOX"), _T(""), dwStyle, 
rc, pParent, nID, lpParam)) 
        return FALSE; 

    listNew.SetFont(pFont); 
    int nNumItems = pList->GetCount(); 
    BOOL bMultiSel = (dwStyle & LBS_MULTIPLESEL || dwStyle & LBS_EXTENDEDSEL); 
    for (int n = 0; n < nNumItems; n++) 
    { 
        CString sText; 
        pList->GetText(n, sText); 
        int nNewIndex = listNew.AddString(sText); 
        listNew.SetItemData(nNewIndex, pList->GetItemData(n)); 
        if (bMultiSel && pList->GetSel(n)) 
            listNew.SetSel(nNewIndex); 
    } 
    if (! bMultiSel) 
    { 
        int nCurSel = pList->GetCurSel(); 
        if (nCurSel != -1) 
        { 
            CString sSelText; 
            // get the selection in the old list 
            pList->GetText(nCurSel, sSelText); 
            // now find and select it in the new list 
            listNew.SetCurSel(listNew.FindStringExact(-1, sSelText)); 
        } 
    } 
    // destroy the existing window, then attach the new one 
    pList->DestroyWindow(); 
    HWND hwnd = listNew.Detach(); 
    pList->Attach(hwnd); 

    // position correctly in z-order 
    pList->SetWindowPos(pWndAfter == NULL ? &CWnd::wndBottom 
: pWndAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 

    return TRUE; 
} 

void CCanvasDesignConjug::InitListBox() 
{ 
    m_pListBox->ResetContent(); 

    if( m_iMisc == 2 ) 
        m_pListBox->ModifyStyle( 0, LBS_SORT | WS_HSCROLL | WS_VSCROLL ); 
    else m_pListBox->ModifyStyle( LBS_SORT, WS_HSCROLL | WS_VSCROLL ); 

    RecreateListBox( m_pListBox, 240 ); 
 ... 
} 

В избранное