GDI基础函数使用绘制线条和图形
1、
绘制一个像素点:SetPixel()。
绘制直线:MoveTo(),LineTo()。
绘制多个首尾相连的线:Polyline()。
绘制矩形:FrameRect(),Rectangle(),FillRect() ,FillSolidRect()。
绘制一个四个角是弧形的矩形:RoundRect()。
绘制圆形或椭圆:Ellipse()。
绘制弧线:Arc(),ArcTo()。
绘制多边形:Polygon()。
创建一个矩形区域:CreateRectRgn()
创建一个圆型或椭圆区域:CreateEllipticRgn()
合并两个区域:CombineRgn()
填充指定的区域:FillRgn()
绘制指定区域的边框:FrameRgn()。
绘制饼形图:Pie()。
对矩形或指定区域的像素颜色进行反转:InvertRect()、InvertRgn()。
以上函数如果没有参数用来指定的话则使用的是当前默认画笔和画刷,可以使用CDC::SelectObject()来改变当前画笔和画刷,而如果只是想改变画笔或画刷的颜色则使用SetDCPenColor()、SetDCBrushColor()即可。
Polyline(const POINT* lpPoints, int nCount)中的lpPoints是要连结的那些点的数组,nCount为点的个数。如果nCount为2的话其相当于MoveTo()和LineTo()绘制一条直线。
FrameRect()用来绘制一个矩形边框,边框颜色由其参数指定,矩形内部是透明的,相当于使用了透明画刷;
Rectangle()用来绘制带边框的矩形,边框颜色和类型使用当前DC默认画笔类型,矩形内部使用当前DC默认画刷,如果想要改变边框或画刷的颜色、类型,使用SelectObject()将指定画笔或画刷选入当前DC。
FillRect()用来绘制一块无边框的矩形,矩形内部使用指定画刷颜色或类型。
FillSolidRect()与FillRect类似,FillSolidRect只能使用固体色(COLORREF类型),但FillRect使用画刷,因此可以为矩形填充固体色、抖动色、阴影、位图或使用调色板,而且FillSolidRect通常比FillRect快。
以下为使用FrameRect、Rectangle、FillRect的对比:
Arc()与ArcTo()的区别在于,Arc函数只是绘出给定的弧线,不会对画笔位置产生影响;而ArcTo函数在工作时将会从画笔原来所在点开始绘制一条直线到弧线的开始点,绘画弧线完成后还会将画笔移动到弧线的终点,从而对画笔位置造成影响。下面是网上找的两个示例图:
下面是一个合并两块矩形区域的例子:
case WM_PAINT:{PAINTSTRUCT ps;HDC hdc = BeginPaint(hWnd, &ps);// TODO: 在此处添加使用 hdc 的任何绘图代码...//创建两个方形区域。HRGN rgnRect1 = CreateRectRgn(10, 10, 100, 100);HRGN rgnRect2 = CreateRectRgn(50, 50, 200, 200);//合并两个区域。 CombineRgn(rgnRect1, rgnRect1, rgnRect2, RGN_XOR);//创建画刷。HBRUSH hbrush = CreateSolidBrush(RGB(255, 0, 0));//填充区域。 FillRgn(hdc, rgnRect1, hbrush);//删除画刷. DeleteObject(hbrush);//删除创建的两个区域. DeleteObject(rgnRect1);DeleteObject(rgnRect2);EndPaint(hWnd, &ps);break;}
2、
画笔CPen、画刷CBrush、字体CFont、位图CBitmap、调色板CPalette等都是GDI对象,通常在函数没有参数指定的情况下我们使用的是DC当前默认GDI对象,如在使用MoveTo/LineTo画线的时候线条的颜色是黑色实线,即当前DC默认画笔为黑色实线,使用Rectangle()画矩形的时候使用的是默认的白色画刷。我们可以使用CDC::SelectObject()来改变DC的默认GDI对象,该函数返回DC中被替换的GDI对象,我们应该保存这个旧的GDI对象,当我们不需要使用新的GDI对象的时候再使用CDC::SelectObject()将旧的GDI对象恢复到DC中。
还可以通过HGDIOBJ GetStockObject(int i)函数来获得系统标准的GDI对象,其参数可以为:NULL_BRUSH透明(空)画刷、SYSTEM_FONT系统字体、DEFAULT_PALETTE缺省调色板等。GetStockObject返回的类型为HGDIOBJ,所以在使用的时候还应该将其返回值强制转换为我们所使用的GDI句柄类型,如HBRUSH、HFONT、HPALETTE等。还可以使用各GDI类型的静态成员函数FromHandle()由这个GDI句柄获得其对象指针。比如CBrush::FromHandle()可以由画刷句柄获得画刷对象的指针,它是一个静态成员函数。同理,对于CPen、CFont、CBitmap、CPalette等GDI对象,甚至CDC和CWnd等也包含静态成员函数FromHandle()。实际上,MFC对各种包含内核对象的封装类都有FromHandle(HANDLE h)方法。
CDC类的成员函数GetSafeHdc(void)可以获得CDC对象的句柄。
下面是一个使用例子,它先将当前DC画刷设置为了系统透明画刷再使用Rectangle()来画矩形:
HBRUSH hNull_Brush = (HBRUSH)GetStockObject(NULL_BRUSH);CBrush *pBrush = CBrush::FromHandle(hNull_Brush);CBrush* pOldBrush = dc.SelectObject(pBrush);CRect rect(0, 0, 100, 100);dc.Rectangle(&rect);dc.SelectObject(pOldBrush);pBrush->DeleteObject();
与前面的例子对比就可以看出效果:
3、
CPen是画笔类,用来在DC上完成绘制线条的任务,常用的构造函数:
CPen(Int style,int width ,COLORREF color);
style:画笔样式,可以为以下样式:
PS_SOLID 实线
PS_DASH 虚线,该值只有当画笔宽度等于1个设备单位或更小时才有效
PS_DOT 点线,该值只有当画笔宽度等于1个设备单位或更小时才有效
PS_DASHDOT 点和虚线交替,该值只有当画笔宽度等于1个设备单位或更小时才有效
PS_DASHDOTDOT 双点线和虚线交替,该值只有当画笔宽度等于1个设备单位或更小时才有效
PS_NULL 空画笔
PS_GEOMETRIC 几何画笔
.......
width:画笔宽度。
color:画笔颜色。
如果CPen在定义的时候没有被初始化,那么在使用之前应该调用其以下的初始化函数来进行初始化。
CreatePen()用指定的样式、宽度、颜色初始化画笔。
CreatePenIndirect()用结构LOGPEN 中指定的风格初始化画笔。
绘制连续曲线的例子:
void CMFC_testDlg::OnMouseMove(UINT nFlags, CPoint point) {// TODO: 在此添加消息处理程序代码和/或调用默认值if(nFlags == MK_LBUTTON)//鼠标左键按下标志 {CClientDC dc(this);CPen pen(PS_DOT, 1, RGB(255,0,0));//创建一个虚线线条,宽度为1,红色的画笔对象 CPen* pOldPen = dc.SelectObject(&pen);//将画笔对象选入到设备描述表中 dc.MoveTo(m_ptOrigin);dc.LineTo(point);m_ptOrigin = point;//修改线段的起点 dc.SelectObject(pOldPen);//恢复设备描述表 pen.DeleteObject(); }CDialogEx::OnMouseMove(nFlags, point); }
CDC::SetROP2(int nDrawMode)用来设置画笔绘画的模式,其参数可以为R2_NOTXORPEN、R2_NOT等绘图模式。R2_NOTXORPEN绘图模式就是先把画笔颜色与屏幕颜色异或,异或之后再取反最后得到一个颜色值显示在屏幕上,而这种做法就会产生一个效果:比如用画笔画了一条线,然后再用画笔在相同的位置画这条线就会擦除原来画的线。R2_NOT绘画模式同样有在同一个地方画两次相当于什么都没画的功能,不过R2_NOT绘画模式第一次画的时候显示颜色并不是你选定的画笔颜色,而是系统默认画笔颜色。
所以SetROP2()可以用来当做橡皮筋来使用,eg:
void Cmfc_testDlg::OnMouseMove(UINT nFlags, CPoint point) {// TODO: 在此添加消息处理程序代码和/或调用默认值if(nFlags == MK_LBUTTON){CClientDC dc(this);int oldmode=dc.SetROP2(R2_NOTXORPEN);//可以注释此行查看不同的效果CPen pen(PS_SOLID, 2, RGB(255,0,0)), *oldpen;oldpen = dc.SelectObject(&pen);//先抹去上次的线 dc.MoveTo(m_ptOrigin);dc.LineTo(m_ptEnd);m_ptEnd=point;//画线 dc.MoveTo(m_ptOrigin);dc.LineTo(m_ptEnd);dc.SelectObject(oldpen);dc.SetROP2(oldmode);ReleaseDC(&dc);}CDialogEx::OnMouseMove(nFlags, point);//CDC::SelectObject() SetDCPenColor()、SetDCBrushColor() }void Cmfc_testDlg::OnLButtonDown(UINT nFlags, CPoint point) {// TODO: 在此添加消息处理程序代码和/或调用默认值m_ptOrigin = m_ptEnd = point; CDialogEx::OnLButtonDown(nFlags, point); }
4、
CBrush为画刷类,画刷通常用来填充一块区域,可以为普通固体色画刷,位图画刷,阴影线画刷等。常用的构造函数:
CBrush( COLORREF crColor ); //普通画刷
CBrush( int nIndex, COLORREF crColor ); //阴影线画刷
CBrush( CBitmap* pBitmap ); //位图画刷
crColor:画刷或阴影线的颜色
nIndex:阴影线的风格,有以下风格可选:
HS_HORIZONTAL 水平的阴影线
HS_VERTICAL 垂直的阴影线
HS_CROSS 水平和垂直方向以网格线作出阴影
HS_BDIAGONAL 45度的向下影线(从左到右)
HS_FDIAGONAL 45度的向上阴影线(从左到右)
HS_DIAGCROSS 45度的网格线阴影
同CPen一样,如果CBrush在定义的时候没有被初始化,那么在使用之前应该调用其以下的初始化函数来进行初始化:
CreateSolidBrush() 用指定的颜色初始化画刷。
CreateHatchBrush() 用指定的阴影线初始化画刷。
CreateBrushIndirect() 用结构LOGBRUSH中指定的风格、颜色和模式初始化画刷。
CreatePatternBrush() 用位图指定的模式初始化画刷。
CreateDIBPatternBrush() 用独立于设备的位图(DIB)初始化画刷。
CreateSysColorBrush() 创建一个使用系统缺省颜色的画刷。
使用阴影线画刷:
CPaintDC dc(this);CRect rect(10, 10, 100, 100);CBrush brush(HS_HORIZONTAL, RGB(255,0,0));dc.FillRect(&rect, &brush);CRect rect2(120, 10, 210, 100);CBrush brush2(HS_CROSS, RGB(255,0,0));dc.FillRect(&rect2, &brush2);CRect rect3(230, 10, 320, 100);CBrush brush3(HS_BDIAGONAL, RGB(255,0,0));dc.FillRect(&rect3, &brush3);brush.DeleteObject();
使用位图画刷:
//使用位图画刷来填充一块矩形区域CClientDC dc(this);CBitmap bitmap;bitmap.LoadBitmapW(IDB_BITMAP1);//初始化位图对象 CBrush brush(&bitmap);//构造位图画刷 CRect rect(10, 10, 100, 100);dc.FillRect(&rect, &brush);bimap.DeleteObject();
如果在绘图过程中要经常改变DC中的画刷或画笔得颜色,可以使用SetDCBrushColor()、SetDCPenColor()函数来改变DC的画刷或画笔的颜色,在使用这两个函数之前要先将系统画刷DC_BRUSH或画笔DC_PEN选到DC中去:
CPaintDC dc(this);dc.SelectObject(GetStockObject(DC_BRUSH));dc.SelectObject(GetStockObject(DC_PEN));//画圆,边框设为蓝色,内部为红色dc.SetDCPenColor(RGB(0,0,255));dc.SetDCBrushColor(RGB(255,0,0));dc.Pie(35,320,300,600,56,470,60,360);//画饼,边框为红色,内部为蓝色dc.SetDCPenColor(RGB(255,0,0));dc.SetDCBrushColor(RGB(0,0,255));dc.Ellipse(35, 100, 235, 300);
5、
CPen、CBrush、CBitmap、CFont等GID对象在使用结束后应该调用DeleteObject()函数用来释放相关资源,而且只有这样才能重新初始化使用。我觉得MFC中的GDI对象会在析构的时候自动调用DelectObject(),win32的话必须显示调用DelectObject()防止内存泄露,所以用完之后再delete是一个好习惯。关于CFont和CBitmap这两个GDI对象会在下面的文章中详解。
6、
Windows中显示是基于设备环境(DC)的,在使用GDI函数之前必须先获得窗口的DC。在Win32 SDK中绘图的话需要调用GetDC()(WM_PAINT消息响应代码块中为BeginPaint)获得指定窗口的DC,绘制结束后还要调用ReleaseDC()(EndPaint())来释放DC资源。MFC的设备环境类CDC封装了窗口的DC对象和绘图所需要的所有函数。CClientDC、CWindowDC、CPaintDC都是从CDC类派生而来,只要在初始化的时候传入窗口的指针那么就可以通过这些对象的方法来方便的对窗口进行绘制等操作,而且DC资源释放会在对象的析构函数中自动执行。还有一个CMetaFileDC类,它对图像的保存比像素更精确,因而往往在要求较高的场合下使用,例如AutoCAD的图形保存等。
CClientDC获得的是窗口客户区的DC,所以只能在客户区画图,其原点坐标为客户区左上角;
CWindowDC获得的是整个窗口的DC,包括标题栏、边框等,其原点坐标也是整个窗口的左上角;
CPaintDC只用在窗口重绘消息响应函数中;
GetDesktopWindow()函数可以获得桌面窗口的指针,所以想在当前屏幕上进行绘图操作可以类似这样:
CWindowDC dc(GetDesktopWindow());//获得与当前桌面窗口相关联的CWindowDC对象 dc.MoveTo(100, 100); dc.LineTo(100, 800);
GDI基础函数使用绘制线条和图形相关推荐
- GDI基础(1):绘制线条和图形
1. 绘制一个像素点:SetPixel(). 绘制直线:MoveTo(),LineTo(). 绘制多个首尾相连的线:Polyline(). 绘制矩形:FrameRect(),Rectangle(),F ...
- android绘制过程3d图形,Android开发之OpenGL绘制三维图形的流程
从这篇文章开始,接下来会连载一系列的OpenGL相关博文,好好探讨如何在Android中进行OpenGL开发. OpenGL的全称是"Open Graphics Library", ...
- html5中Canvas、绘制线条模糊、常见绘制工具、绘制基本图形、绘制图片、面向对象的方式绘制图形图片、绘制文本、帧动画绘制
Canvas容器: canvas标签用来定义图像的容器,必须配合脚本来绘制图像,canvas也运用于游戏开发.注意:canvas绘制图时会出现线条模糊情况,这是因为显示屏像素和canvas中定义的一个 ...
- OpenCV:02基础知识和绘制图形
文章目录 OpenCV的色彩空间 RGB和BGR `HSV`,`HSL`和`YUV` `HSV(HSB)` `HSL` `YUV` 颜色空间的转化 OpenCV的一种重要数据结构--Mat Mat介绍 ...
- VC++ 绘制线条 OnLButtonDown函数(DrawView.cpp) 利用SDK全局函数实现画线功能 利用MFC的CDC类实现画线功能 利用MFC的CClientDC类实现画线功能
目录 绘制线条 OnLButtonDown函数(DrawView.cpp) 利用SDK全局函数实现画线功能 利用MFC的CDC类实现画线功能 利用MFC的CClientDC类实现画线功能 接上:VC+ ...
- 【MATLAB】基本绘图 ( plot 函数绘制多个图形 | legend 函数标注图形 | 图形修饰 )
文章目录 一.plot 函数绘制多个图形 二.legend 函数标注图形 三.图形修饰 一.plot 函数绘制多个图形 使用单个 plot 函数绘制多条曲线 : plot 函数可以传入多个可变参数 , ...
- R语言使用ggplot2包的快速可视化函数qplot绘制基础密度图实战
R语言使用ggplot2包的快速可视化函数qplot绘制基础密度图实战 目录 R语言使用ggplot2包的快速可视化函数qplot绘制基础密度图实战 #仿真数据
- R语言使用ggplot2包的快速可视化函数qplot绘制基础直方图实战
R语言使用ggplot2包的快速可视化函数qplot绘制基础直方图实战 目录 R语言使用ggplot2包的快速可视化函数qplot绘制基础直方图实战 #仿真数据
- 【液晶模块系列基础视频】4.5.X-GUI图形界面库-进度条等函数简介
[液晶模块系列基础视频]4.5.X-GUI图形界面库-进度条等函数简介 ============================== 技术论坛:http://www.eeschool.org 博客地址 ...
最新文章
- Oracle表空间管理
- 微软:97%电子邮件属于垃圾邮件
- Tungsten Fabric SDN — 基于 Tags 的安全访问控制策略
- Java 8中处理集合的优雅姿势——Stream
- 2013手机App发展趋势预测:遇冷和洗牌
- React Native中常用ES6语法
- 关于yield的一些资料
- 初学JAVA随记——循环语句的几个要点
- Word中 Visio 图片到 LaTeX PDF
- Only no-arg methods may be annotated with @Scheduled 的解决方法
- 奔驰809android auto,奔驰E Android Auto+AA Mirro技术作业
- iOS安全防护---越狱检测、二次打包检测、反调试
- 基于casbin的ABAC/RBAC权限实践
- 关于悬浮球(悬浮窗)Android8.0(Android O)的适配
- 【机器学习】“冷启动” 问题
- MATLAB离散卷积的实现_代码编写_实现两列数的卷积
- 支付宝小程序input加disabled字体变灰
- 基于springboot+jsp的商场停车场服务管理信息系统
- 中小型企业搭建数据团队的踩坑分析
- 水库湖泊水雨情监测系统 小型水库雨水情自动测报
热门文章
- 哈希表_四数之和(待完善)
- Codeup 1814.剩下的树
- ​LeetCode刷题实战546:移除盒子
- Linux安装时分区跳过硬盘锁,安装Linux系统对硬盘分区时,必须有两种分区类型: 和 。...
- 90%的人都被这样“坑”过?淘宝京东的双十一价是真的吗?
- Matplotlib画动态散点图:
- ipqc的工作流程图_过程质量控制IPQC的介绍及流程
- apt-get install netstat失败
- 【C语言基础练习】100匹马驮100担货,大马一匹驮3担,中马一匹驮2担,小马两匹驮1担。试编写程序计算大、中、小马的数目。
- 免费的电脑监控软件有哪些?可以一直免费使用的