Jump to content

Recommended Posts

Posted (edited)

I searched some time ago function that draws a radial gradients, but disenchanted. I had to write myself. What came of it you can see below... _WinAPI_RadialGradientFill() function will be included in the next version (2.3) of WinAPIEx.au3 library.

Posted Image Posted Image

#Include <GUIConstantsEx.au3>
#Include <WinAPIEx.au3>

Opt('MustDeclareVars', 1)

Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173

Global $hForm, $Msg, $Pic, $hPic, $hObj, $hBitmap, $hDC, $hDestDC, $hDestSv

; Create GUI
$hForm = GUICreate('MyGUI', 400, 400)
$Pic = GUICtrlCreatePic('', 0, 0, 400, 400)
$hPic = GUICtrlGetHandle($Pic)

; Create gradient
$hDC = _WinAPI_GetDC($hPic)
$hDestDC = _WinAPI_CreateCompatibleDC($hDC)
$hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, 400, 400)
$hDestSv = _WinAPI_SelectObject($hDestDC, $hBitmap)
For $i = 0 To 315 Step 45
    _WinAPI_RadialGradientFill($hDestDC, 200, 200, 200, Random(0, 0xFFFFFF, 1), 0, $i, $i + 45)
Next
_WinAPI_ReleaseDC($hPic, $hDC)
_WinAPI_SelectObject($hDestDC, $hDestSv)
_WinAPI_DeleteDC($hDestDC)

; Set gradient to control
_SendMessage($hPic, $STM_SETIMAGE, 0, $hBitmap)
$hObj = _SendMessage($hPic, $STM_GETIMAGE)
If $hObj <> $hBitmap Then
    _WinAPI_FreeObject($hBitmap)
EndIf

GUISetState()

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $GUI_EVENT_PRIMARYDOWN

    EndSwitch
WEnd

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_RadialGradientFill
; Description....: Fills radial gradient.
; Syntax.........: _WinAPI_RadialGradientFill($hDC, $iX, $iY, $iRadius, $iRGB1, $iRGB2 [, $iAngleStart [, $iAngleEnd [, $iStep]]] )
; Parameters.....: $hDC         - Handle to the destination device context.
;                  $iX          - The x-coordinate of the central point, in logical units.
;                  $iY          - The y-coordinate of the central point, in logical units.
;                  $iRadius     - The circle radius to filling the gradient.
;                  $iRGB1       - The color information at the central point.
;                  $iRGB2       - The color information at the edges of circle.
;                  $iAngleStart - The angle to start filling at, in degree.
;                  $iAngleEnd   - The angle to end filling at, in degree.
;                  $iStep       - The gradient filling step in degree. The larger value of this parameter, the gradient will be
;                                 better, but it's require more time, and vice versa.
; Return values..: Success  - 1.
;                  Failure  - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......:
; Remarks........: This function does not fills gradient with transparency, and does not use antialiasing.
; Related........:
; Link...........: None
; Example........: Yes
; ===============================================================================================================================

Func _WinAPI_RadialGradientFill($hDC, $iX, $iY, $iRadius, $iRGB1, $iRGB2, $iAngleStart = 0, $iAngleEnd = 360, $iStep = 5)

    Local $Val

    If Abs($iAngleStart) > 360 Then
        $iAngleStart = Mod($iAngleStart, 360)
    EndIf
    If Abs($iAngleEnd) > 360 Then
        $iAngleEnd = Mod($iAngleEnd, 360)
    EndIf
    If ($iAngleStart < 0) Or ($iAngleEnd < 0) Then
        $iAngleStart += 360
        $iAngleEnd += 360
    EndIf
    If $iAngleStart > $iAngleEnd Then
        $Val = $iAngleStart
        $iAngleStart = $iAngleEnd
        $iAngleEnd = $Val
    EndIf

    Local $K = 4 * ATan(1) / 180
    Local $Xp = Round($iX + $iRadius * Cos($K * $iAngleStart))
    Local $Yp = Round($iY - $iRadius * Sin($K * $iAngleStart))
    Local $Xn, $Yn, $An = $iAngleStart
    Local $Vertex[3][3]

    While $An < $iAngleEnd
        $An += $iStep
        If $An > $iAngleEnd Then
            $An = $iAngleEnd
        EndIf
        $Xn = Round($iX + $iRadius * Cos($K * $An))
        $Yn = Round($iY - $iRadius * Sin($K * $An))
        $Vertex[0][0] = $iX
        $Vertex[0][1] = $iY
        $Vertex[0][2] = $iRGB1
        $Vertex[1][0] = $Xp
        $Vertex[1][1] = $Yp
        $Vertex[1][2] = $iRGB2
        $Vertex[2][0] = $Xn
        $Vertex[2][1] = $Yn
        $Vertex[2][2] = $iRGB2
        If Not _WinAPI_GradientFill($hDC, $Vertex, 0, 2) Then
            Return SetError(1, 0, 0)
        EndIf
        $Xp = $Xn
        $Yp = $Yn
    WEnd
    Return 1
