主题:[讨论]如何判断pictureBox上没有图像。
天天学习
[专家分:4570] 发布于 2009-11-02 11:47:00
RT。对于加载的图片还可以根据Picture.Handle是否为零来判断。但是对于在PictureBox上画图的方式绘制的图形(Line,Circle),该怎么判断呢?
回复列表 (共5个回复)
沙发
bcahzvip [专家分:6040] 发布于 2009-11-02 14:55:00
EnumObjects
板凳
天天学习 [专家分:4570] 发布于 2009-11-02 16:37:00
[quote]enumObjects[/quote]
不知道这个函数怎么用。
[quote]
Declare Function EnumObjects Lib "gdi32" (ByVal hDC As Long, ByVal n As Long, ByVal lpGOBJEnumProc As Long, lpVoid As Any) As Long
【操作系统】
Win9X:Yes
WinNT:Yes
【说明】
枚举可随同指定设备场景使用的画笔和刷子
【返回值】
Long,如函数要枚举的对象太多,就返回-1。否则由用户自己定义
【其它】
【参数表】
hDC ------------ Long,设备场景的句柄
n -------------- Long,欲枚举的对象的类型。请查找带OBJ_前缀的常数,这样可得到一个对象列表。win32手册建议只使用OBJ_PEN和OBJ_BRUSH两个常数
lpGOBJEnumProc - Long,指向为每个GDI对象调用的指针
lpVoid --------- 枚举过程中传递给回调函数的值
[/quote]
[code=c]
'在窗体里
Option Explicit
Private Declare Function EnumObjects Lib "gdi32" (ByVal hDC As Long, ByVal n As Long, ByVal lpGOBJEnumProc As Long, lpVoid As Any) As Long
Private Const OBJ_BRUSH = 2
Private Const OBJ_PEN = 1
Private Sub Command1_Click()
Debug.Print EnumObjects(Picture1.hDC, OBJ_PEN, AddressOf EnumObjectProc, ByVal 0)
End Sub
'在模块里
Option Explicit
Public Function EnumObjectProc(ByVal lpObj As Long, ByVal lpData As Long) As Long
Debug.Print lpObj, lpData
EnumObjectProc = -1
End Function
[/code]
然后,运行时点command1,打印出好几个数字,不知道代表什么意思。我的理解是是,lpObj的数字代表picture1中拥有的Pen的handler。但这和“如何判断pictureBox中是否绘制有图形”的问题有什么关系呢?
ps:lpObj的数字用GetObjectType()总是返回0,出错。不知道lpObj代表什么了。
3 楼
tanchuhan [专家分:15140] 发布于 2009-11-02 17:44:00
Picture1.Picture是背景图,没加载背景图的话Picture1.Picture.Handle = 0
其实Windows没有背景图这个概念,一个窗口内部就一幅位图,所有的绘图操作都应用到了这幅位图的数据上面,你作画时就是修改BITMAP里的数据,然后由系统读取,再转换(裁掉被遮住部分等等...),发到显卡驱动显示.
vb有这个概念是因为vb在画其他东西前先帮你把背景图画上
你说的没法判断,即使你根本没有执行任何绘图操作,BITMAP里面的数据也存在(全部初始化为0,黑色).
so, Picture1.Image.Handle恒非0
这些是我的理解,说的不是很全面。你大概看下就行了。
可以google下WM_PAINT了解下windows绘图的真正流程
CreateDIBSection,这个函数更有趣,你直接修改它返回的DIB Bits(二维数组),在显示时可以看到你的修改(即使你没有调用任何其它绘图函数)。而调用LineTo之类的绘图函数后,你再读取这个DIB Bits,你会发现里面的数据有了对应的改动(怎么改动需要你自己去了解下DIB的存储格式)
4 楼
bcahzvip [专家分:6040] 发布于 2009-11-02 22:36:00
[code=c]
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type LOGPEN
lopnStyle As Long
lopnWidth As POINTAPI
lopnColor As Long
End Type
Private Type LOGBRUSH
lbStyle As Long
lbColor As Long
lbHatch As Long
End Type
Private Type COLORBYTES
BlueByte As Byte
GreenByte As Byte
RedByte As Byte
AlphaByte As Byte
End Type
Public Function EnumObjectProcPen(ByVal lpObj As Long, ByVal lpData As Long) As Long
Dim p As LOGPEN
Dim c As COLORBYTES
CopyMemory p, ByVal lpObj, Len(p)
CopyMemory c, p.lopnColor, 4
Debug.Print c.AlphaByte; c.BlueByte; c.GreenByte; c.RedByte, p.lopnStyle, p.lopnWidth.x, p.lopnWidth.y, lpData
EnumObjectProcPen = -1
End Function
Public Function EnumObjectProcBrush(ByVal lpObj As Long, ByVal lpData As Long) As Long
Dim p As LOGBRUSH
Dim c As COLORBYTES
CopyMemory p, ByVal lpObj, Len(p)
CopyMemory c, p.lbColor, 4
Debug.Print c.AlphaByte; c.BlueByte; c.GreenByte; c.RedByte, p.lbStyle, p.lbHatch
EnumObjectProcBrush = -1
End Function
[/code]
5 楼
天天学习 [专家分:4570] 发布于 2009-11-03 08:58:00
按tanchuhan的说法,只有判断BITMAP里的数据是不是全部为0的方法来判断是否有图形了?(DIB Bits(二维数组)矩阵中是否有数值)。比Point或GetPixel方法快。
我来回复