我有一个函数,它取一个位图图像的矩形区域,将其重新缩放到不同的尺寸,并在我的对话框应用程序中的窗口内部的某个偏移处绘制它:
void DrawImage(HANDLE hImageBitmap,
CDC* pDstDC,const CRect& dstRect,
CDC* pSrcDC,const CRect& srcRect)
{
pSrcDC->SelectObject(hImageBitmap);
pDstDC->SetStretchBltMode(HALFTONE);
pDstDC->StretchBlt
(
dstRect.left,dstRect.top,dstRect.Width(),dstRect.Height(),pSrcDC,
srcRect.left,srcRect.top,srcRect.Width(),srcRect.Height(),SRCCOPY
);
}
我使用CWnd m_cImageWindow
成员变量创建并维护窗口。
我从对话框的OnPaint
处理程序执行绘图,如下所示:
CDC* pDC = m_cImageWindow.GetDC();
CDC cDC;
cDC.CreateCompatibleDC(pDC);
CRect srcRect = ...;
CRect dstRect = ...;
DrawImage(m_hImageBitmap,pDC,dstRect,&cDC,srcRect);
cDC.DeleteDC();
m_cImageWindow.ReleaseDC(pDC);
我有两个问题:
每当我更改绘图参数时,都会看到闪烁。从我在这里和那里读到的,解决这个问题的标准方法是使用临时DC进行双缓冲。但据我了解,这正是我一直在做的事情。
如果某些目标区域落在窗口之外,则会将其绘制在对话框中的其他控件上。我可以通过为每个控件调用MoveWindow
或SetWindowPos
来部分解决此问题。但我仍然可以看到背后闪烁的图像。我试过以各种不同的方式调用SetWindowPos
,希望它能控制严格的Z控制顺序。
谢谢。
答案 0 :(得分:1)
将图像绘制到子窗口中应该在该子窗口的WM_PAINT处理程序中完成,而不是对话框。您的子窗口可能需要记住父对话框提供的信息,以便它可以独立绘制。通过在对话框的WM_PAINT处理程序中绘制窗口,您可能会绘制得比必要更频繁(并且可能不会导致在图像窗口中进行验证)。
对话框应该具有WS_CLIPCHILDREN窗口样式,并且图像窗口可能应该具有WS_CLIPSIBLINGS。这样可以防止对话框控件相互覆盖,并且可以通过允许更少的更新来减少闪烁。
如果图像始终完全覆盖整个图像窗口,那么您需要确保图像窗口没有发生背景擦除,因为这会导致背景颜色闪烁喜欢画画。有几种方法可以做到这一点,但最简单的方法是提供一个只返回TRUE的WM_ERASEBKGND处理程序。
答案 1 :(得分:0)
我发现OnEraseBkgnd是最小化绘制位图闪烁的最佳位置。