注册 登录
编程论坛 VB6论坛

请教如何填充颜色?

txxb 发布于 2015-01-25 16:02, 3333 次点击
用line围成的三角形,怎么填充颜色??
21 回复
#2
lianyicq2015-01-26 09:35
可以采用API函数
Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long
第一个参数是绘图场景句柄;
第二\三个参数是开始填充的一点坐标;
第四个参数是边界颜色.如果用黑色画的线就用黑色为边界颜色
第五个参数是填充类型.
详尽说明搜百度
#3
txxb2015-01-26 20:49
找不到方法啊,
#4
xzlxzlxzl2015-01-26 22:03
如果不嫌速度慢的话,也可以自己写代码完成,下面代码提供一个着色小面积图案的方法:新建一工程,复制下述代码,运行后在窗口上点击鼠标左键可看到着色效果,点击圆外面会着色不完整。

程序代码:
Private Sub FillPic(obj As Object, X As Single, Y As Single, c As Long, Fc As Long)
  '填充图形,这是一个函数嵌套调用,可填充小面积图形,大面积要多用一个数组再嵌套
  On Error Resume Next
  Dim i As Integer, x1 As Single, y1 As Single, d(3, 1) As Integer
  For i = 0 To 3: d(i, 0) = 0: d(i, 1) = 0: Next
  d(0, 0) = -1: d(1, 0) = 1: d(2, 1) = -1: d(3, 1) = 1  '设置步进方向
  If obj.Point(X, Y) = c Then
    obj.PSet (X, Y), Fc
    For i = 0 To 3
      x1 = X + d(i, 0)
      y1 = Y + d(i, 1)
      FillPic obj, x1, y1, c, Fc
    Next
  End If
End Sub

Private Sub Form_Load()
  Me.ScaleMode = 3
  Me.AutoRedraw = True
  Me.Circle (35, 35), 30, vbBlack
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Dim c As Long
  If Button = 1 Then
    c = Me.Point(X, Y)
    FillPic Me, X, Y, c, vbBlue
  End If
End Sub
#5
txxb2015-01-27 14:35
我想学API的方法。
Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long
怎么用??
#6
lianyicq2015-01-27 15:05
试试
程序代码:
Option Explicit
Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long

Private Sub Form_Load()
Form1.ScaleMode = 3
Picture1.ScaleMode = 3
Picture1.AutoRedraw = True
Picture1.ForeColor = vbRed
Picture1.FillColor = vbBlue
Picture1.FillStyle = 0

Picture1.Line (Picture1.Width / 2, 0)-(0, Picture1.Height)
Picture1.Line -(Picture1.Width, Picture1.Height)
Picture1.Line -(Picture1.Width / 2, 0)


Call ExtFloodFill(Picture1.hdc, Picture1.Width / 2, Picture1.Height / 2, vbRed, 0)
End Sub

#7
txxb2015-01-27 15:51
Form1.Line (Form1.Width / 2, 0)-(0, Form1.Height)
Form1.Line -(Form1.Width, Form1.Height)
Form1.Line -(Form1.Width / 2, 0)
这个怎么弄??
#8
lianyicq2015-01-27 16:00
这是逐点画直线。如果要封闭,最后一点和第一点要相连,即
form1.line -(form1.width/2,0)中的(form1.width/2,0)这点也出现在第一行代码中。
实际测试,最直接。
#9
xzlxzlxzl2015-01-27 17:28
拓展lianyicq版主的功能,填充选中的颜色
程序代码:
Option Explicit
Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long

Private Sub Form_Load()
  Form1.ScaleMode = 3
  Picture1.ScaleMode = 3
  Picture1.AutoRedraw = True
  Picture1.Circle (Picture1.Width * 0.5, Picture1.Height * 0.5), Picture1.Height * 0.4, vbRed
End Sub
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Dim c As Long, r As Long, g As Long, b As Long, s As Integer
  Randomize
  r = Rnd * 255: g = Rnd * 255: b = Rnd * 255
  If Button = 1 Then
    c = Picture1.Point(X, Y)  '获取要取代的颜色
    Picture1.FillColor = RGB(r, g, b)
    s = Picture1.FillStyle
    Picture1.FillStyle = 0  '填充模式
    ExtFloodFill Picture1.hdc, X, Y, c, 1  '从鼠标选中的点开始填充随机色(用模式1,模式0是判断边界颜色)
    Picture1.FillStyle = s  '还原填充模式
  End If
End Sub
#10
txxb2015-01-27 20:15
以下是引用lianyicq在2015-1-27 16:00:31的发言:

这是逐点画直线。如果要封闭,最后一点和第一点要相连,即
form1.line -(form1.width/2,0)中的(form1.width/2,0)这点也出现在第一行代码中。
实际测试,最直接。

太好了,又学会了多边形画法。

