返回列表 发帖

[交流] 第三讲 GDI画笔、线型

本帖最后由 seniors 于 2013-6-16 08:04 编辑

3、GDI之画笔pen
本讲要用到的函数
_WinAPI_DrawLine两点间画线
_WinAPI_MoveTo移动当前位置到某点
_WinAPI_LineTo从当前位置画线到某点
_WinAPI_LineDDA;确切的说这不是画线函数,它是从某点到另一点的过程中,每经过一个点调用指定的函数

_WinAPI_Rectangle 在一个矩形区域画矩形
_WinAPI_RoundRect 在矩形区域画圆角矩形
_WinAPI_AngleArc 画弧线从角度到角度
_WinAPI_Arc 画弧线从点到点
_WinAPI_ArcTo 画弧线从点到点,改变当前位置
_WinAPI_Ellipse  在矩形区域画椭圆
上面这些函数都要用到画笔来绘制线条,有些封闭区域的,还会用画刷填充,画刷下一讲再讲。
画笔建立有二种方式
一是用系统画笔:如$hPen = _WinAPI_GetStockObject($BLACK_PEN);黑画笔,$NULL_PEN是空画笔,也就是不会绘制线条
系统定义好的画笔只有黑白空三种,要更多样的就要用第二种方式。有没有记得上次我们用_WinAPI_GetStockObject设置字体。
二是用_WinAPI_CreatePen,它可以指定类型、指定画笔宽度、指定颜色BGR格式
线宽只适用于实心纯色和空画笔(PS_NULL),其它类型即便你设置了也当做宽度是1

实心纯色有两种方式PS_SOLID和PS_INSIDEFRAME
PS_SOLID画线时,是以线宽的早间为准
PS_INSIDEFRAME画封闭图形时,线宽是全部画在图形内;如果不是封闭图形则和PS_SOLID相同

画笔使用也要_WinAPI_SelectObject选择,用好后再_WinAPI_SelectObject换回,如果不用了再_WinAPI_DeleteObject释放

本讲例子中,还讲到了一个不填充封闭矩形的方法

