首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

请问画笔CreatePen使用后,DeleteObject的正确用法

2012-01-23 
请教画笔CreatePen使用后,DeleteObject的正确用法?我自己写的是这样:(API声明就省略了……)DimWinDCAsLong,C

请教画笔CreatePen使用后,DeleteObject的正确用法?
我自己写的是这样:(API声明就省略了……)

Dim   WinDC   As   Long,   CPen   As   Long,   XY   As   POINTAPI
WinDC   =   GetWindowDC(0)
CPen   =   CreatePen(PS_SOLID,   4,   vbRed)
SetROP2   WinDC,   10   '设置为非异或笔
SelectObject   WinDC,   CPen           ' ' ' ' ' ' ' ' ' ' ' ' '将和下面的代码对比
MoveToEx   WinDC,   200,   200,   XY
Rectangle   WinDC,   200,   200,   400,   400     '画矩形
DeleteObject   CPen     '删除画笔
ReleaseDC   0,   WinDC

后来在API浏览器FoxAPI中的例子中看到不是这样写的,比我多了一点··
按照代码例子,我的代码应该写成:

' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
SetROP2   WinDC,   10   '设置为非异或笔
DeleteObject   SelectObject(WinDC,   CPen)       '和上面代码对比
MoveToEx   WinDC,   200,   200,   XY
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
为什么可以在为DC选入画笔后,直接就删除了??
经过测试,这样的代码也能正常使用来画···(我原来的代码也是能画的)

后来看到网上有些代码是这样:
Dim   WinDC   As   Long,   CPen   As   Long,   XY   As   POINTAPI
WinDC   =   GetWindowDC(0)
CPen   =   CreatePen(PS_SOLID,   4,   vbRed)
SetROP2   WinDC,   10   '设置为非异或笔
Old   =   SelectObject(WinDC,   CPen)       ' ' ' ' ' ' ' ' '和上面的代码对比
MoveToEx   WinDC,   200,   200,   XY
Rectangle   WinDC,   200,   200,   400,   400     '画矩形
DeleteObject   Old     ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '为什么要Delete那个SelectObject的返回值啊??不是删除CPen就可以了吗?
DeleteObject   CPen     '删除画笔
ReleaseDC   0,   WinDC

经过测试:DeleteObject   Old   的返回值是1,表示删除成功的
我还是不大明白为什么要删除SelectObject的返回值


请教大虾,确定一下完全正确的使用方法!!!!

[解决办法]
上面的说法千奇百怪,网上流传的版本很多,我个人看法,都有点问题。它们之所以能流传,就是因为从效果上看不出差别。而很多人写VB程序,恰恰是只看重效果!

这个问题我没见过MSDN中有具体说明,但从其中部分函数说明与很多MFC示例中,基本可得出以下零星线索:
1、不能直接删除已选入DC中的对象,如Bmp、Brush、Pen等;
2、删除DC并不会同时删除已选入其中的对象;
3、SelectObject在选入新对象的同时会返回旧的同类对象,若程序不再需要它,应该主动删除

所以,会出现很多不同做法,常见做法,我常用的是替换法:
就是在调用SelectObject选入自己的对象时,用一个变量保存返回的旧对象;在使用完后,再一次用SelectObject选回旧对象,这样就从DC中替换出了自己的对象,这时才能用DeleteObject删除它。
具体示例:
Old = SelectObject(WinDC, CPen)
....
SelectObject WinDC, Old
DeleteObject CPen
之后若DC也不需要了,还应DeleteDC或ReleaseDC

MSDN中有的示例与上述不同
它没有选回旧对象,而是直接先DeleteDC,后DeleteObject

说实话,这些处理都是最后释放资源的问题,对GDI绘图操作并没有影响,所以从效果上看不出区别,只是若删除不正确,在XP的任务管理器中,你会看到这个程序在多次调用错误操作后,GDI句柄数一直不断增加,不见减少。

我习惯于采用替换法删除对象,实践证明这样做最为可靠,因为我在尝试MSDN示例的办法后发现,删除不能成功,GDI句柄数没有减少。

热点排行