我在派生自 CListBox 的 CMyListBox 类上使用了所有者绘制的策略。我只希望在列表框中插入项目时执行 DrawItem() 方法。但是该方法被多次调用。我如何更改以在需要时调用它。
3 回答
您始终可以通过将内容输出到内存位图然后绘制它来缓存初始绘图,这确实意味着您需要跟踪某些内容何时发生更改,以便您可以再次运行实际的渲染代码。如果有很多渲染代码,它确实可以节省每次运行渲染代码。
我已经完全按照 Kieron 建议的方式缓存位图,但仅在非常昂贵的渲染代码中。实际上,我必须保留多个缓存的“状态”,具体取决于项目是否突出显示、禁用、正常等(这是用于工具栏按钮,而不是 listitem - 但我认为它适用)。我只在第一次需要时缓存预渲染的图像——这样我只缓存我实际需要的“状态”。
我的绘图是纯 GDI 调用。主要是位图操作和其他只需要时间的绘图,加上我经常被重绘(没有充分的理由 - 长篇大论)。
改变我正在使用的框架(MFC 和 Stingray)中的基础不是一个选项。在所有其他优化都不够好(该死的慢虚拟机!!)之后,缓存是最后的手段。
通常,当您无效时(在这种情况下为 DrawItem),绘图速度足够快。我会看看你在 DrawItem 中到底在做什么。除非没有其他选项,否则我会研究渲染所需的缓存数据和计算,而不是渲染本身(例如最终位图)。
另外,我读到 Vista 渲染更加优化,它们缓存您在窗口上绘制的内容,以减少包含无效/重绘周期,例如,当一个窗口从另一个窗口移动时。
只要需要在列表框中绘制任何给定项目,就会调用 DrawItem() 方法。如果您不响应它,您可能会在列表框中获得一个空白区域,其中绘制的数据已被擦除并且您没有刷新它。如果你真的不认为绘图是必要的,你可以做类似的事情
void CMyListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
if (!m_DrawingEnabled)
return;
}
其中 m_DrawingEnabled 是您为停止不必要的绘制而维护的成员,