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

时间:2017-06-03 10:33:45

标签: winapi mfc device-context

我有以下对话框类:

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例程中,我不会将之前的笔重新选入DC。

我这样做的假设是没有必要,因为我无论如何都要释放DC。

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

这样做我错了,或者我的假设是正确的吗?

MSDN对于何时可以或应该删除对象不是很清楚。

我想这个问题是由于我对DC的了解不足。

谢谢。

1 个答案:

答案 0 :(得分:2)

释放device context而不将其恢复到初始状态是错误的。在任何给定时间,设备上下文存储对7 graphics object类型的对象的引用。这些对象由设备上下文拥有,需要在设备上下文被破坏时进行清理。

SelectObject

  

将对象选择到指定的设备上下文(DC)中。新对象替换相同类型的上一个对象。

不恢复设备上下文因此会留下对它不拥有的对象的引用。当它被拆除时,不好的事情发生在 1

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

奖金阅读:

<小时/> 1 无论如何理论。因为那里有太多不好的代码,系统已经对错误的GDI资源管理实现了相当大的弹性。