seniors 发表于 2013-5-31 22:19:56

第十一讲 GDI+画笔及线型

GDI+的画笔,有两种
_GDIPlus_PenCreate,纯色画笔
_GDIPlus_PenCreate2,画刷型画笔
画笔和线型的设置
1、_GDIPlus_PenSetCompoundArray设置复合画笔,也就是把画笔分成几根,可以同时画几根线
2、_GDIPlus_PenSetLineJoin设置画笔转角处的连接方式
3、_GDIPlus_PenSetStartCap、_GDIPlus_PenSetEndCap设置笔头笔尾的样式
4、_GDIPlus_PenSetAlignment设置对齐方式
5、_GDIPlus_PenSetDashStyle设置线型,预设的有5种,还可以自定义
6、画笔缩放和旋转等,缩放和旋转由于没法测试成功,只能作罢
自己看源码体会一下
不知道有没有人做作业,布置一个自定义线帽,线帽为五角星的作业

#include <APIConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>
#include <GDIPlusEx.au3>
#include <GuiSlider.au3>
Global $startX = 50, $startY = 20, $lineWidth = 100, $penWidth = 10
GUICreate("第十一讲 GDI+画笔及线型", 500, 400)
$nCtrlId = GUICtrlCreatePic("", 0, 0, 500, 200)
$hPicWnd = GUICtrlGetHandle($nCtrlId)

Global $rect, $Cap, $lineJoin, $DashCap, $line, $iStartCap, $iEndCap, $iLineJoin = 0, $iDashCap = 0
init()
GUIRegisterMsg($WM_HSCROLL, "onHSCROLL")
GUISetState()

update()

While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3
                        ExitLoop
                Case $lineJoin, $lineJoin, $lineJoin, $lineJoin
                        $iLineJoin = $Msg - $lineJoin
                        update()
                Case $DashCap, $DashCap, $DashCap
                        $iDashCap = $Msg - $DashCap
                        If $iDashCap > 0 Then $iDashCap += 1
                        update()
                Case $line, $line, $line
                        update()
        EndSwitch
WEnd

GUIDelete()
Exit

Func init()
        GUICtrlCreateLabel("直线起点X", 5, 205)
        $rect = GUICtrlCreateSlider(60, 205, 100)
        GUICtrlSetLimit(-1, 50, 0)
        GUICtrlSetData(-1, $startX)
        $rect = GUICtrlCreateLabel("", 170, 205, 40, 25)
        GUICtrlSetData(-1, $startX)

        GUICtrlCreateLabel("直线起点Y", 5, 235)
        $rect = GUICtrlCreateSlider(60, 235, 100)
        GUICtrlSetLimit(-1, 50, 0)
        GUICtrlSetData(-1, $startY)
        $rect = GUICtrlCreateLabel("", 170, 235, 40, 25)
        GUICtrlSetData(-1, $startY)

        GUICtrlCreateLabel("直线长度", 255, 205)
        $rect = GUICtrlCreateSlider(310, 205, 100)
        GUICtrlSetLimit(-1, 150, 0)
        GUICtrlSetData(-1, $lineWidth)
        _GUICtrlSlider_SetTicFreq(-1, 50)
        $rect = GUICtrlCreateLabel("", 420, 205, 40, 25)
        GUICtrlSetData(-1, $lineWidth)
        ;$hPen = _GDIPlus_PenCreate(0xFFFF0000, $penWidth)设置画笔宽度
        GUICtrlCreateLabel("画笔宽", 255, 235)
        $rect = GUICtrlCreateSlider(310, 235, 100)
        GUICtrlSetLimit(-1, 30, 0)
        GUICtrlSetData(-1, $penWidth)
        $rect = GUICtrlCreateLabel("", 420, 235, 40, 25)
        GUICtrlSetData(-1, $penWidth)
