windows第十三章 GDI绘图技术

文章目录

GDI绘图函数介绍

绘图函数在CDC类里

设备上下文

DC:device context 设备上下文,显卡驱动程序,控制硬件,每个厂商的都不同,操作系统层面,底层来控制需要有一套给我操作系统来管理操作的api,对他们进行统一,DC就相当于一块小黑板,绘图设备

函数

cpp 复制代码
		CPaintDC dc(this); // 用于绘制的设备上下文
		//绘制矩形
		dc.Rectangle(0, 0, 100, 100);
		
		//绘制线条
		dc.MoveTo(10, 10);//起点,如果不写,默认是原点
		dc.LineTo(100, 100);//终点
		dc.LineTo(200, 10);
		
		//绘制椭圆,或者圆
		dc.Ellipse(100, 100, 200, 200);
		dc.Ellipse(100, 100, 150, 200);//是一个矩形区域的内切圆
		
		//绘制圆角矩形
		dc.RoundRect(0, 210, 300, 300, 20, 20);
		
		//画3d矩形
		dc.Draw3dRect(10, 300, 100, 100, RGB(255, 255, 255), RGB(10, 10, 10));
		
		//绘制矩形边缘
		dc.DrawEdge(CRect(10, 400, 100, 500), EDGE_SUNKEN, BF_RECT);//绘制矩形边缘,EDGE_SUNKEN是凹陷的,EDGE_RAISED是凸起的,BF_RECT是指整个矩形所有边都画
		
		//绘制扇形
		dc.Pie(100, 100, 300, 300, 100, 100, 200, 200);
		
		//绘制点
		dc.SetPixel(240, 10, RGB(0, 255, 255));//设置点的颜色
		dc.SetPixel(250, 10, RGB(0, 255, 255));//设置点的颜色
		
		//绘制圆弧
		dc.Arc(100, 100, 300, 300, 100, 100, 200, 200);
		dc.ArcTo(100, 100, 300, 300, 100, 100, 200, 200);//绘制弧线,从起始点到弧线

		//绘制多边形
		CPoint point[4];
		point[0] = CPoint(100, 100);
		point[1] = CPoint(200, 100);
		point[2] = CPoint(200, 200);
		point[3] = CPoint(100, 300);
		dc.Polygon(point, 4);//绘制多边形
		
		//绘制多个多边形
		CPoint point1[8];
		point1[0] = CPoint(100, 300);
		point1[1] = CPoint(200, 300);
		point1[2] = CPoint(200, 400);
		point1[3] = CPoint(100, 500);
		point1[4] = CPoint(300, 300);
		point1[5] = CPoint(400, 300);
		point1[6] = CPoint(400, 400);
		point1[7] = CPoint(300, 500);
		int arr[3] = { 3,4,3 };
		dc.PolyPolygon(point1, arr, 3);//绘制多个多边形
		
		//绘制连续的线条
		dc.Polyline(point1, 8);//绘制连续的线条
		
		//绘制贝赛尔曲线,最少需要4个点
		dc.PolyBezier(point, 4);//绘制贝赛尔曲线
		
		//绘制文本
		dc.TextOut(10, 10, _T("Hello World!"));//绘制文本
		CString str = L"你好,世界!";
		CRect rect(10, 50, 200, 100);
		dc.DrawText(str, &rect, DT_LEFT | DT_TOP | DT_SINGLELINE);//绘制文本
		//绘制图标
		int cxIcon = GetSystemMetrics(SM_CXICON);//获取系统图标宽度
		int cyIcon = GetSystemMetrics(SM_CYICON);//获取系统图标高度
		GetClientRect(&rect);//获取客户区大小
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		dc.DrawIcon(x, y, m_hIcon);

		::DrawIcon(dc.m_hDC, x, y, m_hIcon);//绘制图标,另一种方式
		
		//反色显示
		//dc.InvertRect(&rect);
		//也可以对图片进行反转颜色
		CBitmap bmp;
		bmp.LoadBitmap(IDB_BITMAP1);//加载位图
		CDC memDC;
		memDC.CreateCompatibleDC(&dc);//创建一个与dc兼容的内存DC
		memDC.SelectObject(&bmp);//将位图选入内存DC
		dc.BitBlt(0, 0, 322, 439, &memDC, 0, 0, SRCCOPY);//将内存DC中的位图复制到dc中
		dc.InvertRect(&rect);

		//绘制弦
		dc.Chord(100, 100, 300, 300, 100, 100, 200, 200);

		//绘制焦点区域
		dc.DrawFocusRect(&rect);

		//设置背景颜色
		dc.SetBkColor(RGB(255, 255, 0));
		dc.TextOut(10, 10, _T("Hello World!"));//绘制文本 
		dc.SetBkMode(TRANSPARENT);//设置背景模式为透明,之前设置的背景就失效了
		dc.TextOut(10, 30, _T("Hello World!"));//绘制文本
		dc.SetTextAlign(TA_CENTER | TA_BASELINE);//设置文本对齐方式,水平居中,垂直基线对齐
		dc.TextOut(200, 30, _T("Hello World!"));//绘制文本
		dc.SetTextColor(RGB(255, 0, 0));//设置文本颜色
		dc.TextOut(200, 50, _T("Hello World!"));//绘制文本

		CBitmap bmp;
		bmp.LoadBitmap(IDB_BITMAP1);//加载位图
		CDC memDC;
		memDC.CreateCompatibleDC(&dc);//创建一个与dc兼容的内存DC
		memDC.SelectObject(&bmp);//将位图选入内存DC
		//设置拉伸模式
		dc.SetStretchBltMode(HALFTONE);//HALFTONE是半色调模式,可以保证位图的质量
		dc.StretchBlt(0, 0, 200, 300, &memDC, 0, 0, 322, 439, SRCCOPY);//将内存DC中的位图拉伸到dc中

		CDialogEx::OnPaint();//调用了基类的绘图