我是说下面这个多边形如何填色?窗体上的三角形
Form1.Line (Form1.Width / 2, 0)-(0, Form1.Height)
Form1.Line -(Form1.Width, Form1.Height)
Form1.Line -(Form1.Width / 2, 0)
我不会嘛,多点例子才能学会。

[ 本帖最后由 txxb 于 2015-1-27 20:29 编辑 ]
#11
txxb2015-01-27 20:18
以下是引用xzlxzlxzl在2015-1-27 17:28:09的发言:

拓展lianyicq版主的功能,填充选中的颜色
Option Explicit
Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long

Private Sub Form_Load()
  Form1.ScaleMode = 3
  Picture1.ScaleMode = 3
  Picture1.AutoRedraw = True
  Picture1.Circle (Picture1.Width * 0.5, Picture1.Height * 0.5), Picture1.Height * 0.4, vbRed
End Sub
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Dim c As Long, r As Long, g As Long, b As Long, s As Integer
  Randomize
  r = Rnd * 255: g = Rnd * 255: b = Rnd * 255
  If Button = 1 Then
    c = Picture1.Point(X, Y)  '获取要取代的颜色
    Picture1.FillColor = RGB(r, g, b)
    s = Picture1.FillStyle
    Picture1.FillStyle = 0  '填充模式
    ExtFloodFill Picture1.hdc, X, Y, c, 1  '从鼠标选中的点开始填充随机色(用模式1,模式0是判断边界颜色)
    Picture1.FillStyle = s  '还原填充模式
  End If
End Sub

太感谢了,等我一句一句的读懂理解了,我就慢慢的会使用API了。

ExtFloodFill Picture1.hdc, X, Y, c, 1
这个圆在窗体上,怎么填色

[ 本帖最后由 txxb 于 2015-1-27 20:31 编辑 ]
#12
xzlxzlxzl2015-01-27 22:08
ExtFloodFill me.hdc, X, Y, c, 1或 ExtFloodFill form1.hdc, X, Y, c, 1
这个问题我都不好意思回答,只是惊奇于你好意思问。因为纯小白当前是到不了需要问图形处理的问题的,如果真的需要了,大致就像史前人穿越过来要开汽车一样。
#13
txxb2015-01-28 19:09
以下是引用xzlxzlxzl在2015-1-27 22:08:19的发言:

ExtFloodFill me.hdc, X, Y, c, 1或 ExtFloodFill form1.hdc, X, Y, c, 1
这个问题我都不好意思回答,只是惊奇于你好意思问。因为纯小白当前是到不了需要问图形处理的问题的,如果真的需要了,大致就像史前人穿越过来要开汽车一样。

我不懂就问,管他好意思不好意思,学到东西是真的。
Option Explicit
Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long

Private Sub Form_Load()
Form1.ScaleMode = 3
Picture1.ScaleMode = 3
Picture1.AutoRedraw = True
Picture1.ForeColor = vbRed
Picture1.FillColor = vbBlue
Picture1.FillStyle = 0

Picture1.Line (Picture1.Width / 2, 0)-(0, Picture1.Height)
Picture1.Line -(Picture1.Width, Picture1.Height)
Picture1.Line -(Picture1.Width / 2, 0)


Call ExtFloodFill(Picture1.hdc, Picture1.Width / 2, Picture1.Height / 2, vbRed, 0)
End Sub
我问的原因是吧上面所有的Picture1换成Form1,就没有填色效果了,结果没有问到关键处
#14
txxb2015-01-28 19:24
Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long

Private Sub Form_Load()
Form1.Line (Form1.ScaleWidth / 2, 0)-(0, Form1.ScaleHeight)
Form1.Line -(Form1.ScaleWidth, Form1.ScaleHeight)
Form1.Line -(Form1.ScaleWidth / 2, 0)
End Sub

Private Sub Form_Click()
Call ExtFloodFill(Form1.hdc, Form1.ScaleWidth / 2, Form1.ScaleHeight / 2, vbRed, 0)
End Sub

单击没反应,帮看看缺少什么?
#15
lianyicq2015-01-29 10:05
回复 14楼 txxb
有意思,不管用什么方法,学到东西才是真的.
原因自己想想,我只提示一点那个API函数需要在你希望填充的图形内任意定一点,注意是以像素为单位。如果点不在图形内,当然不填充.
#16
txxb2015-01-29 12:53
以下是引用lianyicq在2015-1-29 10:05:27的发言:

有意思,不管用什么方法,学到东西才是真的.
原因自己想想,我只提示一点那个API函数需要在你希望填充的图形内任意定一点,注意是以像素为单位。如果点不在图形内,当然不填充.

你给我的方法,下面这样就不行了,为什么?其他啥都没改
Private Sub Form_Click()
Call ExtFloodFill(Picture1.hdc, Picture1.Width / 2, Picture1.Height / 2, vbRed, 0)
End Sub

[ 本帖最后由 txxb 于 2015-1-29 13:01 编辑 ]
#17
txxb2015-01-29 13:46
程序代码:
Option Explicit
Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long, ByVal wFillType As Long) As Long

