前言:
想在窗口上绘制出各种各样的图形,Windows给我们提供了大量的API函数,这些绘图函数种类很多,基本上能满足我们的绘图需求。要绘制出漂亮的图形,这时需要用到画笔和画刷了,简单来说,画笔是用来画线和边框的,那画刷就是用来填充那些封闭图形的。画笔能够控制线条的颜色、样式、大小等,画刷能够控制填充的类型、颜色、方式等。下面介绍画笔画刷的创建和使用,还有各种图形的绘制。颜色都用RGB进行设置。矩形、椭圆、弓形、扇形、多边形等这些是填充图形,都用当前的画笔画轮廓,用当前的画刷和多边形填充模式画填充。在绘制多条折线或多个多边形时,顶点数组定义时,需要注意:顶点是连续定义的,也按一笔画绘制。


一、画笔和画刷

画笔画刷的使用步骤:(两者使用一致)
1.创建画笔或画刷。
2.选取画笔或画刷(选入设备环境,记得保留先前画笔和画刷)(用SelectObject,此函数返回值为先前画笔画刷)。
3.使用绘图函数进行绘图。
4.删除自己所创建的画笔或画刷。(用DeleteObject)


画笔:

画笔的不同创建:

1.GetStockObject函数

GetStockObject 函数用于获得 Windows 预设的画笔、画刷、字体或者调色板的句柄。 (样式获取点击上面链接即可)

HGDIOBJ GetStockObject(  _In_  int fnObject);//指定待获取对象的类型

注意: 当样式为DC_BRUSH或DC_PEN时,需要调用 SetDCBrushColor 或 SetDCPenColor 函数可以修改该值的颜色,将当前设备上下文环境(DC)的笔颜色设置为指定颜色值。

2.CreatePen函数

CreatePen是指定的样式、宽度和颜色创建画笔。返回画笔HPEN

HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor);//样式、笔宽、颜色
Style 参数可选值: 含义
PS_SOLID = 0 实线
PS_DASH = 1 段线; 要求笔宽<=1
PS_DOT = 2; 点线; 要求笔宽<=1
PS_DASHDOT = 3 线、点; 要求笔宽<=1
PS_DASHDOTDOT = 4 线、点、点; 要求笔宽<=1
PS_NULL = 5; 不可见
PS_INSIDEFRAME = 6 实线; 但笔宽是向里扩展

3.CreatePenIndirect函数

CreatePenIndirect,根据指定的LOGPEN结构创建,这个结构与CreatePen函数的参数非常接近.

画笔使用实例:

HPEN hpen = CreatePen(PS_SOLID,0,RDB(255,0,0)); //创建 一条红色实线
HPEN oldhpen = SelectObject(hdc,hpen); // 画笔选入设备环境,并保留先前画笔
MoveToEx(hdc,0,0,NULL);  //画一条直线
LineTo(hdc,100,100);
SelectObject(hdc,oldhpen); // 恢复先前画笔
DeleteObject(hpen); // 删除创建画笔hpen

画刷:

画刷的不同创建:

1. 实心画刷CreateSolidBrush函数

HBRUSH CreateSolidBrush(COLORREF clrref);// 参数为填充颜色RGB的值

CreateSolidBrush函数,该函数创建一个具有指定颜色的逻辑刷子。画笔可以随后被选为任何设备上下文的当前刷子。

2. 阴影画刷CreateHatchBrush函数

HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);// fnStyle:指定刷子的阴影样式// cirref:指定用于阴影的刷子的前景色
样式 说明
HS_BDIAGONAL 表示45度向上,从左至右的阴影(/)
HS_CROSS 水平和垂直交叉阴影(+++++)
HS_DIAGCROSS 45度交叉阴影(XXXXX)
HS_FDIAGONAL 45度向下,自左至右阴影(\\\)
HS_HORIZONTAL 水平阴影(-----)
HS_VERTICAL 垂直阴影

