seniors 发表于 2013-5-28 20:54:37

第十讲之分解1-渐变画刷

由于反应较多的还是不懂,所以分解,就只能慢点了
分解1-渐变画刷
说明:当画刷起点和填充的起点一至时,填充效果最容易控制,自己在界面上拉动体会一下
对于线性渐变画刷,只有翻转或者不翻转,不分水平垂直
具体看代码注释吧,如果不懂,还是希望说的细一点,到底是哪里不懂

反正讲的慢了,下一讲,就只讲渐变画刷之多色渐变了
#include <APIConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>
#include <GDIPlusEx.au3>

Global $rectx = 5, $recty = 5, $rectw = 100, $recth = 100
Global $brushx = $rectx, $brushy = $recty, $brushw = 50, $brushh = 50
GUICreate("第十讲之分解1-渐变画刷", 500, 400)
$nCtrlId = GUICtrlCreatePic("", 0, 0, 500, 200)
$hPicWnd = GUICtrlGetHandle($nCtrlId)

Global $rect, $brush
init()
GUIRegisterMsg($WM_HSCROLL, "onHSCROLL")
GUISetState()

update()

While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3
                        ExitLoop
        EndSwitch
WEnd

GUIDelete()
Exit

Func init()
        GUICtrlCreateLabel("矩形起点X", 5, 205)
        $rect = GUICtrlCreateSlider(60, 205, 100)
        GUICtrlSetLimit(-1, $rectx, 0)
        GUICtrlSetData(-1, $rectx)
        $rect = GUICtrlCreateLabel("", 170, 205, 40, 25)
        GUICtrlSetData(-1, $rectx)

        GUICtrlCreateLabel("矩形起点Y", 5, 235)
        $rect = GUICtrlCreateSlider(60, 235, 100)
        GUICtrlSetLimit(-1, $recty, 0)
        GUICtrlSetData(-1, $recty)
        $rect = GUICtrlCreateLabel("", 170, 235, 40, 25)
        GUICtrlSetData(-1, $recty)

        GUICtrlCreateLabel("矩形宽度W", 5, 265)
        $rect = GUICtrlCreateSlider(60, 265, 100)
        GUICtrlSetLimit(-1, $rectw, 40)
        GUICtrlSetData(-1, $rectw)
        $rect = GUICtrlCreateLabel("", 170, 265, 40, 25)
        GUICtrlSetData(-1, $rectw)

        GUICtrlCreateLabel("矩形高度H", 5, 295)
        $rect = GUICtrlCreateSlider(60, 295, 100)
        GUICtrlSetLimit(-1, $recth, 40)
        GUICtrlSetData(-1, $recth)
        $rect = GUICtrlCreateLabel("", 170, 295, 40, 25)
        GUICtrlSetData(-1, $recth)

        GUICtrlCreateLabel("画刷起点X", 255, 205)
        $brush = GUICtrlCreateSlider(310, 205, 100)
        GUICtrlSetLimit(-1, $brushx, 0)
        GUICtrlSetData(-1, $brushx)
        $brush = GUICtrlCreateLabel("", 420, 205, 40, 25)
        GUICtrlSetData(-1, $brushx)

        GUICtrlCreateLabel("画刷起点Y", 255, 235)
        $brush = GUICtrlCreateSlider(310, 235, 100)
        GUICtrlSetLimit(-1, $brushy, 0)
        GUICtrlSetData(-1, $brushy)
        $brush = GUICtrlCreateLabel("", 420, 235, 40, 25)
        GUICtrlSetData(-1, $brushy)

        GUICtrlCreateLabel("画刷宽度W", 255, 265)
        $brush = GUICtrlCreateSlider(310, 265, 100)
        GUICtrlSetLimit(-1, 110, 0)
        GUICtrlSetData(-1, $brushw)
        $brush = GUICtrlCreateLabel("", 420, 265, 40, 25)
        GUICtrlSetData(-1, $brushw)

        GUICtrlCreateLabel("画刷高度H", 255, 295)
        $brush = GUICtrlCreateSlider(310, 295, 100)
        GUICtrlSetLimit(-1, 110, 0)
        GUICtrlSetData(-1, $brushh)
        $brush = GUICtrlCreateLabel("", 420, 295, 40, 25)
        GUICtrlSetData(-1, $brushh)