m_hDC

设备上下文,非常核心的成员,与硬件无关的操作系统上面统一的一个绘图设备

GDI对象

画笔

默认黑色,宽度1px

cpp 复制代码
		CPen pen(PS_SOLID, 2, RGB(0, 0, 255));//创建一个蓝色,宽度为2的画笔
		dc.SelectObject(&pen);//将画笔选入dc
		dc.Rectangle(10, 10, 200, 100);//绘制矩形
		//创建一个带虚线的画笔
		CPen pen1(PS_DASH, 1, RGB(0, 0, 255));//创建一个蓝色,宽度为1的带虚线画笔,如果宽度不是1,就画不出dash类型的虚线
		dc.SelectObject(&pen1);//将画笔选入dc
		dc.Rectangle(10, 120, 200, 220);//绘制矩形		

		CPen pen2;
		pen2.CreatePen(PS_DOT, 1, RGB(0, 0, 255));//创建一个蓝色,宽度为1的带点画笔,这个也是宽度1有效

		CPen pen3;
		LOGPEN logpen;
		logpen.lopnStyle = PS_SOLID;
		logpen.lopnWidth.x = 2;
		logpen.lopnColor = RGB(255, 0, 255);
		pen3.CreatePenIndirect(&logpen);//创建一个画笔,参数是一个LOGPEN结构体
		dc.SelectObject(&pen3);//将画笔选入dc
		dc.Rectangle(10, 230, 200, 330);//绘制矩形

		CPen* pen4 = CPen::FromHandle((HPEN)pen3.m_hObject);//将画笔转换为句柄
		dc.SelectObject(pen4);//将画笔选入dc
		dc.Rectangle(10, 340, 200, 440);//绘制矩形

		//恢复原来的画笔
		CPen* oldPen = dc.SelectObject(&pen);//将原来的画笔选入dc
		dc.Rectangle(10, 450, 200, 550);//绘制矩形
		dc.SelectObject(oldPen);//恢复原来的画笔
		dc.Rectangle(10, 560, 200, 660);//绘制矩形

画刷

正常画一个封闭图形,里面有个白色的区域,而整个客户区域是灰色的,这个白色区域可以修改,就是画刷

