3

I have my CListCtrlEx derived from CListCtrl. This list have style LVS_REPORT, LVS_OWNERDRAWFIXED and LVS_EX_GRIDLINES. I have added possibility to change font for this list. This works fine, but there is one bad thing - if I change font and before that I have not been scrolling list, then all list items redraws right, but if I have done scrolling before font changing, then list items redraws a little bit upper or lower than list grid horizontal lines, i. e. items text becomes overlapped by grid lines.

Here is how I changing list font:

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: three people have clicked button UP and nobody knows what it can be? :(

UPD 1: here's the class code http://pastebin.com/UdXYEpF7 .h http://pastebin.com/2HYe5AEd .cpp

brightside90
  • 243
  • 3
  • 13
  • 1
    You have show very little information about your class, it's difficult to figure out anything. From what you have described it doesn't look like there is a bug. If you want to change the font in the middle of the program then scroll to zero and change the font, then scroll back to the old position. – Barmak Shemirani May 17 '15 at 14:31
  • Don't you need to implement the DrawItem() method for the Owner Drawn list ctrl? – cha May 18 '15 at 06:23
  • @BarmakShemirani I've added my class code in question – brightside90 May 18 '15 at 07:25
  • @cha yes, I need, you can see it in my code (UPD 1) – brightside90 May 18 '15 at 07:26
  • @BarmakShemirani if I'll do like you said, then it will perfectly work, but I don't know proper way to return scroll back to the old position, because old position before font changing and after - this is two different things. – brightside90 May 18 '15 at 09:15

1 Answers1

1

I tried your code, it looks like ListView is exchanging messages with scroller, the header is also being resized, it's not really worth investigating. It's fine if you just set position to zero, you can save the old position and put it back.

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);
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • Yeah, that's nice approach. I will use it in my code. Only one thing, that I think is necessary to add here - is SetRedraw(FALSE); before EnsureVisible(0, 0); and SetRedraw(TRUE); after EnsureVisible(saveIndex, 1); to avoid scroll bar flickering. Thank you! – brightside90 May 19 '15 at 06:21