【发布时间】:2017-10-29 19:59:21
【问题描述】:
我有一个函数,它获取位图图像的矩形区域,将其重新缩放为不同的尺寸,并在我的对话框应用程序中的窗口内的某个偏移处绘制它:
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 顺序。
谢谢。
【问题讨论】:
-
OnPaint事件处理程序不应创建自己的 DC 以供绘制。您应该使用CPaintDC类。 -
@CodyGray:谢谢。我已经尝试过了,但它似乎对我不起作用。可能是因为我创建的paint-DC 属于对话框本身,而不是我尝试绘制的窗口。您能否提供一些更具体的证据来说明“
OnPaint事件处理程序不应创建自己的 DC”的原因?谢谢。 -
嗯……你为什么要处理一个窗口(一个对话框)的绘制事件并试图在一个不同的窗口上绘制?如果要在窗口上绘画,请处理 该窗口的 绘画事件。
-
具体证据,为什么
OnPaint处理程序不应创建自己的 DC:该 DC 从不验证无效区域,保留WM_PAINT消息流。 (CPaintDC验证其 c'tor 中的无效区域。) -
那为什么不直接在对话框上画呢?使用
WS_CLIPCHILDREN避免在其他控件上绘画。
标签: winapi mfc gdi stretchblt setwindowpos