EndFunc   ;==>init

Func onHSCROLL($hWnd, $iMsg, $wParam, $lParam)
        Switch $lParam
                Case GUICtrlGetHandle($rect)
                        $rectx = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $rectx)
                Case GUICtrlGetHandle($rect)
                        $recty = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $recty)
                Case GUICtrlGetHandle($rect)
                        $rectw = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $rectw)
                Case GUICtrlGetHandle($rect)
                        $recth = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $recth)
                Case GUICtrlGetHandle($brush)
                        $brushx = GUICtrlRead($brush)
                        GUICtrlSetData($brush, $brushx)
                Case GUICtrlGetHandle($brush)
                        $brushy = GUICtrlRead($brush)
                        GUICtrlSetData($brush, $brushy)
                Case GUICtrlGetHandle($brush)
                        $brushw = GUICtrlRead($brush)
                        GUICtrlSetData($brush, $brushw)
                Case GUICtrlGetHandle($brush)
                        $brushh = GUICtrlRead($brush)
                        GUICtrlSetData($brush, $brushh)
        EndSwitch
        update()
EndFunc   ;==>onHSCROLL

Func update()
        Local $HWND_CX = _WinAPI_GetWindowWidth($hPicWnd)
        Local $HWND_CY = _WinAPI_GetWindowHeight($hPicWnd)
        _GDIPlus_Startup()
        $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hPicWnd)
        $hBitmap = _GDIPlus_BitmapCreateFromGraphics($HWND_CX, $HWND_CY, $hGraphics)
        $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFECE9D8)
        _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2);光滑模式,2为8*8抗距齿
        lineBrushComp($hBackbuffer)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $HWND_CX, $HWND_CY)
        _GDIPlus_BitmapDispose($hBitmap)
        _GDIPlus_GraphicsDispose($hBackbuffer)
        _GDIPlus_GraphicsDispose($hGraphics)
        _GDIPlus_Shutdown()
EndFunc   ;==>update

Func lineBrushComp($hGraphics)
        Local $hPen = _GDIPlus_PenCreate(0xFFFFFFFF, 2)
        Local $hPath = _GDIPlus_PathCreate()
        ;$rectx, $recty, $rectw, $recth分别是矩形路径的起点XY坐标,及宽高
        _GDIPlus_PathAddRectangle($hPath, $rectx, $recty, $rectw, $recth)
        Local $hBrush
        ;下面是4种填充方式的对比,0是不翻转,1是水平翻转,2 是垂直翻转,3是水平垂直均翻转,其中4是不铺设,所以不演示了
        ;水平翻转就是到超过画刷高到第二行时,水平翻转
        ;垂直翻转就是到超过画刷宽到第二列时,垂直翻转
        ;对于线性渐变画刷,只有翻转或者不翻转,所以0,2是翻转,1,3是翻转
        ;$brushx, $brushy, $brushw, $brushh分别是我设置的画刷的起点XY及宽高
        ;_GDIPlus_LineBrushCreate函数的参数是起点XY及终点XY,所以终点的XY用了起点+宽高
        Local $endx = $brushw + $brushx, $endy = $brushh + $brushy
        ;============================================================
        ;说明:当画刷起点和填充的起点一至时,填充效果最容易控制,自己在界面上拉动体会一下
        ;============================================================
       
        For $i = 0 To 3
                $hBrush = _GDIPlus_LineBrushCreate($brushx, $brushy, $endx, $endy, 0xFFFFFFFF, 0xFFFF0000, $i)
                _GraphicsFillPath($hGraphics, $hPath, $hBrush)
                _GraphicsDrawPath($hGraphics, $hPath, $hPen)
                _GDIPlus_BrushDispose($hBrush)
                _GraphicsDrawString($hGraphics, "渐变" & $i, $rectx, $recty + $recth + 10)
                _GDIPlus_GraphicsTranslateTransform($hGraphics, $rectx + $rectw + 10, 0)
        Next
        _GDIPlus_PathDispose($hPath)
        _GDIPlus_PenDispose($hPen)
       
        ;复位画布
        _GDIPlus_GraphicsResetTransform($hGraphics)
        _GDIPlus_GraphicsTranslateTransform($hGraphics, 0, $recty + $recth + 40)
        ;================================绘制原画刷样子
        $hPath = _GDIPlus_PathCreate()
        ;防止画刷宽高为0时,看不到刷子,当为0时,设置为1粗细
        Local $brushrectw = $brushw, $brushrecth = $brushh
        If $brushw = 0 Then $brushrectw += 1
        If $brushh = 0 Then $brushrecth += 1
        _GDIPlus_PathAddRectangle($hPath, $brushx, $brushy, $brushrectw, $brushrecth)
        $hBrush = _GDIPlus_LineBrushCreate($brushx, $brushy, $endx, $endy, 0xFFFFFFFF, 0xFFFF0000)
        _GraphicsFillPath($hGraphics, $hPath, $hBrush)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_PathDispose($hPath)
