问题描述
有人可以确认来自 Microsoft 的 this sample code 是否无法使用 SetDCBrushColor
恢复自定义画笔集吗?
case WM_PAINT:
{
hdc = BeginPaint(hWnd,&ps);
// Initializing original object
HGdioBJ original = NULL;
// Saving the original object
original = SelectObject(hdc,GetStockObject(DC_PEN));
// ...
SelectObject(hdc,GetStockObject(BLACK_PEN));
Rectangle(hdc,200,200);
SelectObject(hdc,GetStockObject(DC_PEN));
SelectObject(hdc,GetStockObject(DC_Brush));
SetDCBrushColor(hdc,RGB(255,0));
SetDCPenColor(hdc,RGB(0,255));
Rectangle(hdc,100,300,400);
SetDCBrushColor(hdc,255,0));
Rectangle(hdc,150,500,300);
// Restoring the original object
SelectObject(hdc,original);
}
break;
//...
Paul Watt 和其他海报,建议我们使用 SelectObject
分别恢复对笔和画笔的更改,或者我们使用 SaveDC
和 RestoreDC
。
https://www.codeproject.com/Articles/224754/Guide-to-Win32-Memory-DC
// Setup paint for first layer.
HGdioBJ hOldBrush = ::SelectObject(hDC,hBrush);
HGdioBJ hOldPen = ::SelectObject(hDC,hPen);
HGdioBJ hOldFont = ::SelectObject(hDC,hFont);
HGdioBJ hOldMan = ::SelectObject(hDC,hBmp);
// ... Paint a motley display
::SelectObject(hDC,hOldBrush);
::SelectObject(hDC,hOldPen);
::SelectObject(hDC,hOldFont);
::SelectObject(hDC,hOldMan);
或者使用 SaveDC
和 RestoreDC
来简化:
// Take a snap-shot of the current state of the DC
//https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-savedc
int SaveDC(
__in HDC hdc,// Handle to the DC
);
// Restore the DC to a prevIoUsly saved state
int RestoreDC(
__in HDC hdc,// Handle to the DC
__in int nSavedDC // Saved state claim ticket
);
我意识到我需要在我创建的任何不是库存对象的画笔/笔上使用 DeleteObject
。
Microsoft 是否忘记将 SelectObject
与之前保存的原始画笔版本一起使用? (或者 Microsoft 是否应该使用 SaveDC
和 RestoreDC
?)
解决方法
微软是否忘记将 SelectObject 与以前保存的 原版刷机?
我会说:是的,他们做到了!
在 SetDCPenColor
调用的情况下,没有问题,因为恢复原始(已保存)笔将恢复所做的更改。该示例似乎忘记保存(并随后恢复)原始画笔;如果这是自定义画笔,那么仅使用 SetDCBrushColor
恢复画笔颜色(恕我直言)不足以恢复。
但问题并没有就此结束!链接的示例也“忘记”调用 EndPaint
!来自here:
对 BeginPaint 的每次调用都必须有一个对 EndPaint 功能。
或者微软应该使用 SaveDC 和 RestoreDC 吗?
为了方便和代码安全,我想说这是最好的策略:保存和恢复整个 DC 状态可以避免以后可能出现的任何问题,如果/当对DC 在未来的代码修订中进行。在 SaveDC()
和 RestoreDC()
调用中括起您的代码还具有恢复字体颜色、文本模式、映射模式等等的优势。
但是,对于可能非常频繁地执行的代码,仅保存和恢复您实际更改的组件可能会显示性能改进(尤其是在较旧或较慢的处理器上)。