中心渐变的快速填充函数

XP为我们开创了程序界面革命的新时代,它的界面最核心的特点之一就是“渐变”。在追求个性化亮丽界面的今天,到处可见漂亮的VB界面源码,可惜它们都还在用图片,或描点描线来生成窗体及控件。要知道,GradientFill函数正是MS为我们准备的一个“超级宝贝”,一直却被VB用户忽视了。它的灵活使用,会为我们带无穷的变幻效果,我就用它先写个例子吧。

像Photoshop中那样的水平与垂直渐变用GradientFill写,很简单,就不多写了。中心渐变,画球或点亮效果时常用,多数人要用图片实现,其实GradientFill是可以做到的。我的这个函数是基于椭图写的,它当然包括正圆,通用性更强。

写下面这段代码,还有一个目的,就是GradientFill是接受数组的,完全可以只调用一次,就完成全部填充,有些人使用它却忽略了这一特性。

Private Type GRADIENT_RECT
    UpperLeft As Long
    LowerRight As Long
End Type
Private Enum GradientFillFlag
    GRADIENT_FILL_RECT_H = &H0&
    GRADIENT_FILL_RECT_V = &H1&
    GRADIENT_FILL_TRIANGLE = &H2&
End Enum
Private Type TRIVERTEX
    x As Long
    y As Long
    Red(1) As Byte
    Green(1) As Byte
    Blue(1) As Byte
    Alpha(1) As Byte
End Type
Private Type GRADIENT_TRIANGLE
    Vertex1 As Long
    Vertex2 As Long
    Vertex3 As Long
End Type

Private Declare Function GradientFillTriangle Lib "msimg32" Alias "GradientFill" (ByVal hdc As Long, pVertex As TRIVERTEX, ByVal dwNumVertex As Long, pMesh As GRADIENT_TRIANGLE, ByVal dwNumMesh As Long, ByVal dwMode As Long) As Long
'若XP系统下,GradientFill函数在Gdi32中就有
'Private Declare Function GradientFillTriangle Lib "gdi32" Alias "GdiGradientFill" (ByVal hdc As Long, pVertex As TRIVERTEX, ByVal dwNumVertex As Long, pMesh As GRADIENT_TRIANGLE, ByVal dwNumMesh As Long, ByVal dwMode As Long) As Long
Public Sub DrawGradientElliptic(dhDC As Long, x1 As Long, y1 As Long, X2 As Long, Y2 As Long, _
    StartColor As Long, Optional EndColor As Long = -1, Optional ByVal Alpha As Long = 192, _
    Optional Inner As Boolean, Optional TriangleCount As Long = 36, Optional CenterX As Long = -1, Optional CenterY As Long = -1)
    Dim Vertex() As TRIVERTEX
    Dim Triangle() As GRADIENT_TRIANGLE
    Dim Red(1) As Long, Green(1) As Long, Blue(1) As Long
    Dim Theta As Double, m As Long, k As Long, l As Double, p As Double, t As Double, tc As Long
    Dim i As Long, j As Long, a As Long, b As Long, cx As Long, cy As Long, cx0 As Long, cy0 As Long
    '椭圆及圆形渐变填充
    '指定一个矩形,该矩形与欲填充椭圆外切
    'X1、Y1;X2、Y2 分别为矩形的左上角与右下角坐标
    'StartColor起始填充色
    'EndColor结束填充色,它是可选的,若小于零时忽略此参数,使用Alpha基于StartColor算出EndColor,实现高亮填充效果
    'Alpha用于计算StartColor的高亮色,0-255之间,越大越亮,若设置了EndColor,则忽略此参数
    'Inner为渐变方式,为True时,StartColor到EndColor(或是alpha计算出的)颜色,按从外向内渐变,False则相反
    'TriangleCount为三角形数量,默认为36个
    'CenterX、CenterY用于指定高光点的位置,若小于0则默认为椭圆中心点
    Red(0) = StartColor And &HFF
    Green(0) = (StartColor And &HFF00&) / &H100&
    Blue(0) = (StartColor And &HFF0000) / &H10000
    If EndColor < 0 Then
        If Alpha < 0 Then Alpha = 0
        Red(1) = (Red(0) * (256 - Alpha) + 255 * Alpha) / 256
        Green(1) = (Green(0) * (256 - Alpha) + 255 * Alpha) / 256
        Blue(1) = (Blue(0) * (256 - Alpha) + 255 * Alpha) / 256
    Else
        Red(1) = EndColor And &HFF
        Green(1) = (EndColor And &HFF00&) / &H100&
        Blue(1) = (EndColor And &HFF0000) / &H10000
    End If
    tc = (TriangleCount / 4) * 4
    If tc < 8 Then tc = 8
    a = (X2 - x1) / 2
    b = (Y2 - y1) / 2
    cx = x1 + a
    cy = y1 + b
    If CenterX >= 0 Then
        cx0 = CenterX
    Else
        cx0 = cx
    End If
    If CenterY >= 0 Then
        cy0 = CenterY
    Else
        cy0 = cy
    End If
   
    '设置所有三角形共有一个位于圆心的顶点
    ReDim Vertex(tc)
    With Vertex(0)
        .x = cx0
        .y = cy0
        If Inner Then
            j = 1
        Else
            j = 0
        End If
        .Red(1) = Red(j)
        .Green(1) = Green(j)
        .Blue(1) = Blue(j)
        j = 1 - j
    End With
    '设置所有位于圆周上的三角形其它顶点,因三角形一个连一个,所以圆周上顶点数与三角形数是一样的
    m = (a ^ 2)
    l = (b / a)
    k = tc / 4
    Theta = (3.1415926 * 2 / tc)
    For i = 1 To k
        p = a * Cos((i - 1) * Theta)
        t = l * Sqr(m - p ^ 2)
        With Vertex(i)
            .x = cx + p
            .y = cy + t
            .Red(1) = Red(j)
            .Green(1) = Green(j)
            .Blue(1) = Blue(j)
        End With
        With Vertex(2 * k - i + 1)
            .x = cx - p
            .y = cy + t
            .Red(1) = Red(j)
            .Green(1) = Green(j)
            .Blue(1) = Blue(j)
        End With
        With Vertex(2 * k + i)
            .x = cx - p
            .y = cy - t
            .Red(1) = Red(j)
            .Green(1) = Green(j)
            .Blue(1) = Blue(j)
        End With
        With Vertex(tc - i + 1)
            .x = cx + p
            .y = cy - t
            .Red(1) = Red(j)
            .Green(1) = Green(j)
            .Blue(1) = Blue(j)
        End With
    Next
   
    '设置每个三角形结构,为它们指定顶点
    ReDim Triangle(tc - 1)
    For i = 0 To tc - 1
        Triangle(i).Vertex1 = 0
        j = i + 1
        Triangle(i).Vertex2 = j
        j = i + 2
        If j > tc Then j = 1
        Triangle(i).Vertex3 = j
    Next
    GradientFillTriangle dhDC, Vertex(0), tc + 1, Triangle(0), tc, GRADIENT_FILL_TRIANGLE
End Sub
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值