GDI,即图形设备接口
关于GDI+,可以理解为GDI的一个升级版本,在多图片格式上有很好的支持,但绘图效率比GDI更慢,更不适合游戏开发。
从一种宏观角度来看,GDI是几百个函数和一些相关的数据结构和宏组成的整体而已。
特点:
*不允许程序直接访问物理显示硬件,通过称为“设备环境”的抽象接口间接访问显示硬件
*用户无需关心具体的物理设备类型
*windows参考设备环境的数据结构完成数据的输出
设备环境(DC)
Device Context,一般称为设备环境,或设备上下文,或设备描述表。就绘图的观点来说,DC就是程序可以进行绘图的地方。
eg:如果在整个屏幕上绘图,那么Device就是屏幕,DC就是窗口可以绘图的地方。
无论哪种 设备接口、哪种通信数据都是同样的处理,GDI的接口都是相同的。
当我们用GDI绘图时,必须先取得设备环境的句柄。
必须在处理单个消息处理期间取得和释放句柄。
获取设备环境句柄(HDC)的两种方式
一,这种方法有一定的局限性,需要在窗口过程函数处理WM_PAINT消息的那个case之后使用,设计到BeginPaint和EndPaint函数,总成对出现。
首先,是BeginPaint函数,将有关信息填充到一个PAINTSTRUCT结构中:
第一个参数为窗口句柄,第二个参数为指向结构体的指针,LP在匈牙利命名法中,是远指针。HDC BeginPaint( _In_ HWND hwnd, _Out_ LPPAINTSTRUCT lpPaint );
PAINTSTRUCT
hdc是用于绘制的句柄,fErase如果为非零值则擦除背景,否则不擦除背景,
typedef struct tagPAINTSTRUCT { HDC hdc; BOOL fErase; RECT rcPaint; BOOL fRestore; BOOL fIncUpdate; BYTE rgbReserved[32]; } PAINTSTRUCT, *PPAINTSTRUCT;
rcPaint通过制定左上角和右下角的坐标确定一个要绘制 的矩形范围,后面的参数是系统预留的,一般用不到。
我们平常就这样定义这个结构体:PAINTSTRUCT paintStruct;
如果BeginPaint函数执行成功,返回值为窗口的设备环境句柄,若失败,则为NULL
现在是EndPaint函数,表示指定窗口绘画过程结束。
第一个参数仍为句柄,上一个函数添的那个,第二个参数指向一个PAINTSTRUCT,一般添BeginPaint的那个。BOOL EndPaint( _In_ HWND hWnd, _In_ const PAINTSTRUCT *lpPaint );
调用实例:
HDC g_hdc; //全局设备环境句柄
……
case WM_PAINT: //客户区重绘消息
g_hdc=BeginPaint(hwnd,&paintStruct);
Game_Paint(); //我们自定义的一个函数,在里面有我们绘图相关的操作。
EndPaint(hwnd,&paintStruct);
ValidateRect(hwnd,NULL);
break;
ValidateRect 函数是我们经常遇到的一个函数,用于更新指定窗口的无效矩形区域,使之有效。
第一个参数,标识一个想要修改的一个函数,若为NULL,系统将更新所用的窗口,BOOL ValidateRect( _In_ HWND hWnd, _In_ const RECT *lpRect );
第二个参数,指向一个需要生效的矩形更新区域坐标的RECT结构体。
二。第二种方法
用GetDC函数或得句柄,
HDC GetDC( HWND hWnd );只要填上我们想要的句柄就可以了,不过在其获取了窗口的DC后,窗口的DC就处于被占用状态,使用完必须将其释放掉,此时用到ReleaseDC,
第一个句柄,第二个指要释放上下文环境的句柄。int ReleaseDC( _In_ HWND hWnd, _In_ HDC hDC );
调用实例:
HDC g_hdc;
g_hdc =GetDC(hWind); //获取窗口设备环境到g_hdc中
/*这里以g_hdc为媒介进行绘制*/
//绘制完成,准备退出
ReleaseDC(hWnd,g_hdc);
GDI基本几何绘图
创建画笔
HPEN是画笔对象的句柄数据类型, 我们可以用CreatePen函数
HPEN CreatePen(
int fnPenStyle,
int nWidth,
COLORREF crColor
);
第一个参数表示我们画笔的样式,实线虚线等。
第二个参数表示线条宽度
得三个参数表示线条颜色,RGB宏可以初始化 COLORREF
实例:创建一个宽度为二十的蓝色画笔,
COLORREF Colorbule=RGB(0,0,255);
HPEN Bluepen=CreatePen(PS_SOLID,20,Colorbule);
创建画刷
HBRUSH是画刷对象的句柄数据类型,
我们常用这两个API函数:CreateSolidBrush和CreateHatchBrush
HBRUSH CreateSolidBrush(
COLORREF crColor
);
唯一一个参数指定了画刷的颜色,取一个RGB值就可以了。
另一个为阴影画刷,具体查看msdn。
文字输出
BOOL TextOut( _In_ HDC hdc, //需要输出的DC句柄 _In_ int nXStart, //开始书写的X坐标 _In_ int nYStart, //开始书写的Y坐标 _In_ LPCTSTR lpString, //指向字符串的指针 _In_ int cchString //字符串的字符数 这里常配合C语言的strlen和weslen(对应字节宽度) );
实例:
wchar_t text[]=L"要有最朴素的生活,与最遥远的梦想,即使明日天高地远,路远马亡";
TextOut (g_hdc,30,150,text1,wcslen(text1));
进阶文字输出 DrawText.,在指定的矩形里写入格式化输入
int DrawText( _In_ HDC hDC, //句柄 _Inout_ LPCTSTR lpchText, //需要写入的字符串指针 ,必须以\0结尾 _In_ int nCount, //需要写入的字符串长度 _Inout_ LPRECT lpRect, //指向包含了绘制区域的矩形结构体的指针 _In_ UINT uFormat // 书写模式的标识,有多种定制表示可以选择,如文本左对齐右对齐);
设置文字颜色
SetTextCorlor(句柄,要设置的颜色)
如:SetTextCorlor(g_hdc,RGB(50,255,50),青绿色_
设置文字背景透明
GDI中,默认的文字输出背景为白色,为了能让文字输出的背景透明,我们需要调用一下SetBkMode函数
int SetBkMode( _In_ HDC hdc, _In_ int iBkMode //要设计的模式,通常设为TPANSPARENT,调用一次就好,以后的文字背景都是透明 );
字体的创建CreateFont 不需要细讲,用的比较少。
int SetBkMode( _In_ HDC hdc, _In_ int iBkMode );