布置作业,画出一个简单的刻度尺,其中刻度线用_WinAPI_LineDDA函数
如果lineDDA看不懂,我隐藏了画刻度线的代码,回复看一下

  1. #include <APIConstants.au3>

  2. #include <WinAPIEx.au3>

  3.  

  4. GUICreate("第三讲", 300, 200)

  5. $ctrlId = GUICtrlCreatePic("", 0, 0, 300, 200)

  6. $hWnd = GUICtrlGetHandle($ctrlId)


  7. gditest()

  8.  


  9.         $Msg = GUIGetMsg()

  10.         Switch $Msg

  11.                 Case -3

  12.                         ExitLoop

  13.         EndSwitch




  14.  

  15. Func gditest()

  16.         $hDC = _WinAPI_GetDC($hWnd)

  17.  

  18.         $hPen_PS_SOLID = _WinAPI_CreatePen($PS_SOLID, 10, 0x0000FF);红色实线画笔宽度为10

  19.         $hPen_PS_INSIDEFRAME = _WinAPI_CreatePen($PS_INSIDEFRAME, 10, 0x0000FF);红色实线向内画笔宽度为10

  20.         $hPen_PS_DASH0 = _WinAPI_CreatePen($PS_DASH, 0, 0x000000);黑色虚线宽度为0的画笔,实际宽度还是1,如果大于1,则变为实线画笔,宽度大于1只对实线画笔和空画笔

  21.         $hPen_PS_DASH1 = _WinAPI_CreatePen($PS_DASH, 1, 0x000000);黑色虚线宽度为1的画笔

  22.         $hBrush = _WinAPI_GetStockObject($NULL_BRUSH);空画刷

  23.         ;一、和三去对照看

  24.         $oldPen = _WinAPI_SelectObject($hDC, $hPen_PS_SOLID);选择红色实线画笔宽度为10

  25.         $oldBrush = _WinAPI_SelectObject($hDC, $hBrush);选择空画刷,作用是画矩形框时中间不填充,和三、中的矩形框看

  26.         $tRECT = _WinAPI_CreateRect(10, 10, 90, 90);

  27.         _WinAPI_Rectangle($hDC, $tRECT);画矩形框,因为画刷是空的所以中间没有填充颜色

  28.         _WinAPI_DrawLine($hDC, 120, 10, 220, 10);画一条直线和三、画的直线对比看看

  29.         _WinAPI_SelectObject($hDC, $oldPen);

  30.         _WinAPI_SelectObject($hDC, $oldBrush);

  31.         ;二、在一、的基础上画一条宽度为1的虚线,看看一中的宽度10的画笔是怎么画的

  32.         $oldPen = _WinAPI_SelectObject($hDC, $hPen_PS_DASH0);选择宽度为0的虚线

  33.         $oldBrush = _WinAPI_SelectObject($hDC, $hBrush);选择空画刷

  34.         $tRECT = _WinAPI_CreateRect(10, 10, 90, 90);

  35.         _WinAPI_Rectangle($hDC, $tRECT);画矩形

  36.         _WinAPI_DrawLine($hDC, 120, 10, 220, 10);画直线

  37.         _WinAPI_SelectObject($hDC, $oldPen);

  38.         _WinAPI_SelectObject($hDC, $oldBrush);

  39.         ;三、和一的对照看

  40.         $oldPen = _WinAPI_SelectObject($hDC, $hPen_PS_INSIDEFRAME);选择红色实线向内画笔宽度为10

  41.         $tRECT = _WinAPI_CreateRect(10, 110, 90, 190);

  42.         _WinAPI_Rectangle($hDC, $tRECT);

  43.         _WinAPI_DrawLine($hDC, 120, 110, 220, 110);

  44.         _WinAPI_SelectObject($hDC, $oldPen);

  45.         ;四在三的基础上画虚线,看三中的宽度10的画笔是怎么画的

  46.         $oldPen = _WinAPI_SelectObject($hDC, $hPen_PS_DASH1);选择宽度为1的虚线

  47.         $oldBrush = _WinAPI_SelectObject($hDC, $hBrush);

  48.         $tRECT = _WinAPI_CreateRect(10, 110, 90, 190);

  49.         _WinAPI_Rectangle($hDC, $tRECT);

  50.         _WinAPI_DrawLine($hDC, 120, 110, 220, 110);

  51.         _WinAPI_SelectObject($hDC, $oldPen);

  52.         _WinAPI_SelectObject($hDC, $oldBrush);

  53.         ;释放建立的对象

  54.         _WinAPI_DeleteObject($hPen_PS_SOLID)

  55.         _WinAPI_DeleteObject($hPen_PS_INSIDEFRAME)

  56.         _WinAPI_DeleteObject($hPen_PS_DASH0)

  57.         _WinAPI_DeleteObject($hPen_PS_DASH1)

  58.         _WinAPI_DeleteObject($hBrush)

  59.        

  60.         ;画讲解文字

  61.         $hPen = _WinAPI_CreatePen($PS_SOLID, 2, 0x00FFFF)

  62.         $oldPen = _WinAPI_SelectObject($hDC, $hPen)

  63.         _WinAPI_MoveTo($hDC, 90, 10)

  64.         _WinAPI_LineTo($hDC, 110, 50)

  65.         _WinAPI_MoveTo($hDC, 120, 10)

  66.         _WinAPI_LineTo($hDC, 110, 50)

  67.         _WinAPI_MoveTo($hDC, 90, 110)

  68.         _WinAPI_LineTo($hDC, 110, 150)

  69.         _WinAPI_MoveTo($hDC, 120, 110)

  70.         _WinAPI_LineTo($hDC, 110, 150)

  71.         _WinAPI_SelectObject($hDC, $oldPen)

  72.         _WinAPI_DeleteObject($hPen)

  73.        

  74.         $hFont = _WinAPI_GetStockObject($DEFAULT_GUI_FONT)

  75.         _WinAPI_SelectObject($hDC, $hFont)

  76.         _WinAPI_SetBkColor($hDC, 0x339933)

  77.         $tRECT = _WinAPI_CreateRect(110, 50, 290, 90)

  78.         _WinAPI_DrawText($hDC, "PS_SOLID"&@CR&"画笔以中间为准", $tRECT, $DT_EDITCONTROL)

  79.         _WinAPI_SetBkColor($hDC, 0x3399FF)

  80.         $tRECT = _WinAPI_CreateRect(110, 150, 290, 190)

  81.         _WinAPI_DrawText($hDC, "PS_INSIDEFRAME画笔"&@CR&"画直线以中间为准"&@CR&"画封闭图形向内画线", $tRECT, $DT_EDITCONTROL)

  82.  

  83.         _WinAPI_ReleaseDC($hWnd, $hDC)

  84. EndFunc   ;==>gditest