cpp 复制代码
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CPaintDC dc(this); // 用于绘制的设备上下文
		CPen pen(PS_SOLID, 3, RGB(0, 0, 255)); //创建一个蓝色、宽度为3的画笔
		dc.SelectObject(&pen); //将画笔选入设备上下文
		CRect rect(100, 100, 300, 300); //定义一个矩形

		//创建普通画刷
		CBrush brush(RGB(255, 0, 0)); //创建一个红色画刷
		dc.SelectObject(&brush); //将画刷选入设备上下文
		dc.Rectangle(rect); //填充矩形

		//可以创建带格式的画刷
		CBrush brush1(HS_BDIAGONAL, RGB(0, 255, 0)); //创建一个绿色斜线画刷
		dc.SelectObject(&brush1); //将画刷选入设备上下文
		dc.Rectangle(rect); //填充矩形

		//用位图创建画刷
		CBitmap bitmap;
		bitmap.LoadBitmap(IDB_BITMAP1); //加载位图
		CBrush brush2(&bitmap); //创建位图画刷
		dc.SelectObject(&brush2); //将画刷选入设备上下文
		dc.Ellipse(rect); //填充椭圆

		//用LOGBRUSH
		CBrush brush3;
		LOGBRUSH logbrush;
		logbrush.lbStyle = BS_SOLID;
		logbrush.lbColor = RGB(0, 0, 255);
		brush3.CreateBrushIndirect(&logbrush); //创建画刷
		dc.SelectObject(&brush3); //将画刷选入设备上下文
		dc.Rectangle(rect); //填充矩形

		//使用系统画刷
		CBrush brush4;
		brush4.CreateSysColorBrush(COLOR_3DLIGHT); //创建系统画刷
		dc.SelectObject(&brush4); //将画刷选入设备上下文
		dc.Rectangle(rect); //填充矩形

		//透明画刷
		CBrush brush5;
		logbrush.lbStyle = BS_NULL;
		brush5.CreateBrushIndirect(&logbrush); //创建透明画刷
		dc.SelectObject(&brush5); //将画刷选入设备上下文
		dc.TextOut(100, 100, _T("透明画刷")); //输出文本
		dc.RoundRect(rect, CPoint(10, 10)); //绘制圆角矩形
		
		//可以从一个句柄转换为指针
		HBRUSH hbrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
		CBrush* pbrush = CBrush::FromHandle(hbrush); //转换为指针
		dc.SelectObject(pbrush); //将画刷选入设备上下文
		dc.Rectangle(rect); //填充矩形
		CDialogEx::OnPaint();//调用了基类的绘图

位图

创建位图,显示到dc上

cpp 复制代码
		CBitmap bmp;//定义一个位图对象
		bmp.LoadBitmap(IDB_BITMAP1);//加载位图
		BITMAP bitmap;//定义一个位图结构体
		bmp.GetBitmap(&bitmap);//获取位图信息
		CDC memDC;//定义一个内存设备上下文
		memDC.CreateCompatibleDC(&dc);//创建与屏幕设备上下文兼容的内存设备上下文
		memDC.SelectObject(&bmp);//将位图选入内存设备上下文
		dc.BitBlt(0, 0, bitmap.bmWidth, bitmap.bmHeight, &memDC, 0, 0, SRCCOPY);//将位图从内存设备上下文拷贝到屏幕设备上下文

		CBitmap bmp1;
		bmp1.CreateCompatibleBitmap(&dc, 200, 200);//创建一个与屏幕设备上下文兼容的位图
		CDC memDC1;
		memDC1.CreateCompatibleDC(&dc);
		memDC1.SelectObject(&bmp1);
		memDC1.FillSolidRect(0, 0, 200, 200, RGB(255, 0, 0));//填充位图
		memDC1.TextOut(50, 50, _T("Hello World!"));//在位图上输出文本
		dc.BitBlt(0, 0, 200, 200, &memDC1, 0, 0, SRCCOPY);//将位图从内存设备上下文拷贝到屏幕设备上下文

		CImage image;
		image.Attach(bmp1);//将位图附加到图像对象
		image.Save(_T("./1.bmp"));//保存图像
		image.Detach();//分离图像

		CBitmap bmp2;
		bmp2.CreateDiscardableBitmap(&dc, 200, 200);//创建一个可丢弃的位图,用完会销毁,节省内存

