1月142015
[教程]第十三讲 GDI+区域及剪切区域
ACN论坛.讲师:seniors 转载请说明此文出处所在:<<简易工作室>>,谢谢!
一、GDI+区域
1、建立
GDI+的路径和区域与GDI的路径和区域不同,GDI只能有一个路径和区域,而GDI+可以同时有多个路径和区域
2、区域混合
;~ 区域的相交模式:
;~ 0 - 用新区域替换已存在的区域
;~ 1 - 用区域自身和新区域的相交部分替换已存在的区域
;~ 2 - 用区域自身和新区域的结合部分替换已存在的区域
;~ 3 - 对两个区域执行异或(XOR)操作的结果替换已存在的区域位于两区域的XOR部分的点表示它在其中一个但不同时在两个区域中
;~ 4 - 用区域自身和新区域外部替换已存在的区域
;~ 5 - 用在已存在区域的外部的新区域部分替换已存在的区域
3、区域的填充
区域没有描边,只有填充,填充函数在3.3.7.15中有误
改为如下吧
Func _GDIPlus__GraphicsFillRegion($hGraphics, $hRegion, $hBrush = 0) Local $iTmpErr, $iTmpExt, $aResult __GDIPlus_BrushDefCreate($hBrush) $aResult = DllCall($ghGDIPDll, "uint", "GdipFillRegion", "hwnd", $hGraphics, "hwnd", $hBrush, "hwnd", $hRegion) $iTmpErr = @error $iTmpExt = @extended __GDIPlus_BrushDefDispose() If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False) $GDIP_STATUS = $aResult[0] Return $aResult[0] = 0 EndFunc ;==>_GDIPlus__GraphicsFillRegion ```
```二、剪切区域(画布的剪切区域) 剪切区域和区域是两回事,应该都叫区域我就放一起了 画布设置了剪切区域后,所有的绘制操作,只有在剪切区域时才能绘制 建立方法 剪切区域的混合模式和区域的混合模式一样 剪切区域的释放 _GDIPlus_GraphicsResetClip($hGraphics) 例子中,右下二个就是剪切区域``````#include <APIConstants.au3> #include <WinAPIEx.au3> #include <GDIPlus.au3> #include <GDIPlusEx.au3> GUICreate("第十三讲 GDI+区域", 500, 200) $nCtrlId = GUICtrlCreatePic("", 0, 0, 500, 200) $hPicWnd = GUICtrlGetHandle($nCtrlId) GUISetState() update() While 1 $Msg = GUIGetMsg() Switch $Msg Case -3 ExitLoop EndSwitch WEnd GUIDelete() Exit Func update() Local $HWND_CX = _WinAPI_GetWindowWidth($hPicWnd) Local $HWND_CY = _WinAPI_GetWindowHeight($hPicWnd) _GDIPlus_Startup() $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hPicWnd) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($HWND_CX, $HWND_CY, $hGraphics) $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsClear($hBackbuffer, 0xFFECE9D8) _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2);光滑模式,2为8*8抗距齿 CombinemodeComp($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 CombinemodeComp($hGraphics) Local $hPen = _GDIPlus_PenCreate(0xFFFF0000, 1) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000) ;从矩形区域建立区域 Local $tRectF = _GDIPlus_RectFCreate(10, 20, 80, 30) Local $hRgn1 = _GDIPlus_RegionCreateFromRect($tRectF) ;从路径建立区域 Local $hPath = _GDIPlus_PathCreate() _GDIPlus_PathAddEllipse($hPath, 25, 10, 50, 50) Local $hRgn2 = _GDIPlus_RegionCreateFromPath($hPath) ;~ 区域的相交模式: ;~ 0 - 用新区域替换已存在的区域 ;~ 1 - 用区域自身和新区域的相交部分替换已存在的区域 ;~ 2 - 用区域自身和新区域的结合部分替换已存在的区域 ;~ 3 - 对两个区域执行异或(XOR)操作的结果替换已存在的区域位于两区域的XOR部分的点表示它在其中一个但不同时在两个区域中 ;~ 4 - 用区域自身和新区域外部替换已存在的区域 ;~ 5 - 用在已存在区域的外部的新区域部分替换已存在的区域 Local $hRgn For $i = 1 To 5 ;复制区域1 $hRgn = _GDIPlus_RegionClone($hRgn1) ;把区域2通过模式$i混合到$hRgn _GDIPlus_RegionCombineRegion($hRgn, $hRgn2, $i) ;填充$hRgn _GraphicsFillRegion($hGraphics, $hRgn, $hBrush) ;释放$hRgn _GDIPlus_RegionDispose($hRgn) _GDIPlus_GraphicsDrawRect($hGraphics, 5, 5, 90, 60) _GraphicsDrawString($hGraphics, "混合模式" & $i, 10, 70) _GDIPlus_GraphicsTranslateTransform($hGraphics, 100, 0) Next _GDIPlus_GraphicsResetTransform($hGraphics) _GDIPlus_GraphicsTranslateTransform($hGraphics, 0, 90) ;绘制$hRgn1和$hRgn2的原始外形,由于区域没有绘制外形的函数,所以直接绘制了原始圆形路径和原始矩形 _GraphicsDrawPath($hGraphics, $hPath, $hPen);原始圆形路径 _GDIPlus_PenSetColor($hPen, 0xFF00FF00) _GDIPlus_GraphicsDrawRect($hGraphics, 10, 20, 80, 30, $hPen);原始矩形 _GraphicsDrawString($hGraphics, "原区域形状", 10, 70) ;释放 _GDIPlus_PathDispose($hPath) _GDIPlus_RegionDispose($hRgn1) _GDIPlus_RegionDispose($hRgn2) ;==============================下面是画布剪切区域的设置====================== Local $hFamily = _GDIPlus_FontFamilyCreate("Arial") Local $tLayout = _GDIPlus_RectFCreate(0, 0) $hPath = _GDIPlus_PathCreate() _GDIPlus_PathAddString($hPath, "Au3", $tLayout, $hFamily, 1, 100) _GDIPlus_GraphicsTranslateTransform($hGraphics, 100, 0) _GraphicsDrawPath($hGraphics, $hPath, $hPen) _GDIPlus_PenSetColor($hPen, 0xFFFF0000) ;从路径获取画布的剪切区域============ _GDIPlus_GraphicsSetClipPath($hGraphics, $hPath) ;以下同心圆超出剪切区域的不会绘制出来 For $i = 0 To 30 _GDIPlus_GraphicsDrawEllipse($hGraphics, 125 - $i * 5, 60 - $i * 5, $i * 10, $i * 10, $hPen) Next ;使剪切区域无限大,相当于不设置剪切区域 _GDIPlus_GraphicsResetClip($hGraphics) _GDIPlus_PathDispose($hPath) ;以下设置从区域设置剪切区域================ _GDIPlus_GraphicsTranslateTransform($hGraphics, 250, 0) $hPath = _GDIPlus_PathCreate(1) _GDIPlus_PathAddEllipse($hPath, 5, 5, 100, 100) _GDIPlus_PathAddEllipse($hPath, 80, 5, 30, 30) _GDIPlus_BrushSetSolidColor($hBrush, 0x33003399) _GraphicsFillPath($hGraphics, $hPath, $hBrush) ;从路径设置区域 $hRgn = _GDIPlus_RegionCreateFromPath($hPath) _GDIPlus_PathDispose($hPath) ;从区域设置画布的剪切区域 _GDIPlus_GraphicsSetClipRegion($hGraphics, $hRgn) _GDIPlus_BrushSetSolidColor($hBrush, 0xFFFF0000) For $i = 0 To 10 _GraphicsDrawString($hGraphics, "我爱Autoit,I love au3", 0, $i * 14, $hBrush) Next _GDIPlus_RegionDispose($hRgn) _GDIPlus_BrushDispose($hBrush) _GDIPlus_PenDispose($hPen) EndFunc ;==>CombinemodeComp ;_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[0], $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[0] Return $aResult[0] = 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[0] Return $aResult[0] = 0 EndFunc ;==>_GraphicsFillPath Func _GraphicsFillRegion($hGraphics, $hRegion, $hBrush = 0) Local $iTmpErr, $iTmpExt, $aResult __GDIPlus_BrushDefCreate($hBrush) $aResult = DllCall($ghGDIPDll, "uint", "GdipFillRegion", "hwnd", $hGraphics, "hwnd", $hBrush, "hwnd", $hRegion) $iTmpErr = @error $iTmpExt = @extended __GDIPlus_BrushDefDispose() If $iTmpErr Then Return SetError($iTmpErr, $iTmpExt, False) $GDIP_STATUS = $aResult[0] Return $aResult[0] = 0 EndFunc ;==>_GraphicsFillRegion ```
``````
本文固定链接: http://jianyiit.com/post-61.html
扫描二维码,在手机上阅读
发表评论
木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!