Private Sub Form_Load()
Form1.ScaleMode = 3
Picture1.ScaleMode = 3
Picture1.AutoRedraw = True
Picture1.ForeColor = vbRed
Picture1.FillColor = vbBlue
Picture1.FillStyle = 0

Picture1.Line (Picture1.Width / 2, 0)-(0, Picture1.Height)
Picture1.Line -(Picture1.Width, Picture1.Height)
Picture1.Line -(Picture1.Width / 2, 0)


Call ExtFloodFill(Picture1.hdc, Picture1.Width / 2, Picture1.Height / 2, vbRed, 0)
End Sub

还有我发现把Picture1.ForeColor = vbRed改个颜色都不行,对我这个不会的人来说,这都是很神奇的问题
#18
xzlxzlxzl2015-01-29 14:05
可能我在12楼说的有点过,sorry!
我想lianyicq版主也明白我的意思。你这样问问题是学不到什么的,不经过思考,张嘴就问,也许,你最后做成了一个小东西,但做完就做完了,你收获肯定不大。
就你这个问题,其实在lianyicq版主给出实例前我也没接触过,不过通过看lianyicq例子我能总结出填充函数需要五个关键要素:1、场景hdc,目前vb里能直接获取hdc的就form和picture两个(没详细总结,可能有误),2、设置场景的填充样式fillstyle<>1,因为1为透明,看不到填充效果,3、设置场景填充颜色fillcolor=你需要的颜色,4、设置填充开始坐标,5、填充模式,0:边界模式,必须指定边界颜色,填充到该颜色停止,lianyicq版主实例使用该模式;1:颜色替换模式,指定替换色,碰到不是该颜色时停止填充。填充模式是百度到的。
补充说明:vb form的度量单位默认为twip,即使你设定了scalemode=3,只能对窗体工作区内起作用,对窗体外框不起作用,因此窗体的width、height的单位仍然是twip,如果使用默认的scalewidth和scaleheight一般是你设置的pixel。
有了上述提示,希望你编程成功,真正进步。
#19
xzlxzlxzl2015-01-29 14:12
@lianyicq
还请lianyicq版主抽空找找使用api设置fillstyle和fillcolor的方法,因为vb里仅form和picture能直接获取hdc,其实其他控件都可以通过getdc来获取hdc的,这样就可以在任何控件上填充、作图了。
#20
txxb2015-01-29 14:43
以下是引用xzlxzlxzl在2015-1-29 14:05:52的发言:

可能我在12楼说的有点过,sorry!
我想lianyicq版主也明白我的意思。你这样问问题是学不到什么的,不经过思考,张嘴就问,也许,你最后做成了一个小东西,但做完就做完了,你收获肯定不大。
就你这个问题,其实在lianyicq版主给出实例前我也没接触过,不过通过看lianyicq例子我能总结出填充函数需要五个关键要素:1、场景hdc,目前vb里能直接获取hdc的就form和picture两个(没详细总结,可能有误),2、设置场景的填充样式fillstyle<>1,因为1为透明,看不到填充效果,3、设置场景填充颜色fillcolor=你需要的颜色,4、设置填充开始坐标,5、填充模式,0:边界模式,必须指定边界颜色,填充到该颜色停止,lianyicq版主实例使用该模式;1:颜色替换模式,指定替换色,碰到不是该颜色时停止填充。填充模式是百度到的。
补充说明:vb form的度量单位默认为twip,即使你设定了scalemode=3,只能对窗体工作区内起作用,对窗体外框不起作用,因此窗体的width、height的单位仍然是twip,如果使用默认的scalewidth和scaleheight一般是你设置的pixel。
有了上述提示,希望你编程成功,真正进步。

感谢版主的耐心回复
我不是为了完成具体的项目来问问题的。我自学VB三个月了,做了一些小玩意,总感觉无法再提高,自己给自己出一些题目,自己再完成,想通过实践提高技术。
这次本来我想做个旋转的正方体,想到了六面要上色,百度到了API,知道了ExtFloodFill,网上狂搜,很遗憾几乎没有教程(我要实例加讲解式的,手册式的教程我看不下去),才来这里问的。
可能因为我是自学的,一些基本概念还是不清楚,form.scalewidth和form.width和form.scalemode的互相关系就不是非常清楚。fillstyle<>1,因为1为透明,看不到填充效果,这个我也才知道。多边形的画法也是在这个帖子刚学会,以前只会用控件line做。可能就是在这些基础问题上你认为我不自己思考,其实不是的。
#21
lianyicq2015-01-30 08:34
回复 19楼 xzlxzlxzl
试着找了找api代替fillstyle和fillcolor的方法,不乐观。
这是专业和不专业的区别吧。专业的能让子弹也能制导,不专业的只能石头当石头用,子弹当子弹用。 :-D
#22
hpwangcheng2015-02-19 17:28
谢谢版主指教,学习了!!!
1