图形设备接口(GDI Graphics Device Interface)是windows的子系统,他负责在视频显示器和打印机上显示图形
GDI 原理: 显示器驱动程序或者打印机驱动程序+GDI命令 = 想要的输出 .dll(驱动程序一般被称为例程,不同的设备有不同的驱动程序)
图形输出设备分为两大类,光栅设备和矢量设备,大多数PC的输出设备时光栅设备,这意味着他们以点模式来表示图像,这类设备包括显示器设备,点阵打印机,激光打印机,矢量设备使用线来绘制图像,通常局限于绘图仪
GDI函数调用
- 获取(创建)和释放(清除)设备描述表函数 DC
- 获取有关设备描述表信息的函数 GetTextMetrics
- 绘制函数 TextOut();
- 设置和获取设备描述表参数的函数 用SetTextColor 来指定TextOut所绘制的文本色彩
- 使用GDI对象 的函数 普通画笔 设置一个特殊的逻辑画笔(GDI对象)
GDI图元
- 直线和曲线 线条时所用矢量图绘制系统的基础(包含圆弧,贝塞尔曲线等)
- 填充区域 被线条包围的区域
- 位图 位图是位的矩形数组,这些位对应于显示设备上的像素,他们是光栅图形的基础工具,位图通常用于在视频显示器或者打印机上显示复杂的(一般都是真实的)图像,位图还可以用于必须快速绘制的小图像,如图标,鼠标光标(十四,十五章详细讨论)
- 文本 (十七章详细讨论)
获取DC
- WM_PAINT消息下 hdc=BeginPaint(hwnd,&ps);
- 不需要 WM_PAINT消息 hdc = GetDc(hwnd);
- 获取整个窗口 hdc = GetWindowsDc(hwnd);
- 前三个都是特定窗口,hdc= CreateDc()用于获取整个窗口的DC(也可获取打印机的DC 十三章) DeleteDc();(成对使用)
- 获取一些相关信息而不进行绘画,可以使用hdc = CreateIC。
- 获取一个位图DC hdcMem = CreateCompatibleDC();可以将位图选进内存设备描述表,然后使用GDI函数在位图上绘图
- 获取元文件hdcMeta = CreateMetaFile() hmf = CloseMetaFile(hdcMeta);
获取设备描述表信息
GetSystemMetrics(获取系统索引)是一个计算机函数,该函数只有一个参数,称之为「索引」,这个索引有75个标识符,通过设置不同的标识符就可以获取系统分辨率、窗体显示区域的宽度和高度、滚动条的宽度和高度。
GetDeviceCaps函数可以访问使用设备描述表的设备数据,应用程序指定相应设备描述表的句柄和说明该函数访问数据类型的索引来访问这些数据。
iValue = GetDeviceCaps(hdc,iIndex);
DEVCAPS1.C
/*------------------------------------------------------------------------
DEVCAPS1.C -- Device Capabilities Display Program No. 1
(c) Charles Petzold, 1998
----------------------------------------------------------------------*/
#include <windows.h>
#define NUMLINES ((int) (sizeof devcaps / sizeof devcaps [0]))
struct
{
int iIndex ;
TCHAR * szLabel ;
TCHAR * szDesc ;
}
devcaps [] =
{
HORZSIZE, TEXT ("HORZSIZE"),TEXT ("Width in millimeters:"),
VERTSIZE, TEXT ("VERTSIZE"),TEXT ("Height in millimeters:"),
HORZRES, TEXT ("HORZRES"), TEXT ("Width in pixels:"),
VERTRES, TEXT ("VERTRES"), TEXT ("Height in raster lines:"),
BITSPIXEL, TEXT ("BITSPIXEL"),TEXT ("Color bits per pixel:"),
PLANES, TEXT ("PLANES"), TEXT ("Number of color planes:"),
NUMBRUSHES, TEXT ("NUMBRUSHES"), TEXT ("Number of device brushes:"),
NUMPENS, TEXT ("NUMPENS"), TEXT ("Number of device pens:"),
NUMMARKERS, TEXT ("NUMMARKERS"), TEXT ("Number of device markers:"),
NUMFONTS, TEXT ("NUMFONTS"), TEXT ("Number of device fonts:"),
NUMCOLORS, TEXT ("NUMCOLORS"), TEXT ("Number of device colors:"),
PDEVICESIZE, TEXT ("PDEVICESIZE"), TEXT ("Size of device structure:"),
ASPECTX, TEXT ("ASPECTX"), TEXT ("Relative width of pixel:"),
ASPECTY, TEXT ("ASPECTY"), TEXT ("Relative height of pixel:"),
ASPECTXY, TEXT ("ASPECTXY"), TEXT ("Relative diagonal of pixel:"),
LOGPIXELSX, TEXT ("LOGPIXELSX"), TEXT ("Horizontal dots per inch:"),
LOGPIXELSY, TEXT ("LOGPIXELSY"), TEXT ("Vertical dots per inch:"),
SIZEPALETTE, TEXT ("SIZEPALETTE"), TEXT ("Number of palette entries:"),
NUMRESERVED, TEXT ("NUMRESERVED"), TEXT ("Reserved palette entries:"),
COLORRES, TEXT ("COLORRES"), TEXT ("Actual color resolution:")
} ;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("DevCaps1") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc= WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow ( szAppName, TEXT ("Device Capabilities"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxChar, cxCaps, cyChar ;
TCHAR szBuffer[10] ;
HDC hdc ;
int i ;
PAINTSTRUCT ps ;
TEXTMETRIC tm ;
switch (message)
{
case WM_CREATE:
hdc = GetDC (hwnd) ;
GetTextMetrics (hdc, &tm) ;
cxChar = tm.tmAveCharWidth ;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
cyChar = tm.tmHeight + tm.tmExternalLeading ;
ReleaseDC (hwnd, hdc) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
for (i = 0 ; i < NUMLINES ; i++)
{
TextOut ( hdc, 0, cyChar * i,
devcaps.szLabel,
lstrlen (devcaps.szLabel)) ;
TextOut ( hdc, 14 * cxCaps, cyChar * i,
devcaps.szDesc,
lstrlen (devcaps.szDesc)) ;
SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
TextOut (hdc, 14*cxCaps+35*cxChar, cyChar*i, szBuffer,
wsprintf (szBuffer, TEXT ("%5d"),
GetDeviceCaps (hdc, devcaps.iIndex))) ;
SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
}
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
设备大小
1 磅大约是1/72英寸,
关于色彩
全色24位,rgb(8,8,8)
高色彩 16位 rgb(5,6,5)
返回色彩平面个数 iPlanes = GetDeviceCaps (hdc , PLANES)
返回每个像素的色彩位数 iBitsPixel = GetDeviceCaps(hdc,BITSPIXEL);
大多数彩色图形显示设备要么使用多个色彩平面要么每像素使用多个位,但不能同时二者兼容;换句话说,两个调用必有一个返回1,视频适配器能够显示的色彩数可以用如下公式来计算 iColor = 1<<(iPlanes* iBitsPixel)
设备描述表属性
默认值,更改默认值的函数,获取该值的函数