第5章,[Win32 章节] :创建、选择和删除画笔
专栏导航上一篇第5章[Win32 章节] 使用现有画笔回到目录下一篇第5章[Win32 章节] 填充空隙本节前言对于本节所讲解的知识有可能你会需要时不时地参考本专栏的其它文章。真的遇到了需要参考之前的文章的知识点请你自行查阅。我呢也会提到一部分的参考课节。但是呢你不应该依赖于我的主动提及。最好呢你自己能够多去了解和查看本专栏目录。在上一节我们讲解了如何来使用系统备用画笔。本节我们来讲解如何来操作自定义画笔。本节内容来自于对佩措尔德教材的大段抄录。一. 本节内容尽管使用备用对象中的画笔非常方便但只能使用实心的黑色画笔、实心的白色画笔或者没有画笔三种情况。如果想要获得更丰富的效果则必须创建自己的画笔。这里是创建画笔的一般过程调用 CreatePen 或者 CreatePenIndirect 函数创建一个 “逻辑画笔”它只是说明你想要得到一个什么样的画笔。这些函数会返回一个逻辑画笔的句柄。然后需要调用 SelectObject 函数将画笔选入设备环境中。接着就可以使用这个新的画笔来绘制线条。一次只能有一支画笔被选入设备环境。释放设备环境之后或者将其他画笔选入设备环境之后需要调用 DeleteObject 函数来删除你创建的逻辑画笔。此后画笔的句柄不再有效。逻辑画笔是一个 “GDI 对象”一个程序可以创建 6 种 GDI 对象它是其中之一。其他五种分别是画刷、位图、区域、字体和调色板。除了调色板之外所有这些对象都通过 SelectObject 函数选入设备环境。下面三条规则控制画笔等 GDI 对象的使用。最终应当删除你所创建的所有 GDI 对象。当 GDI 对象被选入一个有效的设备环境时不要删除它。不要删除备用对象。这些规则都是有道理的。但是有时候有点棘手。下面我们将通过例子来帮助理解这些规则。CreatePen 函数的一般语法如下。hPen CreatePen (iPenStyle, iWidth, crColor);其中参数 iPenStyle 决定画笔绘制的是实线、虚线或者点线。这个参数可以使用定义在 WinGDI.h 头文件中的下列标识符。下面的图也显示了每种样式产生的线条。图1对于 PS_SOLID、PS_NULL 和 PS_INSIDEFRAME 样式参数 iWidth 表示画笔的宽度。当 iWidth 值为 0 时Windows 会把画笔的宽度设定为 1 个像素。这其实是一个很重要的知识点。以后我们还会学习映射模式的知识。在这里我们要求大家先有一个印象无论处于何种映射模式之下当 iWidth 值为 0 时Windows 都会把画笔的宽度设定为 1 个像素。至于何为映射模式我们以后会学习到的。此处我们要求大家有个印象。备用画笔总是一个像素宽。如果指定使用虚线或点线样式同时把画笔宽度设置为大于 1 个像素那么 Windows 会使用实心的画笔来代替。CreatePen 的参数 crColor 是一个 COLORREF 值它用来指定画笔的颜色。对所有的除了 PS_INSIDEFRAME 之外的画笔样式当将画笔选入到设备环境时Windows 将该颜色转换为设备所能表示的最接近的纯色。PS_INSIDEFRAME 画笔样式是唯一能够使用抖动色的画笔样式并且只有当画笔宽度大于 1 时才如此。PS_INSIDEFRAME 画笔样式用于填充区域的函数时有另外一个奇特之处。当使用非 PS_INSIDEFRAME 样式的画笔样式时如果用于绘制轮廓的画笔宽度大于 1 个像素那么画笔的中心会处于边界之上这样画出的轮廓线部分将会在边框之外。但是对于 PS_INSIDEFRAME 画笔样式整个轮廓线都会在边框内。举几个例子。假定我们分别用 PS_SOLID 和 PS_INSIDEFRAME 样式创建两个黑色的 6 像素宽度的画笔并且都去画同样的矩形。那么在 PS_INSIDEFRAME 样式里面所有的 6 像素画笔线条都位于边框之内。而在 PS_SOLID 样式里面有 3 像素的线条像素在边框内另外的 3 像素的线条像素在边框之外。再来假定我们分别用 PS_SOLID 和 PS_INSIDEFRAME 样式创建两个黑色的 7 像素宽度的画笔并且都去画同样的矩形。那么在 PS_INSIDEFRAME 样式里面所有的 7 像素画笔线条都位于边框之内。而在 PS_SOLID 样式里面有 4 像素的线条像素在边框之内另外的 3 像素的线条像素在边框之外。如果用两种样式创建 10 像素宽度的实线来绘制矩形那么在 PS_INSIDEFRAME 样式里面所有的 10 像素画笔线条像素都位于边框之内。而在 PS_SOLID 样式里面有 5 像素的线条像素在边框之内另外的 5 像素的线条像素在边框之外。如果用两种样式创建 11 像素宽度的实线来绘制矩形那么在 PS_INSIDEFRAME 样式里面所有的 11 像素画笔线条像素都位于边框之内。而在 PS_SOLID 样式里面有 6 像素的线条像素在边框之内另外的 5 像素的线条像素在边框之外。如果用两种样式创建 2nn 为大于或等于 1 的整数像素宽度的实线来绘制矩形那么在 PS_INSIDEFRAME 样式里面所有的 2n 像素画笔线条像素都位于边框之内。而在 PS_SOLID 样式里面有 n 像素的线条像素在边框之内另外的 n 像素的线条像素在边框之外。如果用两种样式创建 2n1n 为大于或等于 1 的整数像素宽度的实线来绘制矩形那么在 PS_INSIDEFRAME 样式里面所有的 2n1 像素的画笔线条像素都位于边框之内。而在 PS_SOLID 样式里面有 n1 像素的线条像素在边框之内另外的 n 像素的线条像素在边框之外。我想这么来解释你应该能明白 PS_INSIDEFRAME 样式与非 PS_INSIDEFRAME 样式在绘制矩形椭圆时在绘制外侧边缘的区别了吧。我们接着讲。也可以通过建立一个类型为 LOGPEN逻辑画笔的结构并调用 CreatePenIndirect 函数来建立一个画笔。如果你的程序在初始化时需要创建很多不同的画笔这种方法会很有效。为了使用 CreatePenIndirect 函数首先要定义一个类型为 LOGPEN 的结构体变量。LOGPEN logpen;这个结构有三个字段lopnStyle无符号整型或 UINT表示画笔样式lopnWidth一个 POINT 结构是以逻辑单位表示的画笔宽度还有 lopnColorCOLORREF表示画笔的颜色。Windows 仅使用 lopnWidth 结构中的 x 字段来设置画笔的宽度y 字段会被忽略。可以通过将该结构的地址传递到 CreatePenIndirect 函数来建立画笔。hPen CreatePenIndirect (logpen);注意CreatePen 和 CreatePenIndirect 函数不需要设备环境句柄。在调用 SelectObject 之前这些函数创建的逻辑画笔和设备环境没有任何联系。可以为几种不同的设备例如屏幕和打印机使用相同的逻辑画笔。这里给出创建、选择和删除画笔的一种方法。假定程序使用三种画笔宽度为 1 的黑色画笔、宽度为 3 的红色画笔和黑色的点线画笔。可以首先定义存储这些画笔的句柄的静态变量。static HPEN hPen1, hPen2, hPen3;在处理 WM_CREATE 消息时可以创建这三种画笔。hPen1 CreatePen (PS_SOLID, 1, RGB(0, 0, 0)); hPen2 CreatePen (PS_SOLID, 3, RGB(255, 0, 0)); hPen1 CreatePen (PS_DOT, 0, RGB(0, 0, 0));在处理 WM_PAINT 消息时或者在任何拥有有效的设备环境句柄时可以将其中任何一支画笔选入到设备环境并且使用它来绘制线条。SelectObject (hdc, hPen2); [画线函数] SelectObject (hdc, hPen1); [画线函数]在处理 WM_DESTROY 消息时可以删除这三种画笔。DeleteObject (hPen1); DeleteObject (hPen2); DeleteObject (hPen3);这是用于创建、选择和删除画笔最直接的办法。但是很显然程序必须知道需要使用什么样的画笔。因此可能需要在每个 WM_PAINT 消息处理时创建画笔并且调用 EndPaint 函数后删除它们。也可以在调用 EndPaint 函数前删除它们但是需要小心不要删除已被选入设备环境的当前画笔。可以随时创建画笔还可以将 CreatePen 和 SelectObject 调用组合到一条语句中。SelectObject (hdc, CreatePen (PS_DASH, 0, RGB(255, 0, 0)));现在在绘制直线时将使用一个红色的虚线画笔。红色虚线绘制完成后可以删除画笔。糟糕你没有保存画笔句柄怎么才能删除画笔呢前面介绍过SelectObject 函数将返回先前被选入设备环境的画笔句柄。也就是说可以通过将备用的 BLACK_PEN 选入到环境中来得到需要被删除的画笔句柄然后删除它。DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN)));下面给出另一种方法。当将一支画笔选入到一个新创建的设备环境时保存 SelectObject 返回的画笔句柄。hPen (HPEN) SelectObject (hdc, CreatePen (PS_DASH, 0, RGB(255, 0, 0)));hPen 究竟是什么呢如果这是在获得设备环境后第一次调用 SelectObject 函数hPen 函数就是 BLACK_PEN 的句柄。在这里为何要在 SelectObject 函数调用的左边写上强制类型转换代码 (HPEN) 呢其实道理和 GetStockObject 一样SelectObject 函数的返回值是一个句柄类型 HGDIOBJ 。如果不对 SelectObject 函数的返回值进行强制类型转换那么你说它返回的句柄类型是画笔句柄 HPEN 呢还是画刷句柄 HBRUSH 呢还是位图句柄 HBITMAP 呢在上面的代码块中为了明确地告诉 Windows我们要返回的是一个画笔句柄因此我们需要在 SelectObject 函数的左边加上强制类型转换代码 (HPEN) 。现在可以在同一条语句中选择该画笔到设备环境并且删除自己创建的画笔第二次 SelectObject 调用返回你创建的画笔的句柄。DeleteObject (SelectObject (hdc, hPen));如果有一个画笔的句柄LOGPEN 结构中各个字段成员的值就可以通过调用 GetObject 函数获得。GetObject (hPen, sizeof(LOGPEN), (LPVOID) logpen);如果需要获得当前被选入设备环境的画笔句柄则进行如下调用。hPen GetCurrentObject (hdc, OBJ_PEN);我们将在以后讨论另外一个画笔创建函数ExtCreatePen 。结束语本节内容有点长。好好学吧。专栏导航上一篇第5章[Win32 章节] 使用现有画笔回到目录下一篇第5章[Win32 章节] 填充空隙