EndFunc   ;==>_WinAPI_RadialGradientFill
Edited by Yashied
Posted

That looks pretty cool Yashied. Nice addition to your WinAPIEx. Thanks for sharing. :(

Posted

This is the same, but only by using GDI+ (requires excellent Authenticity's GDIP UDF). Here is gradients can be transparent.

#Include <GDIP.au3>
#Include <WinAPI.au3>


_GDIPlus_Startup()

GUICreate('MyGUI', 800, 600)
$Pic = GUICtrlCreatePic('', 0, 0, 800, 600)
$hPic = GUICtrlGetHandle(-1)

$hBitmap = _WinAPI_CreateBitmap(800, 600, 1, 32)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
$hGraphics = _GDIPlus_ImageGetGraphicsContext($hImage)
$hBitmap = _GDIPlus_ImageLoadFromFile(@WindowsDir & '\Web\Wallpaper\Ascent.jpg')
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, 800, 600)
_GDIPlus_ImageDispose($hBitmap)
_GDIPlus_GraphicsDrawRadialGradient($hGraphics, 800, 0, 600, 0xFFFF0000, 0, 45, 180)
_GDIPlus_GraphicsDrawRadialGradient($hGraphics, 310, 130, 100, 0xFF00FFFF, 0)
_GDIPlus_GraphicsDrawRadialGradient($hGraphics, 414, 314, 100, 0xFFFFFF00, 0)
_GDIPlus_GraphicsDrawRadialGradient($hGraphics, 550, 470, 100, 0xFF00FF00, 0)
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_ImageDispose($hImage)

$hObj = _SendMessage($hPic, 0x0172, 0, $hBitmap)
If $hObj Then
    _WinAPI_DeleteObject($hObj)
EndIf

GUISetState()

Do
Until GUIGetMsg() = -3

_GDIPlus_Shutdown()

Func _GDIPlus_GraphicsDrawRadialGradient($hGraphics, $iX, $iY, $iRadius, $iARGB1, $iARGB2, $iStartAngle = 0, $iEndAngle = 360, $iStep = 5)

    If $iStep < 1 Then
        $iStep = 1
    EndIf

    Local $Xi = $iX - $iRadius, $Yi = $iY - $iRadius, $Di = 2 * $iRadius
    Local $hBrush, $hMatrix, $Smooth = _GDIPlus_GraphicsGetSmoothingMode($hGraphics)
    Local $Start = True

    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 0)
    $hBrush = _GDIPlus_LineBrushCreate(0, 0, $iRadius, 0, $iARGB1, $iARGB2, 3)
    $hMatrix = _GDIPlus_MatrixCreate()
    _GDIPlus_MatrixTranslate($hMatrix, $iX, $iY)
    While $iStartAngle < $iEndAngle
        If $iStartAngle + $iStep > $iEndAngle Then
            $iStep = $iEndAngle - $iStartAngle
        EndIf
        If $Start Then
            _GDIPlus_MatrixRotate($hMatrix, $iStartAngle + $iStep / 2)
            $Start = False
        Else
            _GDIPlus_MatrixRotate($hMatrix, $iStep)
        EndIf
        _GDIPlus_LineBrushSetTransform($hBrush, $hMatrix)
        _GDIPlus_GraphicsFillPie($hGraphics, $Xi, $Yi, $Di, $Di, $iStartAngle, $iStep, $hBrush)
        $iStartAngle += $iStep
    WEnd
    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $Smooth)
    _GDIPlus_MatrixDispose($hMatrix)
    _GDIPlus_BrushDispose($hBrush)
    Return 1
EndFunc   ;==>_GDIPlus_GraphicsDrawRadialGradient

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...