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)));//填充区域
相关推荐
love530love4 小时前
好消息!PyCharm 社区版现已支持直接选择 WSL 终端为默认终端
linux·ide·人工智能·windows·python·pycharm
課代表9 小时前
Windows (可永久)暂停更新用以解决兼容性、性能与稳定性问题
windows·更新·regedit
檀越剑指大厂10 小时前
Windows系统安装Cursor与远程调用本地模型QWQ32B实现AI辅助开发
人工智能·windows
小毛驴85012 小时前
Windows环境,Python实现对本机处于监听状态的端口,打印出端口,进程ID,程序名称
开发语言·windows·python
MyhEhud12 小时前
Kotlin zip 函数的作用和使用场景
开发语言·windows·kotlin
山禾女鬼00112 小时前
从Windows到Mac的过渡:学习笔记与心得
windows·学习·macos
努力的搬砖人.12 小时前
maven如何搭建自己的私服(windows版)?
java·windows·maven
虚!!!看代码13 小时前
【Mybatis-plus常用语法】
windows·tomcat·mybatis
山乐1913113 小时前
笔记本电脑实现网线内网 + Wi-Fi外网同时使用的配置方案
网络·windows·tcp/ip
明月看潮生1 天前
Windows_PyCharm Python语言开发环境构建
windows·python·青少年编程·pycharm·编程与数学