1

有人可以确认微软的这个示例代码是否无法恢复自定义画笔集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来分别恢复对笔和画笔的更改,或者我们使用SaveDCRestoreDC

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);

或者使用SaveDCandRestoreDC来简化:

// 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以前保存的原始画笔版本?(或者微软应该使用SaveDCRestoreDC?)

4

1 回答 1

1

Microsoft 是否忘记将 SelectObject 与先前保存的原始画笔版本一起使用?

我会说:是的,他们做到了!

SetDCPenColor通话的情况下,没有问题,因为恢复原始(保存的)笔将恢复所做的更改。似乎该示例忘记保存(并随后恢复)原始画笔;如果这是一个自定义画笔,那么简单地恢复画笔颜色SetDCBrushColor将(恕我直言)不足以恢复。

但问题并没有就此结束!链接的示例也“忘记”调用EndPaint!从这里

对BeginPaint的每次调用都必须有对EndPaint 函数的相应调用。


或者微软应该使用 SaveDC 和 RestoreDC 吗?

为了方便和代码安全,我会说这是最好的策略:保存和恢复整个DC 状态可以避免以后在未来代码修订中对 DC 进行其他更改时可能出现的任何问题。将代码括起来SaveDC()RestoreDC()调用还具有恢复字体颜色、文本模式、映射模式的优势。

但是,对于可能非常频繁地执行的代码,仅保存和恢复您实际更改的组件可能会显示性能改进(尤其是在较旧或较慢的处理器上)。

于 2021-03-08T20:23:15.020 回答