【问题标题】:Wrong CListCtrl items drawing错误的 CListCtrl 项目绘制
【发布时间】:2015-05-14 09:41:46
【问题描述】:

我的 CListCtrlEx 派生自 CListCtrl。此列表具有样式 LVS_REPORT、LVS_OWNERDRAWFIXED 和 LVS_EX_GRIDLINES。我增加了更改此列表字体的可能性。这工作正常,但有一件坏事 - 如果我更改字体并且在此之前我没有滚动列表,那么所有列表项都会重绘,但如果我在字体更改之前完成滚动,那么列表项会重绘一点点上方或低于列表网格水平线,即。 e.项目文本被网格线重叠。

这是我更改列表字体的方法:

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);
}

更新: 三个人点击了UP按钮,没人知道它是什么? :(

UPD 1: 这是课程代码 http://pastebin.com/UdXYEpF7.h http://pastebin.com/2HYe5AEd.cpp

【问题讨论】:

  • 你显示的关于你的班级的信息很少,很难弄清楚任何事情。从您描述的情况来看,它似乎没有错误。如果您想在程序中间更改字体然后滚动到零并更改字体,然后滚动回旧位置。
  • 所有者绘制列表ctrl不需要实现DrawItem()方法吗?
  • @BarmakShemirani 我添加了有问题的课程代码
  • @cha 是的,我需要,你可以在我的代码中看到它(UPD 1)
  • @BarmakShemirani 如果我像你说的那样做,那么它将完美地工作,但我不知道将滚动返回到旧位置的正确方法,因为在字体更改之前和之后的旧位置- 这是两个不同的东西。

标签: c++ windows user-interface mfc clistctrl


【解决方案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);
}

【讨论】:

  • 是的,这是一个不错的方法。我将在我的代码中使用它。只有一件事,我认为有必要在这里添加 - 是 SetRedraw(FALSE);在 EnsureVisible(0, 0) 之前;和 SetRedraw(TRUE);在 EnsureVisible(saveIndex, 1) 之后;以避免滚动条闪烁。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 2014-06-01
相关资源
最近更新 更多