相关新闻

开箱即用苹果检测数据集:YOLO/VOC/COCO三格式与实战教程

开箱即用苹果检测数据集:YOLO/VOC/COCO三格式与实战教程

简介:目标检测是计算机视觉的核心任务,其原理是通过算法定位并识别图像中的物体。这项技术的价值在于为自动驾驶、工业质检和智能安防等场景提供了关键的感知能力。在实际工程中,数据准备往往是项目成功的关键,涉及数据标注、格式…

2026/11/7 4:04:16 阅读更多 →
AI时代情绪管理:把焦虑转化为行动力的技术指南

AI时代情绪管理:把焦虑转化为行动力的技术指南

这次我们不聊具体的模型,不聊部署,也不聊参数。我们聊一个更底层的东西:在 AI 时代,一个人面对技术爆炸时最该管理的变量,不是工具,而是情绪。准确一点说,是焦虑和愤怒这两类情绪的选择问题。先…

2026/10/29 10:47:18 阅读更多 →
The Caretakers:本地AI服务守护、自动重启与批量任务管理工具

The Caretakers:本地AI服务守护、自动重启与批量任务管理工具

这次我们来看一个叫 The Caretakers 的项目。从项目名称和常见定位看,它不是单个 AI 模型,也不是某条工作流,而是一层“服务管理与守护层”。它解决的是本地部署之后最头疼的问题:WebUI 起来了没人盯、API 服务挂了没人拉、批量…

2026/11/4 17:12:21 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/6 15:21:35 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/6 9:29:27 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/6 22:01:11 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/6 22:01:11 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/6 8:08:42 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/6 22:01:09 阅读更多 →

日新闻

周新闻

月新闻