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);

如上代码所示,我们可以使用GetDCCreateDC函数来获得或创建一个设备上下文句柄(类似的函数还有BeginPaintGetWindowsDC)。有了设备上下文句柄之后,我们就可以把hdc当作参数传递给具有输出功能的函数,这样我们就可以在图形设备上进行输出操作了。

设备类型

DC为我们抽象了具体的设备类型,让我们无需关心输出到设备的细节,只需要关心需要输出什么内容,具体是怎么输出的由DC和设备的驱动程序来完成。当我们需要在不同设备输出内容时,我们只要创建对应类型的DC即可,不同类型DC的操作方式都是统一的。

图形对象

一个DC中还包括一系列图形对象,通过修改图形对象,我们可以影响输出效果。

常用的图形对象包括字体、画笔、画刷、位图、区域、路径等等。除了路径和位图以外,当应用程序创建一个DC时,系统会为DC创建默认的图形对象。

通过创建图形对象,我们可以控制绘图的效果。

选择图形对象

应用程序创建(Create)新的图形对象,通过选入操作(Select Into)替换DC中原来的图形对象。

对于同一种图形对象,DC中只会有一个当前对象。通常使用SelectObject函数为DC选择对象并替换原有对象。

HGDIOBJ SelectObject(
    HDC hdc,            //DC的句柄
    HGDIOBJ hgdiobj     //需要替换的图形对象的句柄
);

也可以通过特定的函数设置特定的图形对象,比如SetDCBrushColorGetDCBrushColorSetDCPenColor等。

获取图形对象及信息

我们可以使用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编程。

posted @ 2025-03-31 16:25  XueZhou  阅读(27)  评论(0)    收藏  举报