Windows GDI的基本概念

为什么需要有Windows GDI

Windows GDI是Windows图形设备的简写。其中图形设备有各种显示器、打印机等等。由于应用程序不能直接访问硬件资源,所以当我们需要使用图形设备时,就需要用到GDI。GDI是Windows图形界面的基础。在编程语言上,就是通过Windows提供的一组函数进行GDI编程。

当然,想要实现类似的功能还可以使用其它库:GDI+、OpenGL、DirectX、Windows Image Acquisition 等可以实现类似或更高级的功能。Windows GDI是最基本的库。

Windows GDI可以实现以下的功能:

  • 获取输出设备的输出,可以截获当前显示器显示的内容,包括整个屏幕、指定窗口或其他任意部分。
  • 控制显示器的输出内容,在显示器的指定位置输出指定的内容。应用程序可以指定输出的位置、颜色、大小、区域。
  • 可以以点、线条(直线、曲线)、图形、位图、文字等方式输出。
  • 可指定输出内容的颜色、大小、位置。
  • 可将输出内容进行变形、变色、字体的处理等。

设备上下文

在进行具体的GDI编程之前,有必要说说设备上下文这一关键概念。

*设备上下文(Device Context)*是一种对象(数据结构),设定了图形输出的特性与属性,包含了绘图所需的设备类型、绘图属性和状态信息。在Windows平台下,所有的图形操作都是通过DC来完成的。在系统中可以有多个DC,每DC都与一个特定的设备相关联。一个DC所关联的设备的驱动定义了过此 DC 进行的图形输出操作(文字输出、绘制、填充等)会被哪个设备(包括显示器、打印机、绘图仪)或设备的子区域(窗口客户端等)所接收。

这里所说的设备,不仅包括显示器、打印机等,一个窗口的客户区也算是设备;这里所说的绘图操作,不仅仅是绘制点、线以及简单多边形,还包括了文本绘制,图像绘制等等。不要误以为绘图操作只是简单地绘制线条。

设备上下文有四种类型:分别是“显示”、“打印机”、“内存”、“信息”。应用程序在进行图像输出时,只需要关心 DC 的类型,如果需要将图像输出到特定的设备只需创建相应类型的DC即可。而对不同类型的DC的操作方式都是统一的,应用程序不需要关注设备硬件的异同,无论哪种设备数据接口、哪种通信数据的格式等都是同样的处理,GDI的接口都是相同的。

说了这么多,DC一句话概括就是应用程序与硬件设备之间的桥梁。

创建DC

Windows编程中,要设备上下文,首先要定义设备上下文句柄HDC

HDC hdc = GetDC(hwnd);//参数是一个窗口句柄
HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);//第一个参数代表了这是一个显示设备上下文

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

图形对象

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

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

HDC hdc = GetDC(hWnd);//定义设备上下文
HPEN hPen = CreatePen(PS_SOLID, 4, RGB(0, 0, 0));//定义画笔图形对象
SelectObject(hWnd, hPen);//为设备上下文选择图形对象

接下来更加详细地介绍图形对象。

选择图形对象

应用程序创建(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;
}

写在最后

本文只给出了GDI编程中基本绘图的示例,希望读者在了解了Windows GDI的基本概念(尤其是设备上下文)之后,能够自行查阅Windows官方文档并写出其它功能的示例程序。后面我也会写文章介绍GDI的其它应用。

此外,MFC对Windows GDI进行了封装,之后会出一篇专门的文章说明MFC中的GDI编程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值