【Demo 0006】图形绘制基础
Windows 系统与DOS系统最大的区别在于其是图形用户界面,有了它电脑才得到飞速的发展,才进入了千家万户。 图形用户界面就是这么强悍!!!
通常我们Windows 系统下划分为3大模块: Kernel(内存与线程), User(窗体及消息), GDI(绘图), User + GDI 时常被统称GWE(图形窗体事件)。
为今起我们开始学习三大模块之一 : GDI(Graphics Device Interface 图形设备接口); GDI 能被划为Windows三大模块之一,可想此模块不简单复杂,因而我们也细分成多个章节促步讲解。 自认为GDI学的不怎么好,只能讲讲表面的, 不过话说回来普通的使用应该问题不大。
一、 GDI 背景
在我们平时工作和生活中几乎每天都会接触到许多不同图形显示设备如:显示屏, 打印机, 而显示屏有LCD, CRT的,又有15英寸, 17英寸的大小的,还有HP, DELL不同品牌的,但我
们并不因为这些使我们的程序不能运行或不行正常工作。 哈.. 是的,简单的背后是复杂的,我们看看Windows 系统是如何做的呢?
如图所示,不同的显示设备有着与其关的设备驱动,而GDI正式通过与当前显示设备匹配的驱动进行通讯从而实现相同的接口控制不同的设备;
GDI 主要定义了一整套图形操作的接口为Windows 开发者提供了非常简单的接口使开发者不需关心其控制的设备;
二、设备DC
Windows 为了让开发者在不同的设备上进行绘图,提供了一个叫设备上下文或叫设备环境, 我们可以理解为一个黑板,有了它我们才可以开发绘图了。 系统对绘图的区域不同而定义
了不同的DC,日常工作中常使用的:
1. 客户区DC -- 此DC只能在客户区绘图(客户区就是除标题栏和菜单栏以及状态栏区域)
a. 获取方法:
通常在处理WM_PAINT消息时,通过BeginPaint返回的
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
用完后释放:
EndPaint(hWnd, &ps);
注: BeginPaint与EndPaint必须成对调用,窗体存在无效剪切区时系统会调用此消息处理,并在EndPaint调用后将无效剪切区变成有效,所以WM_PAINT用户不要发送此消
息;
b. 获取方法:
HDC hDC = GetClientDC(hWnd);
用完后释放:
ReleaseDC(hWnd, hDC);
c. 获取方法:
HDC hDC = GetDC(hWnd);
用完后释放:
ReleaseDC(hWnd, hDC);
2. Window DC – 此DC可以下本窗体的任务地方进行绘图
获取方法:
HDC hDC = GetWindowDC(hWnd);
用完后释放:
ReleaseDC(hWnd, hDC);
3. 屏幕DC - 此DC可以在整个窗体上进行绘图
获取方法:
HDC hDC = CreateDC(_T("DISPLAY”), NULL, NULL, NULL);
完后释放:
DeleteDC(hDC);
备注: 设备DC是共用资源,所以在使用完成后要释放回去, 通过Get的获取,就用Release 来释放;通过Create的就用Delete来释放.
三、DC属性
通知前面的方法,我们得到了黑板,但黑板是什么样的,多长多宽,彩色的还是黑白的等,黑板上支持些什么工具去绘制以及绘制的工具有什么特针, 本节我们来看看如果了解这些信息.
前面提到OS为了方便上层开发将显示设备映射成DC,映射成DC后,DC就具备了显示设备的信息,我们可以通过一些GDI接口来获取:
1. 获取DC信息函数:
int GetDeviceCaps(HDC hDC, int nIndex)
本函数通过设置不同的nIndex可以获取对应的DC信息,我们选择几个常用的讲解:
HORZRES - 获取显示设备宽(象素为单位)
VERTRES - 获取显示设备高(象素为单位)
BITPIXELS - 获取显示设备颜色位数
LOGPIXELSX - 获取每个象素的宽
LOGPIXELSX - 获取每个象素的高
2. 获取DC环境中图形对象
HGDIOBJ GetCurrentObject(HDC hDC, UINT nObjType)
本函数过设置不同的nObjType可以获取被选入设备DC中不同的图形对象,图形对象主要有:
OBJ_BITMAP - 位图
OBJ_BRUSH - 画刷
OBJ_PEN - 画笔
OBJ_FONT - 字体
OBJ_PAL - 调色板
OBJ_COLORSPACE - 没用过
有了这些对象后再通过GetObject函数获取绘图对象更详细的信息:
int GetObject(HGDIOBJ hObj, int nObjSize, LPVOID& pvObj)
每个图形对象都有一个对象描述信息结构体,对应如下:
HBITMAP => BITMAP
HPEN => LOGPEN
HBRUSH => LOGBRUSH
HFONT => LOGFONT
HPALETTE => WORD (调色板的颜色数)
例如:
HPEN hPen = static_cast<HPEN>(GetCurrentObject(hDC, OBJ_PEN));
LOGPEN logPen;
GetObject(hPen, sizeof(LOGPEN), &logPen);
四、DC 操作
因为函数比较多, 我从MSDN中找出来并解常用的和相关的函数做了一些分类, 大部分部函数我们将在后面的程序中会用到.