Win32编程之绘图编程(四)
一、绘图基础
- 绘图设备DC(Device Context),绘图上下文/绘图描述表
- HDC:DC句柄,表示绘图设备
- GDI:Windows graphics device interface(Win32提供的绘图API)
- 颜色的使用:COLORREF:实际DWORD;例如:COLORREF nColor = 0;
- 赋值使用RGB宏:例如:nColor = RGB(0,0, 255)
- 获取RGB值:GetRValue/GetGValue/GetBValue;例如:BYTE nRed = GetRValue(nColor)
计算机使用红、绿、蓝:
R:0~255
G:0~255
B:0~255
每一个颜色是3个字节24位,保存范围:0~2^24-1
二、基本图形绘制
(1).SetPixel设置指定点的颜色
COLORREF SetPixel(
HDC hdc, //DC句柄
int x,//X坐标
int y,//Y坐标
COLORREF crColor//设置的颜色
);
返回指定点原来的颜色
示例代码:
void OnDrawPoint(HDC hdc) {
for (int i = 0; i < 256; i++) {
for (int j = 0; j < 256; j++) {
SetPixel(hdc, i, j, RGB(i, j, 0));
}
}
}
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
OnDrawPoint(hdc);
EndPaint(hWnd, &ps);
}
//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WindProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
switch (msgID) {
case WM_PAINT: {
OnPaint(hWnd);
break;
}
default:
break;
}
return DefWindowProc(hWnd, msgID, wParam, lParam);
}
(2).线的使用(直接,弧线)
- MoveToEx:指名窗口当前点
- LineTo:从窗口当前点到指定点绘制一条直线
- 当前点:上一次绘图时最后一点,初始为(0,0)点
示例代码:
void OnDrawLine(HDC hdc) {
//改变窗口当前点坐标
MoveToEx(hdc, 100, 100, NULL);
LineTo(hdc, 300, 300);
LineTo(hdc, 0, 300);
}
(3).封闭图形:能够用画刷填充的图形(Rectangle/Ellipse)
示例代码:
void OnDrawRect(HDC hdc) {
Rectangle(hdc, 100, 100, 300, 300);
}
void OnDrawEll(HDC hdc) {
Ellipse(hdc, 100, 100, 300, 300);
}
三、GDI绘图对象
1.画笔使用流程
(1)、创建画笔
A.画笔的作用:线的颜色、线型、线粗
B.画笔的使用:
HPEN CreatePen( int fnPenStyle;//画笔的样式 int nWidth;//画笔的粗细 COLORREF crColor//画笔的颜色 ); 创建成功后返回画笔句柄
PS_SOILD:实心线,可以支持多个像素宽,其他线型只能是一个像素宽
(2).将画笔应用到DC中
HGDIOBJ SelectObject( HDC hdc;//绘图设备句柄 HGDIOBJ hgdiobj//GDI绘图对象句柄,画笔句柄 ); 返回原来的GDI绘图对象句柄 注意保存原来DC当中的画笔
(3).绘图
(4).取出DC中当中的画笔
将原来的画笔,使用SelectObject函数,放入到设备DC中,就会将我们创建的画笔取出
(5).释放画笔
BOOL DeleteObject( HGDIOBJ hObject //GDI绘图对象句柄,画笔句柄 ); 只能删除不被DC使用的画笔,所以在释放前,必须将画笔从DC中取出
示例代码:
void OnDrawEll(HDC hdc) {
Ellipse(hdc, 100, 100, 300, 300);
}
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
HPEN hPen = CreatePen(PS_SOLID, 10, RGB(255, 0, 0));
HGDIOBJ nOldPen = SelectObject(hdc, hPen);
OnDrawEll(hdc);//绘制圆形
SelectObject(hdc, nOldPen);
DeleteObject(hPen);
EndPaint(hWnd, &ps);
}
//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WindProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
switch (msgID) {
case WM_PAINT: {
OnPaint(hWnd);
break;
}
default:
break;
}
return DefWindowProc(hWnd, msgID, wParam, lParam);
}
2.画刷的使用流程
(1).画刷相关
画刷:封闭图像的填充的颜色、图案;HBRUSH:画刷句柄
(2).画刷的使用
- 创建画刷:CreateSolidBrush:创建实现画刷;CreateHatchBrush:创建纹理画刷
- 将画刷应用到DC中,selectObject
- 绘图
- 将画刷从DC中取出:SelectObject
- 删除画刷:DeleteObject
(3).透明画刷
可以使用GetStockObject函数获取系统维护的画刷、画笔等,如果不使用画刷填充,需要使用NULL_BRUSH参数,获取不填充的画刷,GetStokObject返回的画刷不需要DeleteObject
示例代码:
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
HPEN hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0));
HGDIOBJ nOldPen = SelectObject(hdc, hPen);
//HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
//HBRUSH hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
HGDIOBJ hBrush = GetStockObject(NULL_BRUSH);
HGDIOBJ nOldBrush = SelectObject(hdc, hBrush);
OnDrawEll(hdc);//绘制圆形
SelectObject(hdc, nOldBrush);
DeleteObject(hBrush);
SelectObject(hdc, nOldPen);
//DeleteObject(hPen);
EndPaint(hWnd, &ps);
}
四、位图绘制
(1).位图相关
- 光栅图形:激励图像中每一点的颜色信息
- 矢量图形:记录图像算法、绘图指令等
- HBITMAP:位图句柄
(2).位图使用
- 在资源中添加位图资源
- 从资源中加载位图
- 创建一个与当前DC相匹配的DC(内存DC)
HDC CreateCompatibleDC( HDC hdc //当前句柄,可以为NULL(使用屏幕DC) ); 返回创建的DC句柄
- 将位图放入匹配的内存DC中,SelectObject
- 成像(1:1)
BOOL BitBlt( HDC hdc, //目的DC(窗口DC) int x, //目的的左上X坐标 int y, //目的的左上Y坐标 int cx, //目的宽度 int cy, //目的的高度 HDC hdcSrc, //源DC(内存DC) int x1, //源左上X坐标 int y1, //源左上Y坐标 DWORD rop //成像方法 SRCCOPY );
- 取出位图:SelectObject
- 释放位图:DeleteObject
- 释放匹配的DC:DeleteDC
示例代码:
void OnDrawBmp(HDC hdc) {
//添加位图资源
HBITMAP hBmp = LoadBitmap(g_hIns, (LPCWSTR)IDB_BITMAP1);
//创建一个内存DC,并构建一个虚拟区域,并且内存DC在虚拟区域中绘图
HDC hMemdc = CreateCompatibleDC(hdc);
//将位图数据送给内存DC,内存DC在虚拟区域中将位图绘制出来
HGDIOBJ nOldBmp = SelectObject(hMemdc, hBmp);
//将虚拟区域中绘制好的图形成像到窗口中
BitBlt(hdc, 100, 100, 48, 48, hMemdc, 0, 0, SRCCOPY);
//缩放成像
StretchBlt(hdc, 200, 200, 24, 24, hMemdc, 0, 0, 48, 48, SRCCOPY);
SelectObject(hMemdc, nOldBmp);
DeleteObject(hBmp);
DeleteDC(hMemdc);
}
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
OnDrawBmp(hdc);
EndPaint(hWnd, &ps);
}
五、文本绘制
(1).绘制简单文件
/* TextOut():将文字绘制在指定坐标位置 int DrawText( HDC hDc,//DC句柄 LPCTSTR lpString, //字符串 int nCount, //字符数量 LPRECT lpRect, //绘制文字的矩形框 UINT uFormat //绘制方式 ); */
示例代码:
void onDrawText(HDC hdc) {
TCHAR szText[] = TEXT("Hello Text ");
TextOut(hdc, 100, 100, szText, _tcslen(szText));
RECT rc;
rc.left = 100;
rc.top = 150;
rc.right = 200;
rc.bottom = 200;
Rectangle(hdc, 100, 150, 200, 200);
//DT_VCENTER /DT_BOTTOM只是用于DT_SINGLELINE, 它们和DT_WORDBREAK冲突
DrawText(hdc, szText, _tcslen(szText), &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP);
}
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
onDrawText(hdc);
EndPaint(hWnd, &ps);
}
(2).文件颜色和背景
- 文字颜色:SetTextColor
- 文字背景颜色:SetBkColor
- 文字背景模式:SetBkMode(OPAQUE/TRANSPARENT)
示例代码:
void onDrawText(HDC hdc) {
TCHAR szText[] = TEXT("Hello Text ");
TextOut(hdc, 100, 100, szText, _tcslen(szText));
RECT rc;
rc.left = 100;
rc.top = 150;
rc.right = 200;
rc.bottom = 200;
DrawText(hdc, szText, _tcslen(szText), &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP);
}
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
SetTextColor(hdc, RGB(255, 0, 0));
SetBkColor(hdc, RGB(0, 255, 0));//只适用在OPAQUE模式下
SetBkMode(hdc, TRANSPARENT);
onDrawText(hdc);
EndPaint(hWnd, &ps);
}
3.字体的使用
- 字体相关:Windows常用的字体为TrueType格式的字体文件,字体名:标识字体类型;HFONT:字体句柄
- 应用字体到DC:SelectObject
- 绘制文字:DrawText/TextOut
- 取出字体:SelectObject
- 删除字体:DeleteObject
字体的使用函数:
CreateFont( _In_ int cHeight, //字体高度 _In_ int cWidth, //字体宽度 _In_ int cEscapement, //字符串倾斜角度 _In_ int cOrientation, //字符旋转角度 _In_ int cWeight, //字体的粗细 _In_ DWORD bItalic, //斜体 _In_ DWORD bUnderline, //字符下划线 _In_ DWORD bStrikeOut, //删除线 _In_ DWORD iCharSet, //字符集 _In_ DWORD iOutPrecision, //输出精度 _In_ DWORD iClipPrecision, //剪切精度 _In_ DWORD iQuality, //输出质量 _In_ DWORD iPitchAndFamily, //匹配字体 _In_opt_ LPCWSTR pszFaceName //字体名称 );
示例代码:
void onDrawText(HDC hdc) {
TCHAR szText[] = TEXT("Hello Text ");
HFONT hFont = CreateFont(30, 0, 45, 0, 900, 1, 1, 1, GB2312_CHARSET, 0, 0, 0, 0, TEXT("黑体"));
HGDIOBJ nOldFont = SelectObject(hdc, hFont);
TextOut(hdc, 100, 100, szText, _tcslen(szText));
RECT rc;
rc.left = 100;
rc.top = 150;
rc.right = 200;
rc.bottom = 200;
DrawText(hdc, szText, _tcslen(szText), &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP);
SelectObject(hdc, nOldFont);
DeleteObject(hFont);
}
void OnPaint(HWND hWnd) {
PAINTSTRUCT ps = { 0 };
HDC hdc = BeginPaint(hWnd, &ps);
SetTextColor(hdc, RGB(255, 0, 0));
SetBkColor(hdc, RGB(0, 255, 0));//只适用在OPAQUE模式下
SetBkMode(hdc, TRANSPARENT);
onDrawText(hdc);
EndPaint(hWnd, &ps);
}

浙公网安备 33010602011771号