我是否需要在释放之前将之前的笔重新select 放入 DC 中?

Do I need to re-select the previous pen into the DC, just before releasing it?

我有以下对话框 class:

class CInputDlg : public CDialog
{
public:
    CInputDlg(CWnd* pParent = NULL);
    virtual ~CInputDlg();

DECLARE_MESSAGE_MAP();

protected:
    afx_msg BOOL OnInitDialog();
    afx_msg void OnCancel();
    afx_msg void OnPaint();

private:
    CPen m_Pen;
};

回调例程的实现如下:

BOOL CInputDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    m_Pen.CreatePen(...);
    return TRUE;
}

void CInputDlg::OnCancel()
{
    m_Pen.DeleteObject();
    CDialog::OnCancel();
}

void CInputDlg::OnPaint()
{
    CPaintDC dc(this);
    CDC* pDC = GetDC();
    pDC->SelectObject(m_Pen);
    ...
    ReleaseDC(pDC);
}

如您所见,在OnPaint例程中,我没有重新select之前的笔入DC

我这样做是在没有必要的假设下,因为无论如何我都会发布 DC。

最后,在 OnCancel 例程中,我删除了笔(在某些 DC 中可能 selected)。

是我这样做错了,还是我上面的假设是正确的?

MSDN 并不清楚我何时可以或应该删除对象。

我猜这个问题是因为我对DC的理解不够。

谢谢。

释放一个device context without restoring it to its initial state. At any given time a device context stores a reference to an object of 7 graphics object类型是错误的。这些对象归设备上下文所有,需要在设备上下文被销毁时清理。

SelectObject

selects an object into the specified device context (DC). The new object replaces the previous object of the same type.

因此,不恢复设备上下文会留下对它不拥有的对象的引用。到了拆毁的时候,坏事就来了1.

规则很简单:始终在将 DC 传递回其所有者(调用者或系统)之前还原 DC。如果跟踪每个图形对象太繁琐或不切实际,您可以在退出时使用 SaveDC on entry and RestoreDC

阅读奖励:


1 理论上无论如何。因为那里有太多糟糕的代码,所以系统对有问题的 GDI 资源管理实现了相当多的弹性。