1

我在派生自 CListBox 的 CMyListBox 类上使用了所有者绘制的策略。我只希望在列表框中插入项目时执行 DrawItem() 方法。但是该方法被多次调用。我如何更改以在需要时调用它。

4

3 回答 3

1

您始终可以通过将内容输出到内存位图然后绘制它来缓存初始绘图,这确实意味着您需要跟踪某些内容何时发生更改,以便您可以再次运行实际的渲染代码。如果有很多渲染代码,它确实可以节省每次运行渲染代码。

于 2008-10-29T12:13:29.127 回答
1

我已经完全按照 Kieron 建议的方式缓存位图,但在非常昂贵的渲染代码中。实际上,我必须保留多个缓存的“状态”,具体取决于项目是否突出显示、禁用、正常等(这是用于工具栏按钮,而不是 listitem - 但我认为它适用)。我只在第一次需要时缓存预渲染的图像——这样我只缓存我实际需要的“状态”。

我的绘图是纯 GDI 调用。主要是位图操作和其他只需要时间的绘图,加上我经常被重绘(没有充分的理由 - 长篇大论)。

改变我正在使用的框架(MFC 和 Stingray)中的基础不是一个选项。在所有其他优化都不够好(该死的慢虚拟机!!)之后,缓存是最后的手段。

通常,当您无效时(在这种情况下为 DrawItem),绘图速度足够快。我会看看你在 DrawItem 中到底在做什么。除非没有其他选项,否则我会研究渲染所需的缓存数据和计算,而不是渲染本身(例如最终位图)。

另外,我读到 Vista 渲染更加优化,它们缓存您在窗口上绘制的内容,以减少包含无效/重绘周期,例如,当一个窗口从另一个窗口移动时。

于 2008-10-29T13:14:04.260 回答
0

只要需要在列表框中绘制任何给定项目,就会调用 DrawItem() 方法。如果您不响应它,您可能会在列表框中获得一个空白区域,其中绘制的数据已被擦除并且您没有刷新它。如果你真的不认为绘图是必要的,你可以做类似的事情

void CMyListBox::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
   if (!m_DrawingEnabled)
     return;
}

其中 m_DrawingEnabled 是您为停止不必要的绘制而维护的成员,

于 2008-10-29T12:06:00.483 回答