请确认选择自定义笔和自定义画笔时恢复DC的最佳方式
Please confirm the best way to Restore the DC when a custom Pen and a custom Brush are selected
有人可以确认 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,0,0,200,200);
SelectObject(hdc, GetStockObject(DC_PEN));
SelectObject(hdc, GetStockObject(DC_BRUSH));
SetDCBrushColor(hdc, RGB(255,0,0));
SetDCPenColor(hdc, RGB(0,0,255));
Rectangle(hdc,100,300,200,400);
SetDCBrushColor(hdc, RGB(0,255,0));
Rectangle(hdc,300,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
);
我意识到我需要对我创建的任何 brushes/pens 非库存对象使用 DeleteObject
。
微软是不是忘记了使用SelectObject
之前保存的原刷版本? (或者微软应该使用 SaveDC
和 RestoreDC
吗?)
Did Microsoft forget to use SelectObject with a previously saved
version of the original brush?
我会说:是的,他们做到了!
在 SetDCPenColor
调用的情况下,没有问题,因为恢复原始(保存的)笔将恢复所做的更改。该示例似乎忘记保存(并随后恢复)原始画笔;如果这是自定义画笔,那么仅使用 SetDCBrushColor
恢复画笔颜色(恕我直言)不足以恢复。
但问题并没有就此结束!链接示例也有 'forgotten' 调用 EndPaint
!来自 here:
Each call to BeginPaint must have a corresponding call to the EndPaint
function.
Or should Microsoft have used SaveDC and RestoreDC?
为了方便和代码安全,我认为这是最好的策略:保存和恢复 整个 DC 状态可以避免以后可能出现的任何问题 if/when 在未来的代码修订中对 DC 进行了其他更改。将您的代码放在 SaveDC()
和 RestoreDC()
调用中还具有恢复字体颜色、文本模式、映射模式等 等 .
的优势
但是,对于可能执行得非常频繁的代码,仅保存和恢复您实际更改的组件可能会显示性能改进(尤其是在较旧或较慢的处理器上)。
有人可以确认 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,0,0,200,200);
SelectObject(hdc, GetStockObject(DC_PEN));
SelectObject(hdc, GetStockObject(DC_BRUSH));
SetDCBrushColor(hdc, RGB(255,0,0));
SetDCPenColor(hdc, RGB(0,0,255));
Rectangle(hdc,100,300,200,400);
SetDCBrushColor(hdc, RGB(0,255,0));
Rectangle(hdc,300,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
);
我意识到我需要对我创建的任何 brushes/pens 非库存对象使用 DeleteObject
。
微软是不是忘记了使用SelectObject
之前保存的原刷版本? (或者微软应该使用 SaveDC
和 RestoreDC
吗?)
Did Microsoft forget to use SelectObject with a previously saved version of the original brush?
我会说:是的,他们做到了!
在 SetDCPenColor
调用的情况下,没有问题,因为恢复原始(保存的)笔将恢复所做的更改。该示例似乎忘记保存(并随后恢复)原始画笔;如果这是自定义画笔,那么仅使用 SetDCBrushColor
恢复画笔颜色(恕我直言)不足以恢复。
但问题并没有就此结束!链接示例也有 'forgotten' 调用 EndPaint
!来自 here:
Each call to BeginPaint must have a corresponding call to the EndPaint function.
Or should Microsoft have used SaveDC and RestoreDC?
为了方便和代码安全,我认为这是最好的策略:保存和恢复 整个 DC 状态可以避免以后可能出现的任何问题 if/when 在未来的代码修订中对 DC 进行了其他更改。将您的代码放在 SaveDC()
和 RestoreDC()
调用中还具有恢复字体颜色、文本模式、映射模式等 等 .
但是,对于可能执行得非常频繁的代码,仅保存和恢复您实际更改的组件可能会显示性能改进(尤其是在较旧或较慢的处理器上)。