2015-05-14 9 views
3

У меня есть CListCtrlEx, полученный из CListCtrl. В этом списке есть стиль LVS_REPORT, LVS_OWNERDRAWFIXED и LVS_EX_GRIDLINES. Я добавил возможность изменить шрифт для этого списка. Это работает отлично, но есть одна плохая вещь - если я меняю шрифт, и до этого я не был списком прокрутки, тогда все элементы списка перерисовываются правильно, но если бы я прокрутил перед изменением шрифта, то элементы списка перерисовывают немного верхнюю или ниже горизонтальных линий сетки списка, т.е. е. текст элементов перекрывается линиями сетки.Неверный рисунок CListCtrl:

Вот как я меняюсь список шрифты:

LRESULT CListCtrlEx::OnSetFont(WPARAM wParam, LPARAM) 
{ 
    LRESULT res = Default(); 

    CRect rc; 
    GetWindowRect(&rc); 

    WINDOWPOS wp; 
    wp.hwnd = m_hWnd; 
    wp.cx = rc.Width(); 
    wp.cy = rc.Height(); 
    wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER; 
    SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp); 

    return res; 
} 

void CListCtrlEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{ 
    HDC hDC = ::GetDC(NULL); 
    CFont* pFont = GetFont(); 
    HFONT hFontOld = (HFONT)SelectObject(hDC, pFont->GetSafeHandle()); 
    CRect rect; 

    DrawText(hDC, _T(" "), 1, rect, DT_SINGLELINE | DT_CALCRECT); 
    lpMeasureItemStruct->itemHeight = rect.bottom - rect.top; 
    SelectObject(hDC, hFontOld); 
    ::ReleaseDC(NULL, hDC); 
} 

And here is how it looks like:

UPD: три человека нажал кнопку UP, и никто не знает, что это может быть? :(

UPD 1: вот код класса http://pastebin.com/UdXYEpF7 .h http://pastebin.com/2HYe5AEd .cpp

+1

вы шоу очень мало информации о вашем классе, это трудно е выставить что угодно. Из того, что вы описали, не похоже, что есть ошибка. Если вы хотите изменить шрифт в середине программы, прокрутите до нуля и измените шрифт, а затем перейдите к старой позиции. –

+0

Вам не нужно внедрять метод DrawItem() для владельца, нарисованного списком ctrl? – cha

+0

@BarmakShemirani Я добавил свой код класса в вопрос – brightside90

ответ

1

Я попробовал ваш код, он выглядит как ListView обменивается сообщениями с скроллер, заголовок также изменяется, это на самом деле не стоит исследовать. это нормально, если вы просто установить позицию до нуля, вы можете сохранить прежнее положение и положить его обратно.

void CListCtrlEx::SetupFont(int nSize, const CString& strName) 
{ 
    int saveIndex = GetTopIndex(); 
    EnsureVisible(0, 0); 

    if (m_pFont.get()) m_pFont.get()->DeleteObject(); 
    VERIFY(m_pFont.get()->CreatePointFont(nSize, strName)); 
    SetFont(m_pFont.get()); 

    //This scrolls to bottom, it ensures saveIndex will end up on top 
    //once the next EnsureVisible is called 
    if (GetItemCount()) 
     EnsureVisible(GetItemCount() - 1, 1); 

    EnsureVisible(saveIndex, 1); 
} 
+0

Да, это хороший подход. Я буду использовать его в своем коде. Единственное, что, я думаю, нужно добавить сюда - это SetRedraw (FALSE); до EnsureVisible (0, 0); и SetRedraw (TRUE); после EnsureVisible (saveIndex, 1); чтобы избежать мерцания полосы прокрутки. Спасибо! – brightside90