文章目录
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)));//填充区域