读书人

再理解上这句话:不能删除已选入DC的G

发布时间: 2012-12-14 10:33:08 作者: rapoo

再理解下这句话:不能删除已选入DC的GDI对象
先提问题吧:删除了会报错吗?

从书上copy的代码:
CPaintDC dc(this)
CBrush brush(RGB(255,0,0))
dc.SelectObject(&brush);
dc.Ellipse(0,0,200,200);
解释是:因brush和dc都在栈上创建,且brush后创建,所以brush先析构,所以不出错。

把第一句和第二句调换,那按理说该报错了。vc6和vs2005都试过了,没错。
所以删除选入DC的GDI对象不会报错。那就是说能删除了,只要以后不再使用就行了。

[最优解释]

引用:
没错,析构函数会DeleteObject,但是MSDN是这样说的:
引用Return value
If the function succeeds, the return value is nonzero.
If the specified handle is not valid or is currently selected into a DC, the ret……




{
CPaintDC dc(this)
CBrush brush(RGB(255,0,0))
CBrush* pOld= dc.SelectObject(&brush);
dc.Ellipse(0,0,200,200);

dc.SelectObect((HBRUSH)*pOld);


}

你好,楼主 代码没有 selectobject(旧的画笔);

难道没有问题???

windows程序设计一书上,还有前辈们的敦敦教导,都说:释放之前,无论是析构函数还是你手动释放

都要将旧画笔选择到你的dc中。

然后删除画笔,dc,删除dc,画笔似乎没有顺序限制吧。

我觉得楼主要问的问题是:删除dc,画笔似乎没有顺序限制??


::createpen这个函数 可以看出来,其的参数没有dc,说明创建是不需要先获得dc,释放也是一样的,

也没有dc作为参数。想释放就释放呗。




[其他解释]
首先楼主要理解:
不能删除已选入DC的GDI对象

这句话的后果是什么? 不是程序崩溃,是内存泄露。

brush就释放不了了。所以需要保存selectobject的返回值指针。然后再删除bursh,选回来保存的指针再删除brush。
[其他解释]
没错,析构函数会DeleteObject,但是MSDN是这样说的:
引用
Return value
If the function succeeds, the return value is nonzero.
If the specified handle is not valid or is currently selected into a DC, the return value is zero.

Remarks
Do not delete a drawing object (pen or brush) while it is still selected into a DC.


事实上真的一定是MSDN说的那样吗?可以作个测试验证一下,结果发现DeleteObject删除已选入DC的GDI对象返回值是非0,就是删除成功了。尽管如此,我们还是不要做违背文档的事情,而且我也没有在其它系统测试过,或者在其它系统环境下就真的如MSDN所说呢。
[其他解释]
是的,内存泄露了
[其他解释]
沙发放了这么久
为嘛没人坐?
我诅咒看见不说话的晚上都梦到如花和酸菜
[其他解释]
CPaintDC dc(this)
CBrush brush(RGB(255,0,0))

这两句调换不会出错的
[其他解释]
不会的,你根本 就是没有涉及到操作dc
[其他解释]
引用:
CPaintDC dc(this)
CBrush brush(RGB(255,0,0))

这两句调换不会出错的

那关于这段代码的解释:因brush和dc都在栈上创建,且brush后创建,所以brush先析构,所以不出错。
该怎么理解呢
[其他解释]
引用:
不会的,你根本 就是没有涉及到操作dc

dc.Ellipse(0,0,200,200);
??
[其他解释]
引用:
引用:不会的,你根本 就是没有涉及到操作dc


dc.Ellipse(0,0,200,200);
??

这是你的后续操作,才会用到dc
[其他解释]
帮楼主顶一下, 我也没有理解,


[其他解释]
似乎楼主的代码泄露了吧

{
CPaintDC dc(this)
CBrush brush(RGB(255,0,0))
CBrush* pOld= dc.SelectObject(&brush);
dc.Ellipse(0,0,200,200);

dc.SelectObect((HBRUSH)*pOld);


}

大神们斧正,多谢


[其他解释]
引用:
首先楼主要理解:
不能删除已选入DC的GDI对象

这句话的后果是什么? 不是程序崩溃,是内存泄露。

brush就释放不了了。所以需要保存selectobject的返回值指针。然后再删除bursh,选回来保存的指针再删除brush。

恩。推荐一个内存泄露检测工具吧。我试试~

引用:
首先楼主要理解:
不能删除已选入DC的GDI对象

这句话的后果是什么? 不是程序崩溃,是内存泄露。

brush就释放不了了。所以需要保存selectobject的返回值指针。然后再删除bursh,选回来保存的指针再删除brush。

书上说只是程序健壮性的问题。。推荐一个内存泄露检测工具吧,我试试~谢谢。
详见MFC windows程序设计第二版64页。
[其他解释]
引用:
首先楼主要理解:
不能删除已选入DC的GDI对象

这句话的后果是什么? 不是程序崩溃,是内存泄露。

brush就释放不了了。所以需要保存selectobject的返回值指针。然后再删除bursh,选回来保存的指针再删除brush。

关于内存泄露的问题,CBrush的析构函数会释放brush占用的内存,我也觉得不存在内存泄露~
[其他解释]
引用:
似乎楼主的代码泄露了吧

{
CPaintDC dc(this)
CBrush brush(RGB(255,0,0))
CBrush* pOld= dc.SelectObject(&brush);
dc.Ellipse(0,0,200,200);

dc.SelectObect((HBRUSH)*pOld);


}

大神们斧正,多谢

64页selectObject之前的话你再读读~
[其他解释]
引用:
引用:
没错,析构函数会DeleteObject,但是MSDN是这样说的:
引用Return value
If the function succeeds, the return value is nonzero.
If the specified handle is not valid or is currently selected into a DC,……

谢谢14L,我的问题不太明确,帮我明确了。
[其他解释]
引用:
引用:引用:
没错,析构函数会DeleteObject,但是MSDN是这样说的:
引用Return value
If the function succeeds, the return value is nonzero.
If the specified handle is not valid……


明确啥了?

你老是说看xx页的书

我们压根就接触这本书, 大多数看windows程序设计,而不是mfc windows程序设计。


[其他解释]
结贴。分不太多。谢谢大家。
稍微总结下吧:
selectobject(旧的HGDIOBJ)这是必须的。
调用此函数不只是健壮性的问题,所以书上的表述有点偏差。
为什么要调用,大概某个环境下会内存泄露,当然是存在不泄露的情况。暂时没发现明确的答案。
[其他解释]
引用:
引用:引用:引用:
没错,析构函数会DeleteObject,但是MSDN是这样说的:
引用,不能的话私M我。
[其他解释]
引用:
引用:引用:引用:
没错,析构函数会DeleteObject,但是MSDN是这样说的:
引用Return value
If the function succeeds, the return value is nonzero.


If the specified ……


帅哥,你好敬业。。
我1L的代码是从书上copy来的,作者只是说这段代码健壮性存在问题。
因删除dc和画笔没有顺序上的关系,所以不只是健壮性问题。

那为什么要调用selectobject呢?有什么作用呢?

读书人网 >VC/MFC

热点推荐