EndFunc   ;==>String1

;_GDIPlus_GraphicsDrawString这个函数,我认为他没有设置$hBrush,所以我改成这样就可以用不同的画刷了
Func _GraphicsDrawString($hGraphics, $sString, $nX, $nY, $hBrush = 0, $sFont = "Arial", $nSize = 10, $iFormat = 0)
        Local $hFormat = _GDIPlus_StringFormatCreate($iFormat)
        Local $hFamily = _GDIPlus_FontFamilyCreate($sFont)
        Local $hFont = _GDIPlus_FontCreate($hFamily, $nSize)
        Local $tLayout = _GDIPlus_RectFCreate($nX, $nY, 0, 0)
        Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hFormat)
        __GDIPlus_BrushDefCreate($hBrush)
        Local $aResult = _GDIPlus_GraphicsDrawStringEx($hGraphics, $sString, $hFont, $aInfo, $hFormat, $hBrush)
        Local $iError = @error
        __GDIPlus_BrushDefDispose()
        _GDIPlus_FontDispose($hFont)
        _GDIPlus_FontFamilyDispose($hFamily)
        _GDIPlus_StringFormatDispose($hFormat)
        Return SetError($iError, 0, $aResult)
EndFunc   ;==>_GraphicsDrawString

;下面这两个描路径和填充路径,在3.3.9.5中已经更正了,我用的是3.3.7.15画笔和画刷设置不对,可以改成这样的就行了
Func _GraphicsDrawPath($hGraphics, $hPath, $hPen = 0)
        Local $iTmpErr, $iTmpExt, $aResult

        __GDIPlus_PenDefCreate($hPen)

        $aResult = DllCall($ghGDIPDll, "uint", "GdipDrawPath", "hwnd", $hGraphics, "hwnd", $hPen, "hwnd", $hPath)
        $iTmpErr = @error
        $iTmpExt = @extended

        __GDIPlus_PenDefDispose()

        If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False)
        $GDIP_STATUS = $aResult
        Return $aResult = 0
EndFunc   ;==>_GraphicsDrawPath

Func _GraphicsFillPath($hGraphics, $hPath, $hBrush = 0)
        Local $iTmpErr, $iTmpExt, $aResult

        __GDIPlus_BrushDefCreate($hBrush)

        $aResult = DllCall($ghGDIPDll, "uint", "GdipFillPath", "hwnd", $hGraphics, "hwnd", $hBrush, "hwnd", $hPath)
        $iTmpErr = @error
        $iTmpExt = @extended

        __GDIPlus_BrushDefDispose()

        If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False)
        $GDIP_STATUS = $aResult
        Return $aResult = 0
EndFunc   ;==>_GraphicsFillPath

楼上风云 发表于 2013-5-28 21:15:37

回复 1# seniors
沙发!
先收藏,慢研读。

zym3138 发表于 2013-5-29 11:51:09

慢慢研究,学习学习再学习

sniperone 发表于 2013-5-29 16:02:40

seniors 大大讲的好,搬个板凳坐着慢慢看~
页: [1]
查看完整版本: 第十讲之分解1-渐变画刷