字体

cpp 复制代码
		CFont font;
		font.CreateFont(20,//高度
			0, //宽度
			0,//倾斜角度
			0,//倾斜角度
			FW_NORMAL, //加粗
			FALSE,//斜体
			FALSE,//下划线
			0,//删除线
			DEFAULT_CHARSET,//字符集
			OUT_DEFAULT_PRECIS,//输出精度
			CLIP_DEFAULT_PRECIS,//剪裁精度
			DEFAULT_QUALITY,//输出质量
			DEFAULT_PITCH | FF_SWISS,//输出间距和家族
			_T("宋体"));//字体
		dc.SelectObject(&font);//选择字体
		dc.TextOut(10, 10, _T("Hello World!"));//输出文本

		CFont font2;
		font2.CreatePointFont(100, _T("宋体"));//创建字体
		dc.SelectObject(&font2);//选择字体
		dc.TextOut(10, 100, _T("Hello World!"));//输出文本

		dc.TextOut(20, 200, _T("Hello World!"));//输出文本
		font2.DeleteObject();//删除字体

		CFont* font3 = GetFont();//获取当前字体
		LOGFONT lf;
		font3->GetLogFont(&lf);//获取字体信息
		lf.lfHeight = 50;//设置字体高度
		lf.lfItalic = TRUE;//设置字体为斜体
		lf.lfUnderline = TRUE;//设置字体为下划线
		CFont font4;
		font4.CreateFontIndirect(&lf);//创建字体
		dc.SelectObject(&font4);//选择字体
		dc.TextOut(20, 300, _T("Hello World!"));//输出文本

区域

cpp 复制代码
		//区域创建1
		CRect rect(0, 0, 300, 100);//设置绘图区域
		CRgn rgn;//定义一个区域
		rgn.CreateRectRgnIndirect(&rect);//创建一个矩形区域
		dc.SelectObject(&rgn);//选择区域
		dc.FillRgn(&rgn, &CBrush(RGB(0, 255, 255)));//填充区域

		//区域创建2
		CRgn rgn2;
		//rgn2.CreateRectRgn(0, 100, 300, 200);//创建一个矩形区域
		rgn2.CreateRoundRectRgn(0, 100, 300, 200, 10, 10);//创建一个圆角矩形区域
		dc.SelectObject(&rgn2);//选择区域
		dc.FillRgn(&rgn2, &CBrush(RGB(255, 0, 255)));//填充区域

		//区域组合
		CRgn rgn3;
		rgn3.CreateRectRgn(0, 150, 300, 300);//创建一个矩形区域
		rgn3.CombineRgn(&rgn2, &rgn3, RGN_XOR);//区域组合,RGN_XOR为异或
		dc.SelectObject(&rgn3);//选择区域
		dc.FillRgn(&rgn3, &CBrush(RGB(0, 255, 0)));//填充区域
相关推荐
蓝屏达人3 小时前
6.PE文件新增节
windows
.m5 小时前
Adobe Photoshop CC 2025配置要求
windows
攻城狮7号6 小时前
【第九节】windows sdk编程:通用控件的使用
c++·windows·windows编程·windows sdk
kanlon9 小时前
Window10永久暂停(禁用)自动更新
windows
心灵宝贝10 小时前
Wireshark 2.2.1(32 位)版本详解:功能、安装与使用指南
windows
周Echo周15 小时前
6、STL中list的使用方法
数据结构·c++·windows·后端·算法·链表·list
小gpt&1 天前
02 windows qt配置ffmpeg开发环境搭建
windows·qt·ffmpeg
爱的叹息1 天前
Java 集合遍历过程中修改数据触发 Fail-Fast 机制 ,导致报ConcurrentModificationException异常
java·windows·python
lqj_本人1 天前
鸿蒙的 ListItem 组件
windows·microsoft