绘图算法在普通DC正常但兼容DC+StretchBlt失效问题排查
问题排查与解决方案
1. 兼容DC未绑定兼容位图(核心问题)
CreateCompatibleDC(hdc)创建的兼容DC默认关联1x1的单色位图,并非你需要的800x400像素画布。如果未通过CreateCompatibleBitmap(hdc, 800, 400)创建匹配位图并选入兼容DC,所有绘制操作都没有有效存储载体——哪怕FillRect返回成功,也只是在那个1x1的单色位图上执行,StretchBlt自然无法输出内容。
必须在绘制前完成兼容位图的创建与选入,用完后正确释放资源:
PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // 创建兼容DC与匹配位图 HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmMem = CreateCompatibleBitmap(hdc, 800, 400); HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem); // 在兼容DC上绘制内容 RECT rcMem = {0, 0, 800, 400}; FillRect(hdcMem, &rcMem, (HBRUSH)GetStockObject(WHITE_BRUSH)); // 此处添加其他绘制逻辑 // 获取实际窗口客户区尺寸,执行缩放绘制 RECT rcClient; GetClientRect(hWnd, &rcClient); StretchBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, 800, 400, SRCCOPY); // 清理GDI对象,避免泄漏 SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); EndPaint(hWnd, &ps);
2. 检查StretchBlt参数正确性
- 源矩形必须为
(0, 0, 800, 400),覆盖兼容DC的完整画布 - 目标矩形需匹配实际窗口客户区尺寸(通过
GetClientRect获取),确保是800x400的2倍比例 - 确认ROP码为
SRCCOPY,避免使用BLACKNESS这类会输出黑色的模式
3. 验证GDI对象生命周期
- 选入新位图后,必须在销毁DC前将旧位图选回兼容DC,否则会造成GDI对象泄漏,引发后续操作异常
- 确保
BeginPaint与EndPaint配对使用,不要在WM_PAINT消息之外的时机直接操作窗口DC
4. 排查窗口消息处理逻辑
如果绘制逻辑在WM_PAINT之外的消息(如WM_SIZE)中执行,需调用InvalidateRect触发重绘,确保窗口内容及时更新
内容的提问来源于stack exchange,提问作者HelpfulHelper
相关产品推荐
相关产品推荐