3. CreateBrushIndirect函数

HBRUSH CreateBrushlndirect(CONST LOGBRUSH *lplb);// LOGBRUSH结构体

CreateBrushIndirect,可以创建具有指定风格、颜色和模式的逻辑刷子。
LOGBRUSH结构体

画刷使用实例:

HBRUSH hbrush = CreateSolidBrush(RGB(0,255,0)); // 创建一个绿色实心画刷
HBRUSH oldhbrush = SelectObject(hdc,hbrush); // 选入设备环境,并保留先前画刷
Rectangle(hdc,100,100,200,200); // 绘制一个矩形
SelectObject(hdc,oldhbrush); // 恢复画刷
DeleteObject(hbrush); // 删除创建画刷

二、绘图

1. 一个点的绘制

API函数:

绘制:

COLORREF SetPixel(HDC hdc, //DC句柄int X, //x坐标int Y, //y坐标COLORREF crColor ); // 点的颜色

获取:

 COLORREF GetPixel(HDC hdc,   //DC句柄int XPos,  //x坐标int nYPos ); //y坐标
// 返回指定坐标位置的点的颜色

2. 直线的绘制

API函数:
如果无MoveToEx,直线默认起点为原点(0,0);GetCurrentPositionEx函数能够获取当前位置。

BOOL MoveToEx(  // 移动当前位置HDC hdc,     // 句柄int X,     // 起点X坐标int Y,     // 起点Y坐标LPPOINT lpPoint );  // 一个指向POINT结构的指针,用来存放上一个点的位置,若此参数为NULL,则不保存上一个点的位置。
BOOL LineTo(HDC hdc,    //  句柄int nXEnd,  //  终点X坐标int  YEnd   //  终点Y坐标
);

3. 折线的绘制

API函数:
PolylineTo 与Polyline类似, PolylineTo的不同就是:在绘制折线前,会将当前位置连一根线到折线的第一个顶点。
一条折线的绘制:

 BOOL Polyline( HDC hdc,             // DC句柄CONST POINT *lppt,   // 顶点的坐标数组int cPoints );       // 顶点的个数

多条折线的绘制:

 BOOL PolyPolyline( HDC hdc,   // 句柄CONST POINT *lppt,   // 所有点的数组(按顺序)CONST DWORD *lpdwPolyPoints ,// 每条顶点个数的数组DWORD cCount );   // 折线的条数

4. 贝塞尔曲线的绘制

API函数:
4个点: 1和4是端点,2.3点是控制点
7个点: 1.4.7是端点,其余是控制点

BOOL PolyBezier(HDC hdc,           // 句柄CONST POINT *lppt, // 点数组,最少4个点DWORD cPoints );   // 点的数量

5. 矩形的绘制

API函数:
普通矩形绘制:

BOOL RoundRect( HDC hdc,int nLeftRect,    // 左上X坐标int nTopRect,     // 左上Y坐标int nRightRect,   // 右下X坐标int nBottomRect); // 右下Y坐标

圆角矩形绘制:
圆角的生成是由椭圆的弧调节的。

BOOL RoundRect( HDC hdc,int nLeftRect,   // 左上X坐标int nTopRect,    // 左上Y坐标int nRightRect,  // 右下X坐标int nBottomRect, // 右下Y坐标int nWidth,      // 生成圆角的椭圆的宽度int nHeight );   // 生成圆角的椭圆的高度

6. 椭圆和圆的绘制

API函数:
椭圆和圆由外切矩形控制。

BOOL Ellipse( HDC hdc,int nLeftRect,    // 外切矩形左上X坐标int nTopRect,     // 外切矩形左上Y坐标int nRightRect,   // 外切矩形右下X坐标int nBottomRect); // 外切矩形右下Y坐标

7. 圆弧的绘制

API函数:
Arc函数: 可以使用SetArcDirection函数,设置Arc函数切割方向,顺时针和逆时针。这里所说的切割半径坐标意思是说,此坐标与椭圆中点的连线为半径,两条半径之间形成弧。

 BOOL Arc( HDC hdc, int nLeftRect,   // 外切矩形的坐标int nTopRect,    // 外切矩形的坐标int nRightRect,  // 外切矩形的坐标int nBottomRect, // 外切矩形的坐标int nXStartArc,  // 起始切割半径的X坐标int nYStartArc,  // 起始切割半径的Y坐标int nXEndArc,    // 终止切割半径的X坐标int nYEndArc );  // 终止切割半径的X坐标

AngleArc函数: 直线连弧绘制函数,需要注意的 ,会与当前位置连接起来。

BOOL AngleArc( HDC hdc,int X,          // 圆心的X坐标int Y,          // 圆心的Y坐标DWORD dwRadius,    // 圆的半径FLOAT eStartAngle, // 开始角度FLOAT eSweepAngle ); // 夹角

8. 弓形弦的绘制

API函数:
填充图形,弧的首尾相连形成弓形。

BOOL Chord( HDC hdc, int nLeftRect,   // 外切矩形左上X坐标int nTopRect,    // 外切矩形左上Y坐标int nRightRect,  // 外切矩形右下X坐标int nBottomRect, // 外切矩形右下Y坐标int nXRadial1,   // 切割起始半径X坐标int nYRadial1,   // 切割起始半径Y坐标int nXRadial2,   // 切割终止半径X坐标int nYRadial2 ); // 切割终止半径Y坐标

9. 扇形饼的绘制

API函数:

 BOOL Pie( HDC hdc, int nLeftRect,   // 外切矩形左上X坐标int nTopRect,    // 外切矩形左上Y坐标int nRightRect,  // 外切矩形右下X坐标int nBottomRect, // 外切矩形右下Y坐标int nXRadial1,   // 切割起始半径X坐标int nYRadial1,   // 切割起始半径Y坐标int nXRadial2,   // 切割终止半径X坐标int nYRadial2 ); // 切割终止半径Y坐标

10. 多边形的绘制

在多边形绘制这里会有用到多边形填充模式,填充模式一共有两种:ALTERANATE(交替式,默认)WINDING(螺旋式)。用SetPolyFillMode函数设置
API函数:
一个多边形的绘制:

 BOOL Polygon( HDC hdc,CONST POINT *lpPoints, // 多边形的顶点int nCount );          // 顶点的数量

多个多边形的绘制:
第二个参数中各多边形是连续定义的,每个多边形通过画一条从最后中一个顶点到第一个顶点的线段而自动闭合起来,每个顶点应被定义一次。

BOOL PolyPolygon( HDC hdc,CONST POINT *lpPoints, // 顶点的POINT结构数组的指针CONST INT *lpPolyCounts, //整数数组的指针,每个整数指定//相应多边表的点数,每个整数必须大于等于2int nCount); // 指定多边形的总个数

三、代码(绘制以上所有图形)

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {PAINTSTRUCT ps;HDC hdc;HPEN hpen1, oldhpen, hpen2, hpen3, hpen4, hpen5,hpen;HBRUSH hbrush1, oldhbrush, hbrush2, hbrush3, hbrush4, hbrush5,hbrush6;static int xClient, yClient;static POINT apt[5] = { 90,50,110,10,130,50,150,10,180,50 };//5个点static POINT capt[] = { 200, 50, 230, 10, 260, 50, 290, 10, 310, 50,200, 100, 230, 60, 260, 100, 290, 60, 310, 100,200, 150, 230, 110, 260, 150, 290, 110, 310, 150 };static DWORD asz[] = { 5,5,5 };static POINT bapt[4] = { 350,50,350,80,370,50,450,10 };//4个点switch (Message){case WM_SIZE:{xClient = LOWORD(lParam);yClient = HIWORD(lParam);break;}case WM_PAINT:{hdc = BeginPaint(hwnd, &ps);//还可以使用CreatePenIndirect创建画笔//画一个红色点SetPixel(hdc, 20, 50, RGB(255, 0, 0));//画一条直线hpen1 = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));//实线oldhpen = (HPEN)SelectObject(hdc, hpen1);//选入画笔MoveToEx(hdc, 30, 50, NULL);LineTo(hdc, 70, 50);SelectObject(hdc, oldhpen);//恢复先前画笔DeleteObject(hpen1);//记得自创画笔一定删除//画一条5个点折线hpen2 = CreatePen(PS_DASH, 1, RGB(255, 255, 0));//段线oldhpen = (HPEN)SelectObject(hdc, hpen2);//选入画笔Polyline(hdc, apt, 5); //其后缀不带To,表示该函数不使用也不改变设备当前位置SelectObject(hdc, oldhpen);//恢复先前画笔DeleteObject(hpen2);//记得自创画笔一定删除//画3条折线hpen3 = CreatePen(PS_DASHDOT, 1, RGB(255, 0, 255));//线点SetBkColor(hdc, RGB(0, 0, 222));// 设置当前背景颜色oldhpen = (HPEN)SelectObject(hdc, hpen3);//选入画笔PolyPolyline(hdc, capt, asz, 3);SelectObject(hdc, oldhpen);//恢复先前画笔DeleteObject(hpen3);//记得自创画笔一定删除//画贝塞尔曲线(最少需要4个点)hpen4 = (HPEN)GetStockObject(BLACK_PEN);//获得Windows预设的画笔画刷oldhpen = (HPEN)SelectObject(hdc, hpen4);//选入画笔PolyBezier(hdc, bapt, 4);// 4个点: 1和4是端点, 2.3点是控制点// 7个点 : 1.4.7是端点, 其余是控制点SelectObject(hdc, oldhpen);//恢复先前画笔DeleteObject(hpen4);//记得自创画笔一定删除//画无边框矩形hbrush1 = CreateSolidBrush(RGB(0, 255, 0)); //绿色实心画刷hpen = CreatePen(PS_NULL, 1, 0);  //创建空画笔oldhpen=(HPEN)SelectObject(hdc, hpen);  //重点:填充图形的边框由当前画笔绘制oldhbrush=(HBRUSH)SelectObject(hdc, hbrush1);//选入环境句柄Rectangle(hdc, 10, 80, 70, 140);SelectObject(hdc, oldhpen);SelectObject(hdc, oldhbrush);DeleteObject(hbrush1);//删除画刷//圆角矩形SetBkColor(hdc, RGB(0, 0, 0));// 设置当前背景颜色hbrush2=CreateHatchBrush(HS_FDIAGONAL,RGB(255,255,0));//创建画刷oldhbrush = (HBRUSH)SelectObject(hdc, hbrush2);//选入设备环境RoundRect(hdc, 90, 80, 150, 140,20,20);//画图SelectObject(hdc,oldhbrush);//恢复先前画刷DeleteObject(hbrush2);//删除画刷//椭圆SetBkColor(hdc, RGB(222, 0, 0));// 设置当前背景颜色hbrush3=CreateHatchBrush(HS_CROSS,RGB(255,255,0));oldhbrush = (HBRUSH)SelectObject(hdc, hbrush3);Ellipse(hdc, 10, 160, 70, 200);SelectObject(hdc,oldhbrush);DeleteObject(hbrush3);//普通弧SetDCPenColor(hdc, RGB(255, 0, 255));  //设置句柄颜色hpen5 = (HPEN)GetStockObject(DC_PEN);oldhpen = (HPEN)SelectObject(hdc, hpen5);Arc(hdc, 90, 160, 150, 200, 90, 180, 150, 170);SelectObject(hdc, oldhpen);DeleteObject(hpen5);//圆弧MoveToEx(hdc, 190, 200, NULL);AngleArc(hdc, 190, 200,30,10,90);  //终点会与当前位置连接起来//弓形、弦hbrush4 = CreateSolidBrush(RGB(155, 155, 155));oldhbrush = (HBRUSH)SelectObject(hdc, hbrush4);Chord(hdc, 240, 160, 300, 240, 270, 180, 290, 230);SelectObject(hdc, oldhbrush);DeleteObject(hbrush4);//扇形SetBkColor(hdc, RGB(35, 55, 111));// 设置当前背景颜色hbrush5 = CreateHatchBrush(HS_HORIZONTAL, RGB(0, 255, 0));oldhbrush = (HBRUSH)SelectObject(hdc, hbrush5);Pie(hdc, 330, 160, 370, 220, 333, 26, 370, 220);SelectObject(hdc, oldhbrush);DeleteObject(hbrush5);//绘制多边形,POINT dot[5]{100,300,200,300,125,350,150,250,175,350};//按笔画顺序绘制5个点SetPolyFillMode(hdc, ALTERNATE);//设置填充模式hbrush6 = CreateSolidBrush(RGB(0, 255, 0)); //绿色实心画刷oldhbrush = (HBRUSH)SelectObject(hdc, hbrush6);Polygon(hdc, dot, 5);//绘制多边形SelectObject(hdc, oldhbrush);DeleteObject(hbrush6);EndPaint(hwnd, &ps);break;}case WM_DESTROY: {PostQuitMessage(0);break;}default:return DefWindowProc(hwnd, Message, wParam, lParam);}return 0;
}

留言:
我妈今天早上六点的样子就坐车出去了,当时还没睡醒,模模糊糊的,我妈是趁着我们放假在家,回来看看我们,她说她很想我们了。妈在前几天就跟我说,你车票买好、怎么坐车去车站、你衣服鞋子什么的自己整理好、自己在家去买菜吃、千万不能饿肚子啊,每天早点睡、不要玩手机到太晚,有时间就多出去走走,我想说有妈是天底下最幸福的事了。妈在家时,我真的是每天使劲玩,等着吃饭就好了,妈这出去了,心里总感觉少了什么,有点小不舒服,哈哈哈,可能又要自己动手煮饭了吧。以前小时候不怎么懂事,在家经常让我妈担心,有点后悔,现在我只希望我妈身体健健康康的、平安就好。当然,我爸也是一样,为我们的生活和成长,付出了他的全部。父爱同母爱一样的无私,他不求回报;父爱是一种默默无闻,寓于无形之中的一种感情,只有用心的人才能体会。在父母的眼中,孩子常是自我的一部分,子女是他理想自我再来一次的机会。我现在能做的就是让自己成为一个他们自豪的人!

Win32绘图总结篇(点、直线、折线、贝塞尔曲线、矩形、椭圆、圆弧、弓形、扇形、多边形等)相关推荐

  1. VS2019MFC进行无预览简单绘图:直线,画笔,画刷,矩形,椭圆

    1.MFC常用绘图函数 CreatePen 创建画笔:属性:线型.宽度.颜色 CreateSolidBrush 创建画刷,填充封闭图形 SetPixel 绘制像素点,返回RGB值 SetPixelV ...

  2. 几何向量:贝塞尔曲线

    刚好又用上了二维贝塞尔曲线,顺便写一篇博客. 贝塞尔曲线算是二维开发中偶尔会碰到的,我依稀记得我第一次认识贝塞尔曲线是选修photoshop课程用钢笔工具拉曲线.工作中第一次用贝塞尔计算,是做手游的时 ...

  3. 有理贝塞尔曲线(Rational Bezier Curves)

    有理贝塞尔曲线(Rational B′ezier Curves) 1.定义 有理贝塞尔曲线(Rational B′ezier Curves) 控制点为 b0,⋯,bnb_0,\cdots,b_n 的n ...

  4. 贝塞尔曲线(B′ezier)基础

    贝塞尔曲线是计算机图形学和计算机辅助设计中最重要的曲线之一. 在机器人(特别是移动机器人)轨迹规划中,经常用到贝塞尔曲线. 贝塞尔曲线是一种特殊的多项式曲线,n 阶贝塞尔曲线由 n+1 个控制点来确定 ...

  5. unity 控制点 贝塞尔曲线_在Unity中使用贝塞尔曲线(转)

    鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...

  6. View系列:贝塞尔曲线专栏:绘制二阶贝塞尔曲线(二)

    1:Android贝塞尔曲线Api 作用 相关Api 备注 移动起点 moveTo 移动下一次操作的起点位置 连接直线 lineTo 添加上一个点到当前点的直线Path 贝塞尔曲线 qyadTo / ...

  7. 贝塞尔曲线之购物车动画效果

    Question 贝塞尔曲线是什么? 贝塞尔曲线可以做什么? 怎么做? What is it ? 贝塞尔曲线在百度定义是贝塞尔曲线(Bézier curve),又称 贝兹 曲线或贝济埃曲线,是应用于二 ...

  8. Android绘图最终篇之大战贝塞尔三次曲线

    零.前言 1.可以说贝塞尔曲线是一把 "石中剑",能够拔出它,会让你的绘图如虎添翼. 2.今天要与贝塞尔曲线大战三百回合,将它加入我的绘图大军麾下. 3.自此Android绘图五虎 ...

  9. Path之贝塞尔曲线 进阶篇

    一.Path常用方法表 为了兼容性(偷懒) 本表格中去除了在API21(即安卓版本5.0)以上才添加的方法.忍不住吐槽一下,为啥看起来有些顺手就能写的重载方法要等到API21才添加上啊.宝宝此刻内心也 ...

最新文章

  1. c++ 暂停功能_app下载功能背后的逻辑
  2. 黑盒测试和白盒的区别,有哪些常见的白盒黑盒测试方法
  3. 程序员面试题精选100题(56)-C/C++/C#面试题(4)
  4. TensorFlow MNIST CNN LeNet5模型
  5. Visual Studio的调试技巧
  6. Python档案袋( 面向对象 )
  7. 收藏 | 循环神经网络 RNN 详细图解!
  8. C#_基础,初始化器
  9. docker安装chirpstack_用docker-compose快速部署ChirpStack
  10. 贺利坚老师汇编课程47笔记:jmp short和jmp near ptr和jmp far ptr
  11. Fragment 源码解析add()和replace()方法
  12. Atitit 提升记忆效率 有损压缩原理总结 目录 1. 常见方法 1 1.1. 抽象化提升一层 概念化 1 1.2. 骨架 ,目录化 大纲化 归纳整理 1 1.3. 提取关键词 ,摘要 ,
  13. MacBook 右键查询英文查词无法翻译成中文
  14. “WebProxyWrapper”的对象强制转换为类型“System.Net.WebProxy
  15. MySQL 支持表情字符
  16. C语言:一个非常完美MAX宏的诞生及5次进化
  17. Excel单元格设置下拉选项
  18. [book]《岩田先生》
  19. 浅谈单片机、ARM和DSP的异同
  20. Set集合的概述及特点

热门文章

  1. Python爬虫入门教程31:爬取猫咪交易网站数据并作数据分析
  2. 【利用二进制位做输出】抖音上“输出方块8”的看法
  3. jupyter中怎么把图形在一个单独的窗口显示_【一点小套路】手把手从安装Python到完成第一个数据分析项目...
  4. Unity中的资源管理-几种常见的序列化方式
  5. 《冰封王座》世界魔兽界十大叱咤风云人物
  6. 解读照明设备中国能效标示认证流程
  7. 提取数据_基于众包的可视化图表数据提取
  8. 计算机三维动画学什么,计算机三维动画设计教学大纲..doc
  9. BZOJ 1193 HNOI2006 马步距离
  10. c语言求商品的总价程序,C语言简单问题,求商品总价。。在线急等大神解答