复制代码 高亮切换

本帖隐藏的内容需要回复才可以浏览
附件: 您需要登录才可以下载或查看附件。没有帐号?加入
6

评分人数

  • lixiaolong

  • 楼上风云

  • xms77

  • lpxx

  • user3000

坐沙发致敬~!
Hello...

TOP

要好好认真学习一下。
自己知道的,尽量告诉别人,自己不知道的,虚心学习

TOP

继续学习,没抢到沙发~
转身离开
分手说不出来
海鸟跟鱼相爱
只是一场意外
我们的爱差异一直存在
风中尘埃竟累积成伤害

TOP

回复 1# seniors
每天一讲认真学习

TOP

没有沙发  首页支持 !
业精于勤荒于嬉。

TOP

回复 1# seniors


    大虾,你辛苦了。
正在继续消化中....

TOP

回复 1# seniors
GDI真的需要花很大的力气来学习啊!
Seniors大侠,为什么GDI画的东西在窗体最小化后会消失呢?窗体回复后要怎样重画图形?
懒人一个

TOP

这么多函数,看过了当时能记住每个的用法,如果日后不练习的话,估计很快会忘掉。
主要是一些逻辑搞不清楚,所以标尺画的很乱,还请老师指点。
交作业:

  1. ;~ 布置作业,画出一个简单的刻度尺,其中刻度线用_WinAPI_LineDDA函数

  2. ;~ 如果lineDDA  看不懂,我隐藏了画刻度线的代码,回复看一下

  3. #include <APIConstants.au3>

  4. #include <WinAPIEx.au3>

  5. #include <WindowsConstants.au3>

  6.  

  7. Global Const $STM_SETIMAGE = 0x0172

  8. Global Const $STM_GETIMAGE = 0x0173

  9. Global $Count = 0, $n = 0

  10. Global $HBiaoChi = DllCallbackRegister('BiaoChi', 'none', 'int;int;lparam')

  11. Global $BIAOCHI = DllCallbackGetPtr($HBiaoChi)

  12.  

  13. GUICreate("作业3", @DesktopWidth, 100, -1, -1, $WS_POPUP)

  14. $ctrlId = GUICtrlCreatePic("", 0, 0, @DesktopWidth, 100)

  15. $hWnd = GUICtrlGetHandle($ctrlId)


  16. WinSetOnTop("作业3", "", 1)

  17. gditest()

  18.  


  19.         $Msg = GUIGetMsg()

  20.         Switch $Msg

  21.                 Case -3

  22.                         ExitLoop

  23.         EndSwitch




  24.  

  25. Func gditest()

  26.         $hDC = _WinAPI_GetDC($hWnd)

  27.         $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0x000000)

  28.         _WinAPI_SelectObject($hDC, $hPen)

  29.         $hMemDC = _WinAPI_CreateCompatibleDC($hDC)

  30.         $hBitmap = _WinAPI_CreateCompatibleBitmapEx($hDC, @DesktopWidth, 100, _WinAPI_SwitchColor(_WinAPI_GetSysColor($COLOR_3DFACE)))

  31.         $hMemSv = _WinAPI_SelectObject($hMemDC, $hBitmap)

  32.         _WinAPI_LineDDA(0, 0, @DesktopWidth, 0, $BIAOCHI, $hMemDC)

  33.  

  34.  

  35.         _WinAPI_DeleteObject($hPen)

  36.         _WinAPI_ReleaseDC($hWnd, $hDC)

  37.         _WinAPI_SelectObject($hMemDC, $hMemSv)

  38.         _WinAPI_DeleteDC($hMemDC)

  39.        

  40.         _SendMessage($hWnd, $STM_SETIMAGE, 0, $hBitmap)

  41.         $hObj = _SendMessage($hWnd, $STM_GETIMAGE)

  42.         If $hObj <> $hBitmap Then

  43.                 _WinAPI_DeleteObject($hBitmap)

  44.         EndIf

  45. EndFunc   ;==>gditest

  46.  

  47. Func BiaoChi($iX, $iY, $hDC)

  48.         Local $NUM = Mod($Count, 20)

  49.         Switch $NUM

  50.                 Case 0

  51.                         _WinAPI_DrawLine($hDC, $iX, $iY, $iX, $iY + 25)

  52.                         _WinAPI_SetBkMode($hDC, $TRANSPARENT)

  53.                         $tRECT = _WinAPI_CreateRect($iX - 8, $iY + 25, $iX + 8, $iY + 45)

  54.                         _WinAPI_DrawText($hDC, $n, $tRECT, $DT_CENTER)

  55.                         $n += 1

  56.                 Case 10

  57.                         _WinAPI_DrawLine($hDC, $iX, $iY, $iX, $iY + 15)

  58.         EndSwitch

  59.         $Count += 1

  60. EndFunc   ;==>BiaoChi

