我有以下对话框类:
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的了解不足。
谢谢。
答案 0 :(得分:2)
释放device context而不将其恢复到初始状态是错误的。在任何给定时间,设备上下文存储对7 graphics object类型的对象的引用。这些对象由设备上下文拥有,需要在设备上下文被破坏时进行清理。
将对象选择到指定的设备上下文(DC)中。新对象替换相同类型的上一个对象。
不恢复设备上下文因此会留下对它不拥有的对象的引用。当它被拆除时,不好的事情发生在 1 。
规则很简单:始终在将DC传回其所有者(调用者或系统)之前将其还原。如果跟踪每个图形对象过于繁琐或不切实际,您可以在输入时使用SaveDC,在退出时使用RestoreDC。
奖金阅读:
<小时/> 1 无论如何理论。因为那里有太多不好的代码,系统已经对错误的GDI资源管理实现了相当大的弹性。