Windows GDI编程快速入门
为什么需要有Windows GDI
Windows GDI是Windows图形设备的简写。其中图形设备有各种显示器、打印机等等。由于应用程序不能直接访问硬件资源,所以当我们需要使用图形设备时,就需要用到GDI。GDI是Windows图形界面的基础。
设备上下文
设备上下文(Device Context)是一种对象(数据结构),设定了图形输出的特性与属性,包含了绘图所需的设备类型、绘图属性和状态信息。关于DC里面到底有什么,Windows可以隐藏了这些内容,我们不能直接修改DC中的内容,而是通过Windows给出的各种函数修改DC。在Windows平台下,所有的图形操作都是通过DC来完成的。
这里所说的绘图操作,不仅仅是绘制点、线以及简单多边形,还包括了文本绘制,图像绘制等等。不要误以为绘图操作只是简单地绘制线条。
Windows编程中,要设备上下文,首先要定义设备上下文句柄HDC
。
HDC hdc = GetDC(hwnd);
HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
如上代码所示,我们可以使用GetDC
或CreateDC
函数来获得或创建一个设备上下文句柄(类似的函数还有BeginPaint
、GetWindowsDC
)。有了设备上下文句柄之后,我们就可以把hdc当作参数传递给具有输出功能的函数,这样我们就可以在图形设备上进行输出操作了。
设备类型
DC为我们抽象了具体的设备类型,让我们无需关心输出到设备的细节,只需要关心需要输出什么内容,具体是怎么输出的由DC和设备的驱动程序来完成。当我们需要在不同设备输出内容时,我们只要创建对应类型的DC即可,不同类型DC的操作方式都是统一的。
图形对象
一个DC中还包括一系列图形对象,通过修改图形对象,我们可以影响输出效果。
常用的图形对象包括字体、画笔、画刷、位图、区域、路径等等。除了路径和位图以外,当应用程序创建一个DC时,系统会为DC创建默认的图形对象。
通过创建图形对象,我们可以控制绘图的效果。
选择图形对象
应用程序创建(Create)新的图形对象,通过选入操作(Select Into)替换DC中原来的图形对象。
对于同一种图形对象,DC中只会有一个当前对象。通常使用SelectObject
函数为DC选择对象并替换原有对象。
HGDIOBJ SelectObject(
HDC hdc, //DC的句柄
HGDIOBJ hgdiobj //需要替换的图形对象的句柄
);
也可以通过特定的函数设置特定的图形对象,比如SetDCBrushColor
、GetDCBrushColor
、SetDCPenColor
等。
获取图形对象及信息
我们可以使用GetCurrentObject
函数获取DC中的指定图形对象信息。
HGDIOBJ GetCurrentObject(
HDC hdc,
UINT uObjectType
);
示例代码
接下来给出一份代码,帮助读者理解Windows GDI编程的有关概念
#include <Windows.h>
void GDIOut(HDC hdc)
{
HPEN hPen, hPenOld;//画笔图形对象
HBRUSH hbrush, hbrushOld;//画刷图形对象
BYTE bRed = 0;
BYTE hGreen = 0;
BYTE hBlue = 0;
COLORREF cPen = RGB(bRed, hGreen, hBlue);//定义画笔颜色
COLORREF cBrush = RGB(233, GetGValue(cPen), 255);//定义画刷颜色
hPen = CreatePen(PS_SOLID, 10, cPen);//创建画笔图形对象
hbrush = CreateSolidBrush(cBrush);//创建画刷图形对象
//选择对象
hPenOld = (HPEN)SelectObject(hdc, hPen);
hbrushOld = (HBRUSH)SelectObject(hdc, hbrush);
LineTo(hdc, 500, 500);
SelectObject(hdc, hPenOld);
Rectangle(hdc, 200, 200, 500, 500);
DeleteObject(hPen);
SelectObject(hdc, hbrushOld);
DeleteObject(hbrush);
}
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
_In_ PSTR lpCmdLine, _In_ int nCmdShow)
{
HDC hdc = GetDC(NULL);//设定参数为NULL,获取整个屏幕的设备上下文句柄
GDIOut(hdc);
ReleaseDC(NULL, hdc);//释放DC,使其它程序可以使用
return 0;
}
写在最后
本文只给出了画笔和画刷图形对象的使用,没有说明字体、位图、区域、路径等图形对象的使用,希望读者在了解了Windows GDI的基本概念(尤其是设备上下文)之后,能够自行查阅Windows官方文档并写出示例程序。
此外,MFC对Windows GDI进行了封装,之后会出一篇专门的文章说明MFC中的GDI编程。