;~ $iStartCap
;~ 起点线帽的样式:
;~ 0x00 - 直线以方形线帽结束.
;~ 0x01 - 方形线帽. 直线在方形中心结束. 方形宽高为线宽.
;~ 0x02 - 圆形端点. 直线在圆形中心结束. 圆形直径为线宽.
;~ 0x03 - 三角形线帽. 直线在三角形基线结束. 三角形基线为线宽.
;~ 0x10 - 线帽不固定.
;~ 0x11 - 线终点以方形固定. 方形中心为线的最后一点. 方形宽高大于线宽.
;~ 0x12 - 线终点以圆形固定. 圆形中心为线的最后一点. 圆宽于线.
;~ 0x13 - 线终点以钻石形固定(方形旋转45度). 钻石形中心为线的最后一点. 钻石形宽于线.
;~ 0x14 - 线终点以箭头固定. 箭头顶点为线的最后一点. 箭头宽于线.
;~ 0xff - 线帽由CustomLineCap对象创建.
;~ $iEndCap
;~ 终点线帽的样式(与$iStartCap相同)
;~ $iDashCap
;~ 破折号的起点和终点线帽:
;~ 0 - 两端点均为方形线帽
;~ 2 - 两端点均为圆形线帽
;~ 3 - 两端点均为三角形线帽的最后一点. 箭头宽于线.
;~ _GDIPlus_PenSetLineCap( $hPen, $iStartCap, $iEndCap, $iDashCap )
;~ _GDIPlus_PenSetStartCap($hPen, $iEndCap)
;~ _GDIPlus_PenSetEndCap($hPen, $iEndCap)
;~ _GDIPlus_PenSetDashCap($hPen[, $iDash = 0])
        GUICtrlCreateLabel("起点形状", 5, 265)
        $Cap = GUICtrlCreateSlider(60, 265, 100)
        GUICtrlSetLimit(-1, 9, 0)
        GUICtrlSetData(-1, 0)
        _GUICtrlSlider_SetTicFreq(-1, 1)
        $Cap = GUICtrlCreateLabel("", 170, 265, 40, 25)
        GUICtrlSetData(-1, "直线")
       
        GUICtrlCreateLabel("终点形状", 255, 265)
        $Cap = GUICtrlCreateSlider(310, 265, 100)
        GUICtrlSetLimit(-1, 9, 0)
        GUICtrlSetData(-1, 0)
        _GUICtrlSlider_SetTicFreq(-1, 1)
        $Cap = GUICtrlCreateLabel("", 420, 265, 40, 25)
        GUICtrlSetData(-1, "直线")
;~ _GDIPlus_PenSetLineJoin( $hPen, $iLineJoin )
;~ $iLineJoin
;~ 线连接类型:
;~ 0 - 线连接生成一个锐角
;~ 1 - 线连接生成一个对角Line join produces a diagonal corner.
;~ 2 - 线连接在两线间生成平滑的圆弧
;~ 3 - 线连接生成一个锐角剪切角
        GUICtrlCreateLabel("线连接类型", 5, 295)
        GUIStartGroup()
        $lineJoin = GUICtrlCreateRadio("锐角连接", 105, 295)
        GUICtrlSetState(-1, 1)
        $lineJoin = GUICtrlCreateRadio("对角连接", 205, 295)
        $lineJoin = GUICtrlCreateRadio("圆弧连接", 305, 295)
        $lineJoin = GUICtrlCreateRadio("切角连接", 405, 295)
        GUICtrlCreateLabel("虚线连接样式", 5, 325)
        GUIStartGroup()
        $DashCap = GUICtrlCreateRadio("方形", 105, 325)
        GUICtrlSetState(-1, 1)
        $DashCap = GUICtrlCreateRadio("圆形", 205, 325)
        $DashCap = GUICtrlCreateRadio("三角", 305, 325)
        GUICtrlCreateLabel("直线类型", 5, 355)
        GUIStartGroup()
        $line = GUICtrlCreateRadio("实线", 105, 355)
        GUICtrlSetState(-1, 1)
        $line = GUICtrlCreateRadio("虚线", 205, 355)
        $line = GUICtrlCreateRadio("复合", 305, 355)
EndFunc   ;==>init

Func onHSCROLL($hWnd, $iMsg, $wParam, $lParam)
        Switch _WinAPI_GetDlgCtrlID($lParam)
                Case $rect
                        $startX = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $startX)
                Case $rect
                        $startY = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $startY)
                Case $rect
                        $lineWidth = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $lineWidth)
                Case $rect
                        $penWidth = GUICtrlRead($rect)
                        GUICtrlSetData($rect, $penWidth)
                Case $Cap
                        $iStartCap = GUICtrlRead($Cap)
                        $iStartCap = setDate($iStartCap, 1)
                Case $Cap
                        $iEndCap = GUICtrlRead($Cap)
                        $iEndCap = setDate($iEndCap, 3)
        EndSwitch
        update()
EndFunc   ;==>onHSCROLL

Func setDate($nCap, $n)
        Switch $nCap
                Case 0
                        GUICtrlSetData($Cap[$n], "直线")
                Case 1
                        GUICtrlSetData($Cap[$n], "方形")
                Case 2
                        GUICtrlSetData($Cap[$n], "圆形")
                Case 3
                        GUICtrlSetData($Cap[$n], "三角")
                Case 4
                        GUICtrlSetData($Cap[$n], "不固定")
                        $nCap += 12
                Case 5
                        GUICtrlSetData($Cap[$n], "大方形")
                        $nCap += 12
                Case 6
                        GUICtrlSetData($Cap[$n], "大圆形")
                        $nCap += 12
                Case 7
                        GUICtrlSetData($Cap[$n], "大钻石")
                        $nCap += 12
                Case 8
                        GUICtrlSetData($Cap[$n], "箭头")
                        $nCap += 12
                Case 9
                        GUICtrlSetData($Cap[$n], "自定义")
                        $nCap = 0xFF
        EndSwitch
        Return $nCap
