禁用擦除背景事件。当 wxWidgets 想要更新显示时,它会发出两个事件:一个擦除背景事件和一个绘制事件。您必须为擦除背景事件实现一个空方法(换句话说:拦截 EVT_ERASE_BACKGROUND 事件并且不要调用 event.Skip())。
由于您的位图覆盖了整个面板,因此您无需擦除背景。
使用 wxClientDC 的原因是因为“在 EVT_PAINT() 处理程序中使用 wxPaintDC 会自动将剪切区域设置为窗口的损坏区域。不会出现在该区域之外绘制的尝试。”
由于剪切区域存在问题,因此忽略剪切区域“解决”了问题。
这在 wxPaintDC 和 wxClientDC 类参考文档的详细描述部分中有介绍。
这是一个“更好”答案的草图。这比您的计时器和重绘所有解决方案要复杂得多,但从某种意义上说,它更节省系统资源,因此您的应用程序将变得更具响应性。
需要两件事。
显示位图的更快方法
仅重绘位图的损坏区域。
(注意:在 wxPaintDC 上使用 DrawBitmap 实际上是处理整个位图,然后对输出进行裁剪)
为了加快位图部分的显示速度,您需要将位图绘制到内存 DC 中,并将其放在方便的地方(此解决方案不节省内存,但这通常不是现代计算机的问题),以便您可以将所需的部分粘贴到 wxPaintDC 中。
wxMemoryDC memdc;
memdc.SelectObject(bitmap);
dc.Blit( ...
这是 Blit 参数的描述http://docs.wxwidgets.org/2.8/wx_wxdc.html#wxdcblit
要仅处理损坏的区域,您需要调用 GetUpdateRegion 并使用区域迭代器通过 reutun 工作。我看到您正在使用滚动面板,因此您必须允许这样做,因为更新区域是根据窗口中的客户区域,而不是您的 bitmap 中的逻辑区域。
wxRegionIterator upd(GetUpdateRegion());
while ( upd )
{ wxRect rect(upd,GetRect());
// calculate damaged rectangle in terms of your complete bitmap
...
// blit the calculated rectangle from bitmap in memoryDC to damaged recatngle in wxPaintDC
...
upd++;
{