GUI作图概述
作图步骤
- 获得设备描述表资源句柄
- 绘图操作
- 释放设备描述表资源句柄
流程图如下:
获取/释放设备资源描述表
- 获取设备资源描述表: BeginPaint / GetDC
- 释放设备资源描述表: EndPaint / ReleaseDC
BeginPaint / GetDC 两种方式的区别:
BeginPaint GetDC
使用环境 只用于图形刷新时获取设备环境 使用较为广泛
操作区域 无效区 特定窗口的客户区或者整个窗口
释放设备环境所用函数 ReleaseDC () EndPaint ()代码示例:
在 WM_PAINT 添加 BeginPaint 事件,在 WM_LBUTTONDOWN 添加 GetDC 事件.
BeginPaint 使用:
//获得资源DC hdc=BeginPaint(hwnd,&ps); //获得窗口大小 GetClientRect(hwnd,&rect); //绘制文本 DrawText(hdc,"hellow my first windows program",strlen("hellow my first windows program"),&rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); //释放资源DC EndPaint(hwnd,&ps);GetDC 使用:
//获得设备资源描述表 hdc = GetDC(hwnd); //绘制带圆角矩形 RoundRect(hdc,10,10,110,60,10,10); //释放设备资源描述表 ReleaseDC(hwnd,hdc);程序源码
运行结果:
单击鼠标右键和重绘窗口时
在单击鼠标右键后
绘图操作分类
- 描绘图形
- 位图
- 文本输出
与设备描述表相关函数
- 背景色: GetBkColor SetBkColor
- 背景模式: GetBkMode SetBkMode
- 位图: CreateBitMap CreateBitMapIndirect CreateCompatibleBitmap SelectObject
- 画刷: CreateBrushIndirect CreateDIBPatternBrush CreateHatchBrush CreatePatternBrush CreateSolidBrush SelectObject
- 画刷起始位置: GetBrushOrg SetBrushOrg UnrealizeObject
- 剪裁域: ExcludeClipRect IntersectClipRect OffsetClipRgn SelectClipPath SelectObject SelectClipRgn
- 颜色调色板: CreatePalette RealizePalette SelectPalette
- 绘图方式: GetROP2 SetROP2
- 字体: CreateFont CreateFontIndirect SelectObject
- 字符间距: GetTextCharacterExtra SetTextCharacterExtra
- 映射方式: GetMapMode SetMapMode
- 画笔: CreatePen CreatePenIndirect SelectObject
- 多边形填充方式: GetPolyFillMode SetPolyFillMode
- 缩放模式: SetStretchBltMode GetStretchBltMode
- 文本颜色: GetTextColor SetTextColor
- 视图范围: GetViewportExtEx SetViewportExtEx ScaleViewportExtEx
- 视图原点: GetViewportOrgEx SetViewportOrgEx
- 窗口范围: GetWindowExtEx SetWindowExtEx ScaleWindowExtEx
- 窗口原点: GetWindowOrgEx SetWindowOrgEx
描绘图形
常用绘图函数:
- 画贝塞尔曲线:
- PolyBezier
- PolyDraw
- 画点: SetPixel
- 画矩形: Rectangle
- 画带圆角的矩形: RoundRect()
函数原型: BOOL RoundRect( HDC hdc, int nLeftRect, int nTopRect,int nRightRect,int nBottomRect,int nWidth,int nHeight);
参数说明:
- 画椭圆: Ellipse
- 画椭圆的一部分(即画一个弦): Chord
- 画一个扇形区并用当前画刷填充: Pie
- 画椭圆弧线: Arc
函数原型: BOOL Arc(HDC hdc,int nLeftRect, int nTopRect,int nRightRect,int nBottomRect,int nXStartArc,int nYStartArc,int nXEndArc,int nYEndArc);
参数说明:
- 画椭圆弧线: ArcTo
- 画正圆弧线: AngleArc
函数原型: BOOL AngleArc(HDC hdc,int X,int Y,DWORD dwRadius,FLOAT eStartAngle,FLOAT eSweepAngle);
参数说:
- 画一系列相连的直线:
- Polyline
- PolylineTo
- PolyPolyline
- 画线条:
- 设置画笔起始位置: MoveToEx
- 设置画笔终止位置: LineTo
位图
步骤:
- 建立位图资源
- 载入/创建位图资源
- 获取设备内存
- 选入内存设备
- 贴图
流程图如下所示:
代码示例:
.rc 内容(位图资源):
IDB_BITMAP1 BITMAP "8c8a09f1gw1ds3qh4vtcyj.bmp"位图(8c8a09f1gw1ds3qh4vtcyj.bmp 尺寸信息:440*622):
在鼠标左键单击事件中添加贴图操作:
加载位图:
hBmp = LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BITMAP1));创建兼容 DC 并将位图选入兼容 DC 中:
hcmdc = CreateCompatibleDC(hdc); SelectObject(hcmdc,hBmp);获得窗口大小(被显示的区域),获得位图信息(要显示的区域)
//获取窗口大小 GetClientRect(hwnd,&rect); //获取位图信息(在 StretchBlt 时候有用到,而 BitBlt 没有) GetObject(hBmp, sizeof(BITMAP), &bmp); 显示位图: //显示方式一, 按原图比例显示 BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,SRCCOPY); //显示方式二, 拉伸式显示 StretchBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);程序源码
运行结果:
文本输出
文本输出操作
- 文字输出: TextOut
- 显示字符串: DrawText
有关文本操作:
- 获取文字信息: GetTextMetrics
- 格式化文字: GetTextExtentPoint32
- 设置字体颜色和背景颜色:
- 字体: SetTextColor
- 背景: SetBkColor
设置画刷/画笔/字体
步骤:
- 创建资源句柄
- 创建自定义资源/调用系统资源
- 将资源选入系统
如下图所示:
代码示例:
在窗口重画的时候添加创建新画笔操作:
创建新画笔,并将画笔选入设备描述表中
pen = CreatePen(PS_DOT,3,RGB(255,100,100)); SelectObject(hdc,pen);为了区别创建画笔前和创建画笔后的作图的区别
在创建画笔前绘制一条直线:
//rect 为记录窗口大小的 RECT 结构体 MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2-50,NULL); LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2-50);在创建画笔后绘制一条直线:
MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2+50,NULL); LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2+50);程序源码
运行结果:
程序源码
#include<windows.h> #include"resource.h" HINSTANCE hinstance; LRESULT CALLBACK textprom( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ); int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // pointer to command line int nCmdShow // show state of window ) { WNDCLASS wndclass; HWND hwnd; MSG msg; //设计窗口类 wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hIcon=LoadIcon(NULL,IDI_ERROR); wndclass.hInstance=hInstance; wndclass.lpfnWndProc=textprom; wndclass.lpszClassName="text"; wndclass.lpszMenuName=NULL; wndclass.style=CS_HREDRAW | CS_VREDRAW; //注册窗口类 if(!RegisterClass(&wndclass)) { MessageBox(NULL,"create windows error!","error",MB_OK | MB_ICONSTOP); } //创建无菜单资源的窗口窗口 hwnd=CreateWindow("text","hellow world",WS_DLGFRAME | WS_MINIMIZEBOX | WS_SYSMENU,0,0,500,300,NULL,NULL,hInstance,NULL); //显示更新窗口 ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); hinstance = hInstance; //消息循环 while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK textprom( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { HDC hdc,hcmdc; PAINTSTRUCT ps; RECT rect; HBITMAP hBmp; SIZE size; BITMAP bmp; HPEN pen; switch(uMsg) { //重绘事件 case WM_PAINT: hdc=BeginPaint(hwnd,&ps); //显示文本 GetClientRect(hwnd,&rect); DrawText(hdc,"hellow my first windows program",strlen("hellow my first windows program"),&rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); //画笔 MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2-50,NULL); LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2-50); pen = CreatePen(PS_DOT,3,RGB(255,100,100)); SelectObject(hdc,pen); MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2+50,NULL); LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2+50); EndPaint(hwnd,&ps); break; //绘制圆角矩形 case WM_LBUTTONDOWN: hdc = GetDC(hwnd); RoundRect(hdc,10,10,110,60,10,10); ReleaseDC(hwnd,hdc); break; //贴图 case WM_RBUTTONDOWN: hdc = GetDC(hwnd); hBmp = LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BITMAP1)); hcmdc = CreateCompatibleDC(hdc); SelectObject(hcmdc,hBmp); GetClientRect(hwnd,&rect); GetObject(hBmp, sizeof(BITMAP), &bmp); StretchBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); //BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,SRCCOPY); ReleaseDC(hwnd,hdc); break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd,uMsg,wParam,lParam); }