Winapi 我是否需要在释放前将上一支笔重新选择到DC中?

Winapi 我是否需要在释放前将上一支笔重新选择到DC中?,winapi,mfc,gdi,Winapi,Mfc,Gdi,我有以下对话框类: 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

我有以下对话框类:

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不太清楚我何时可以或应该删除对象

我想这个问题是因为我对跟单信用证理解不足


谢谢。

在未将其恢复到初始状态的情况下释放是错误的。在任何给定时间,设备上下文存储对7种类型对象的引用。这些对象属于设备上下文,当设备上下文被销毁时,需要清理这些对象

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

因此,不还原设备上下文会使其保留对它不拥有的对象的引用。到了拆毁它的时候,坏事就发生了

规则很简单:在将DC传递回其所有者(调用方或系统)之前,始终还原DC。如果保持对每个图形对象的跟踪过于繁琐或不可行,则可以在进入和退出时使用

额外阅读:



1不管怎样,理论上是这样。因为有太多糟糕的代码,系统对有缺陷的GDI资源管理实现了相当大的恢复力。

这是一个你应该能够自己回答的问题:谁拥有GDI资源(
SelectObject
不转移所有权)?@RbMm:谢谢。此链接中的描述不涉及释放DC的情况。这就是我的问题。你能参考一下这个场景吗?@IInspectable:我不明白你的评论。我创造了这支钢笔,这意味着我拥有它。。。正确的?我是否可以在
OnCancel
例程中安全地删除此对象,或者它是否可能在某些DC中被选中?谢谢。你所做的直接违反了MSDN指南。试图解释当你做错事时可能发生的事情是没有多大成效的。做对了,你就不必去想它,也不必担心你的程序会崩溃。这种错误很早就开始了,顺便说一句,缓存对象是明智的,因为它们的创建成本很高,存储成本也很低。像钢笔这样的绘图对象正好相反,创建起来非常便宜,存储起来也非常昂贵。所以首先解决这个问题,去掉m_Pen变量。现在您不得不正确地编写代码。还要注意,这个特定的问题是关于
ReleaseDC
,它不会删除DC。它只是将DC返回到缓存。因此,缓存现在有一个脏对象,这不仅意味着泄漏,还意味着当您请求另一个DC时,您可能会得到一个脏对象。