我有一个win32应用程序在由活动x控件托管的IE Web浏览器中运行。我的应用程序作为活动x控件的子窗口。当我调整IE的大小时,整个操作系统将被冻结。 通过使用远程调试器,当桌面被冻结时,我发现我的应用程序运行到IntersectClipRect(在Win8.1上)或GetDC(在Win10上)。这两个API没有返回,似乎DWM被阻止复合桌面。 在Win 7上运行它没有问题。 我还没有在MSDN上找到任何解释,nether IntersectClipRect和GetDC都不应该随时被阻止。 以下是我处理WM_PAINT和WM_ERASEBACKGROUND消息的代码:
BOOL CRunView::OnEraseBkgnd(CDC* pDC)
{
::EraseWindow(pDC, this);
return TRUE;
}
void EraseWindow(CDC* pDC, CWnd * window)
{
// Set brush to desired background color.
CBrush
backBrush(GetWindowLong(window->GetSafeHwnd(), GWL_USERDATA)),
*pOldBrush = pDC->SelectObject(&backBrush);
CRect rect;
SelectPalette(pDC->m_hDC, (HPALETTE)getPalette(), false);
RealizePalette(pDC->m_hDC);
pDC->GetClipBox(&rect);
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
pDC->SelectObject(pOldBrush);
}
void CRunView::OnPaint()
{
RECT r = { -1, -1, -1, -1 };
INT32 zoomFactor = getZoomFactor();
if (zoomFactor <= 1)
{
GetUpdateRect(&r);
}
else {
GetClientRect(&r);
r.right = r.right / zoomFactor;
r.bottom = r.bottom / zoomFactor;
}
CPaintDC dc(this);
SendRepaintRequest(WindowHandle, r.left, r.top, r.right, r.bottom);
}
OnPaint中的SendRepaintRequest将通知另一个线程在主窗口的客户区域上绘制一些东西。因此,大多数绘图操作不在我的应用程序的UI线程上。在主窗口上绘图时,我使用GetDC来获取窗口dc,在绘图之后,我使用ReleaseDC。当应用程序未托管在活动x控件中时,该应用程序运行良好。