复制代码 高亮切换
附件: 您需要登录才可以下载或查看附件。没有帐号?加入
1

评分人数

  • seniors

转身离开
分手说不出来
海鸟跟鱼相爱
只是一场意外
我们的爱差异一直存在
风中尘埃竟累积成伤害

TOP

回复 8# xms77
不要着急,反正先能用GDI画出来,要一直能显示,只是告诉系统我要显示这个图形,不急啊

TOP

回复 9# haijie1223
我不知道其它人是不是能记住每个函数的用法,反正我是记不住。
我只是知道有这样一个功能,到用时再看帮助,反正我不是专业编程的,对不对。

标尺画的不错

TOP

回复 11# seniors


    看着帮助,照葫芦画瓢,不过通过你的讲解和做你布置的作业,起码能知道这些函数的用法,收获良多~

TOP

回复 12# haijie1223
少个了一个画点函数,还是用lineDDA来画个正弦函数图像

  1. #include <APIConstants.au3>

  2. #include <WinAPIEx.au3>

  3.  

  4. Global $HBiaoChi = DllCallbackRegister('BiaoChi', 'none', 'int;int;lparam')

  5. Global $BIAOCHI = DllCallbackGetPtr($HBiaoChi)

  6.  

  7. GUICreate("作业3", 600, 60)

  8. $ctrlId = GUICtrlCreatePic("", 0, 0, 600, 60)

  9. $hWnd = GUICtrlGetHandle($ctrlId)


  10. WinSetOnTop("作业3", "", 1)

  11. gditest()

  12.  


  13.         $Msg = GUIGetMsg()

  14.         Switch $Msg

  15.                 Case -3

  16.                         ExitLoop

  17.         EndSwitch




  18.  

  19. Func gditest()

  20.         $hDC = _WinAPI_GetDC($hWnd)

  21.         $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0x000000)

  22.         _WinAPI_SelectObject($hDC, $hPen)

  23.         _WinAPI_SetBkMode($hDC, $TRANSPARENT)

  24.         _WinAPI_DrawLine($hDC, 0, 30, 600, 30)

  25.         _WinAPI_DrawLine($hDC, 10, 0, 10, 60)

  26.         _WinAPI_TextOut($hDC, 20, 5, "y = 20 * sin(x)")

  27.         _WinAPI_LineDDA(10, 30, 590, 30, $BIAOCHI, $hDC)

  28.         _WinAPI_DeleteObject($hPen)

  29.         _WinAPI_ReleaseDC($hWnd, $hDC)

  30. EndFunc   ;==>gditest

  31.  

  32. Func BiaoChi($iX, $iY, $hDC)

  33.         _WinAPI_SetPixel($hDC, $iX, 20 * Sin(($iX - 10) / 10) + 30, 0xFF0000)

  34. EndFunc   ;==>BiaoChi

复制代码 高亮切换
附件: 您需要登录才可以下载或查看附件。没有帐号?加入
1

评分人数

  • haijie1223

TOP

学习一下GDI知识

TOP

回复 1# seniors


    学习了

TOP

返回列表