【问题标题】:How to prevent vertical scrollbar flicker in CListCtrl after re-population of its items重新填充其项目后如何防止 CListCtrl 中的垂直滚动条闪烁
【发布时间】:2015-10-18 12:21:06
【问题描述】:

我的目标是在我的 MFC 应用程序中以 1 秒的频率重绘 CListCtrl 以刷新其内容。我使用以下伪代码来做到这一点:

//CListCtrl lstLog;

//Prevent redrawing
lstLog.SetRedraw(FALSE);

//Remove all items
lstLog.DeleteAllItems();

for(int i = 0; i < 100; i++)
{
    lstLog.InsertItem(i, str);
}

//Scroll to the bottom of the list
int scrollY = lstLog.GetItemCount() * nItemHeight;

//Allow back redrawing
lstLog.SetRedraw(TRUE);
lstLog.Scroll(CSize(0, scrollY));

除了垂直滚动条在我使用此方法时似乎闪烁或快速上下跳跃之外,此方法效果很好。

我可以做些什么来防止这种情况发生吗?

【问题讨论】:

  • 在重新开启重绘之前先滚动会有帮助吗?
  • @JonathanPotter:你知道,如果我这样做,它会产生一种奇怪的效果。在第一次迭代中它滚动到底部,然后在下一次迭代中它滚动到最顶部,然后重复。我检查了scrollY,该参数似乎没有改变。
  • 只是滚动条或列表本身?
  • @JonathanPotter:整个列表以及滚动条...
  • 如果从滚动量中减去 listview 控件的客户端高度会发生什么情况(从技术上讲,您向下滚动得太远了,尽管我本以为 listview 会剪切滚动但它可能正在做某事像环绕一样奇怪)。

标签: c++ windows winapi mfc clistctrl


【解决方案1】:

两件事:

  • 避免不必要地更新列表框。这不仅会浪费时间,还会干扰用户尝试从中选择内容。尽量只更新那些必要的元素。
  • 查看LockWindowUpdate()。编写一个 RAII 助手,在重新填充时锁定列表框。确保检查调用的结果,并且仅在第一次调用成功时才在 dtor 中反转此结果,以免干扰嵌套调用。

【讨论】:

  • @UlrichEckhardt:是的,我同意。 LockWindowUpdate 不适合使用它。尽管如此,我还是尝试了它,但它使闪烁变得更糟。现在有了它,整个列表控件似乎在闪烁。
  • @UlrichEckhardt: "Avoid unnecessarily updating the listbox" -- 所以你是说 Windows 任务管理器编码错误?
  • 这是一个问题的实际答案,@Jonathan。但是,SetWindowRedraw() 正是他们正在做的事情,而且它似乎不起作用......
  • 我的意思是你应该避免改变内容,除非内容真的需要改变。此外,如果您构建此事件库,则需要更改的项目将更改得更快,而不是延迟最多 1 秒。
猜你喜欢
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2010-11-25
  • 2012-01-19
  • 1970-01-01
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多