EndFunc   ;==>setDate

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抗距齿
        TextureBrushComp($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 TextureBrushComp($hGraphics)
        Local $hPen = _GDIPlus_PenCreate(0xFFFF0000, $penWidth);左边红色画笔
       
        Local $hBrush = _GDIPlus_LineBrushCreate(0, 0, 10, 10, 0xFFFFFF00, 0xFFFF0000)
        Local $hpen2 = _GDIPlus_PenCreate2($hBrush, $penWidth)
        _GDIPlus_BrushDispose($hBrush);右边渐变画笔
        ;如果虚线设置虚线,及虚线连接样式
        If GUICtrlRead($line) = 1 Then
                _GDIPlus_PenSetDashStyle($hPen, 1);虚线
                _GDIPlus_PenSetDashCap($hPen, $iDashCap)
                _GDIPlus_PenSetDashStyle($hPen2, 2);点线
                _GDIPlus_PenSetDashCap($hPen2, $iDashCap)
        EndIf
;~         ;复合画笔指同时画多条线,$aCompounds = 指二条线,第一条是画笔宽从0-0.2,第二条是从画笔宽0.5-1
        If GUICtrlRead($line) = 1 Then
                Local $aCompounds =
                _GDIPlus_PenSetCompoundArray($hPen, $aCompounds);复合画笔
                _GDIPlus_PenSetCompoundArray($hPen2, $aCompounds);复合画笔
        EndIf
        ;设置连接方式
        _GDIPlus_PenSetLineJoin($hPen, $iLineJoin)
        _GDIPlus_PenSetLineJoin($hPen2, $iLineJoin)
        Local $aPoints = [,[$startX, $startY + 60],[$startX + $lineWidth, $startY + 60],[$startX + $lineWidth, $startY + 140]]
        ;绘制黑色参考线,左边界,右边界,中心线
        _GDIPlus_GraphicsDrawLine($hGraphics, $startX, $startY, $startX, $startY + 40)
        _GDIPlus_GraphicsDrawLine($hGraphics, $startX + $lineWidth, $startY, $startX + $lineWidth, $startY + 40)
        _GDIPlus_GraphicsDrawLine($hGraphics, $startX - 20, $startY + 20, $startX + $lineWidth + 20, $startY + 20)
        ;设置笔帽
        _GDIPlus_PenSetStartCap($hPen, $iStartCap)
        _GDIPlus_PenSetEndCap($hPen, $iEndCap)
        _GDIPlus_PenSetStartCap($hPen2, $iStartCap)
        _GDIPlus_PenSetEndCap($hPen2, $iEndCap)
        ;左边图形
        _GDIPlus_GraphicsDrawLine($hGraphics, $startX, $startY + 20, $startX + $lineWidth, $startY + 20, $hPen)
        _GDIPlus_GraphicsDrawPolygon($hGraphics, $aPoints, $hPen)
        ;右边图形
        _GDIPlus_GraphicsTranslateTransform($hGraphics, 250, 0)
        _GDIPlus_GraphicsDrawLine($hGraphics, $startX, $startY + 20, $startX + $lineWidth, $startY + 20, $hPen2)
        _GDIPlus_GraphicsDrawPolygon($hGraphics, $aPoints, $hPen2)
        ;释放画笔
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_PenDispose($hPen2)
;_GDIPlus_PenSetMiterLimit( $hPen, $nMiterLimit )
;$nMiterLimit
;指定画笔对象的斜切限制的实际数字. 如该值小于1则以1替代
;斜切限制没有调试出效果,所以不用了
;===================================================
;_GDIPlus_PenSetAlignment($hPen,1)
;这句的作用是画封闭图形时,让线向内对齐
;==========不作演示了===============================
EndFunc   ;==>TextureBrushComp

hzxymkb 发表于 2013-5-31 22:37:00

这回坐定沙发了!哈哈!

f4李文杨 发表于 2013-5-31 22:48:42

真要学习了!

楼上风云 发表于 2013-5-31 23:26:01

回复 1# seniors

一群码农,就这么痴痴地过周末

楼上风云 发表于 2013-5-31 23:27:18

回复 2# hzxymkb

水哥多久不见,越发小气了。才贡献5大元?

devilma 发表于 2013-6-1 11:16:52

不错啊。。学习一下。。

seniors 发表于 2013-6-1 11:46:09

回复 4# 楼上风云
汉字笔顺是路径问题,下次讲路径时看,能不能把路径读出来,分析一下

userdel 发表于 2013-6-1 13:39:05

六一都不去过节,这种精神可贵啊!

jirunyang 发表于 2013-6-2 20:26:18

s大有新课了没?很期待啊!

chishingchan 发表于 2013-6-3 20:51:52

我也顶一个支持一下!

wowuwoxiu 发表于 2016-10-3 14:24:00

"D:\Users\Administrator\Desktop\dddd.au3"(222,64) : error: _GDIPlus_PenSetCompoundArray(): undefined function.
页: [1]
查看完整版本: 第十一讲 GDI+画笔及线型