鱼C论坛

 找回密码
 立即注册
查看: 2175|回复: 0

[学习笔记] 《Windows SDK》024 窗口绘画小结(015-023)

[复制链接]
发表于 2017-7-27 12:51:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 BngThea 于 2017-7-27 12:55 编辑

由于课程的024讲是利用绘图函数绘制哆啦A梦,无实际新知识点,故将该课时用于总结窗口绘画

一 绘画基础知识
* 绘画实际上是给窗口中的像素上色
从 SetPixel / SetPixelV 两个函数的单词组合可以理解到绘画的本质

* Windows 中的颜色为COLORREF
1 COLORREF通过宏RGB(red, green, blue)的三原色数值进行表征
2 COLORREF本质上一个DWORD类对象,由四个字节构成,从最低位到最高位分别存放三原色红绿蓝和零

* POINT 结构
POINT结构用来存放窗口中的某个像素的的xy坐标,在绝大多数绘制API函数中都会使用

* LOGPEN 结构和 LOGBRUSH 结构
两种结构可以分别存放自定义的画笔或画刷的特性,一般结合 CreatePenIndirect 或 CreateBrushIndirect 使用


二 绘画进阶知识
* 每次绘画都必须获得hdc,其方式有以下几种
1 BeginPaint + EndPaint —— 通常在WM_PAINT消息中,配合一个PAINTSTRUCT使用,可以操作失效区域
2 GetDC + ReleaseDC   —— 适用各种情况,但一般操作整个客户区
3 GetWindowDC + ReleaseDC —— 获得整个窗口的hdc,包括非客户区
4 CreateDC + DeleteDC —— 直接生成一个DC供使用
5 CreateIC + DeleteDC —— 获取hdc,但不能进行绘制
6 CreateCompatibleDC + DeleteDC —— 直接生成一个DC,用来与指定设备兼容
7 CreateMetaFile + CloseMetaFile —— 直接生成一个DC,但只能用来创建图元文件

* “当前位置”
1 每次绘制的时候,都需要知道绘制的起点,很多时候,“当前位置”描述的就是这样一个位置,可以通过 GetCurrentPosition 函数来获取该位置,或者通过 MoveToEx 函数来设定绘制的起点
2 所有的绘画API函数都分为操作或不操作“当前位置”,在绘制曲线时要特别留意其区别

* 绘制的曲线根据客户区尺寸自动改变大小
典型的做法是——            首先,定义两个静态的存放窗口尺寸的变量:
                                              static int cxClient,cyClinet
然后,在处理WM_SIZE消息时获取当前窗口客户区的尺寸:
                                              cxClient = LOWORD(lParam);
                                              cyClient = HIWORD(lParam);

* Windows 自带有不同的画笔和画刷
可以通过函数 GetStockObject(item) 来获取预设的画笔或画刷,其中item可以是以下的一种——
1 画笔:BLACK_PEN, WHITE_PEN,NULL_PEN,4 DC_PEN
2 画刷: BLACK_BRUSH,WHITE_BRUSH, HOLLOW_BRUSH / NULL_BRUSH,DC_BRUSH,DKGRAY_BRUSH,GRAY_BRUSH,LIGRAY_BRUSH

* 可以自定义画笔和画刷
1 通过 CreatePen / CreatePenIndirct 来自定义画笔
2 通过 CreateSolidBrush / CreateHatchBrush / CreateBrushIndirect 来自定义画刷

* 灵活的操作画笔和画刷
1 定义好画笔或画刷后,需要用SelectObject来将自定义的对象选中,此时较为科学的做法如下
           (选中hPen)hOldPen = SelectObject(hPen) ->使用该hPen->还原hOldPen)SelectObject(hOldPen)
2 一般在WM_DESTROY消息中利用 DeleteObject 函数来销毁自定义的画笔或画刷
3 如果需要使用的画笔或画刷类型较多,可以用 LOGPEN 或 LOGBRUSH 结构的方式来自定义创建
4 可以通过 GetCurrentObject 或 GetObject 来获取当前画笔或画刷的信息
5 可以通过 SetDCPenColor 和 SetDCBrushColor 来设置画笔或画刷的颜色

* 边框绘制函数
1 不同于简单的点线绘制,边框绘制在完成曲线绘制之后,会将当前画刷的颜色填充其内部
2 包括绘制矩形Rectangle,椭圆Ellipse,圆角矩形RoundRect,弧形区域Chord,扇形Pie,多边形Polygan/PolyPolygan

* Windows的窗口背景

1 Windows 绘画过程中采用层叠加方式,最上面一层的将覆盖其下面的区域的绘制内容
2 默认的绘制曲线间隙(绘制对象的背景)颜色是白色的
3 通过 Set/GetBkColor 设置或获取当前绘制对象的背景颜色
4 通过 Set/GetBkMode 设置或获取背景模式。如将模式改为透明,当前绘制对象的背景颜色将不会生效
5 通过 Set/GetROP2 设置或获取混合模式

* 多边形的填充模式
通过SetPolyFillMode可以将填充模式设置为交替式(默认)或螺旋式,两者的区别是——
交替式填充机理是:从客户区的左向右画一条线段,与奇数边相交的右方闭合区域填充,偶数变相交的闭合区域不填充
螺旋式填充机理是:如果内部的闭合区域在使用 Polygan 作图过程中是可以单向一笔完成的即进行填充,否则不填充



三 绘画API函数
* 点  —— SetPixel(hdc, 10, 10, RGB(0,0,255)) 或 SetPixelV(hdc, 10, 10, RGB(0,0,255))

* 线段 —— MoveToEx(hdc, 100, 100, NULL) 配合 LineTo(hdc, 600, 100)

* 多条线段 —— Polyline(hdc, apt, NUM) 或 PolylineTo(hdc, apt, NUM) 或 PolyPolyline(hdc, apt, asz, NUM)

* Bezier曲线 —— PolyBezier(hdc, apt, 4) 或 PolyBezierTo(hdc, apt, 4)

* 矩形 —— Rectangle(hdc, 100, 100, 200, 200)

* 椭圆 —— Ellipse(hdc, 100, 100, 200, 200)

* 圆角矩形 —— RoundRect(hdc, 100, 100, 200, 200, 20, 30)

* 弧线 —— Arc(hdc, 100, 100, 200, 200, 150, 100, 50, 150)

* 弓形 —— Chord(hdc, 100, 100, 200, 200, 150, 100, 50, 150)

* 扇形 —— Pie(hdc, 100, 100, 200, 200, 150, 100, 50, 150)

* 闭合多边形 —— Polygan(hdc, apt, 4) 或 PolyPolygan(hdc, apt, asz, 3)



评分

参与人数 1鱼币 +6 收起 理由
小甲鱼 + 6

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 00:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表