Windows 使用设备描述表来保存控制 GDI 函数在显示器上如何操作的“属性”。例如,在使用 TextOut 函数显示文本时,程序员不必指定文本的色彩和字体,Windows 从设备描述表获取这个信息。
程序获取一个设备描述表句柄时,Windows 用默认值设置所有的属性。
1. Windows 98 支持的设备描述表属性,程序可以改变或者获取任何一种属性。
设备描述表属性 |
默认值 |
修改该值的函数 |
获取该值的函数 |
Mapping Mode |
MM_TEXT |
SetMapMode |
GetMapMode |
Window Orign |
(0,0) |
SetWindowOrgEx |
GetWindowOrgEx |
OffsetWindowOrgEx |
Viewport Orign |
(0,0) |
SetViewportOrgEx |
GetViewportOrgEx |
OffsetViewportOrgEx |
Window Extents |
(1,1) |
SetWindowExtEx |
GetWindowExtEx |
SetMapMode |
ScaleWindowExtEx |
Viewport Extents |
(1,1) |
SetViewportExtEx |
GetViewportExtEx |
SetMapMode |
ScaleViewportExtEx |
Pen |
BLACK_PEN |
SelectObject |
SelectObject |
Brush |
WHITE_BRUSH |
SelectObject |
SelectObject |
Font |
SYSEMT_FONT |
SelectObject |
SelectObject |
Bitmap |
None |
SelectObject |
SelectObject |
Current Position |
(0,0) |
MoveToEx |
GetCurrentPositionEx |
LineTo |
PolylineTo |
PolyBezierTo |
Background Mode |
OPAQUE |
SetBkMode |
GetBkMode |
Background Color |
White |
SetBkColor |
GetBkColor |
TextColor |
Black |
SetTextColor |
GetTextColor |
Drawing Mode |
R2_COPYPEN |
SetROP2 |
GetROP2 |
Stretching Mode |
BLACKONWHITE |
SetStretchBltMode |
SetStretchBltMode |
Polygon Fill Mode |
ALTERNATE |
SetPolyFillMode |
GetPolyFillMode |
Intercharacter |
0 |
SetTextCharacterExtra |
GetTextCharacterExtra |
Spacing |
|
|
|
Brush Origin |
(0,0) |
SetBrushOrgEx |
GetBrushOrgEx |
Clipping Region |
None |
SelectObject |
GetClipBox |
SelectClipRgn |
IntersectClipRgn |
OffsetClipRgn |
ExcludeClipRect |
SelectClipPath |
2. 保存设备描述表
通常,在您调用 GetDC 或 BeginPaint 时,Windows 用默认值创建一个新的设备描述表句柄,您对属性所做的一切改变在设备描述表用 ReleaseDC 或 EndPaint 调用释放时,都会丢失。
如果您的程序需要使用非默认的设备描述表属性,则您必须在每次获取设备描述表句柄时初始化设备描述表:
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
[initialize device context attributes]
[paint client area of window]
EndPaint(hwnd,&ps);
return 0;
虽然通常情况下这种方法已经很令人满意了,但是您还可能想要在释放设备描述表之后,仍然保存程序中对设备描述表属性所做的改变,以便在下一次调用 GetDC 和 BeginPaint 时,它们仍然能够起作用。
为此,可在登陆(注册)窗口类时,将 CS_OWNDC 标志包含为窗口类的一部分:
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
现在基于这个窗口类所创建的每个窗口都将拥有自己的设备描述表,它一直存在,直到窗口被删除。如果使用了 CS_OWNDC 风格,就只需初始化设备描述表一次,可以在处理 WM_CREATE 消息期间完成这一操作:
case WM_CREATE:
hdc = GetDC(hwnd);
[initialize device context attributes]
ReleaseDC(hwnd,hdc);
这些属性在改变之前一直有效。
CS_OWNDC 风格只影响 GetDC 和 BeginPaint 获得的设备描述表,不影响其他函数(如 GetWindowDC)获得的设备描述表。
即使使用了 CS_OWNDC,您仍然应该在退出窗口过程之前释放设备描述表。
在某些情况下,您可能想改变某些设备描述表属性,用改变后的属性进行绘图,然后恢复原来的设备描述表。要简化这一过程可以像下面这样做:
// 保存设备描述表的状态
idSaved = SaveDC(hdc);
// now,可以改变一些属性,在想要回到调用 SaveDC 前存在的设备描述表时,调用:
RestoreDC(hdc,idSaved);
// 可以在调用 RestoreDC 之前调用 SaveDC 数次
RestoreDC 和 SaveDC 的另一种使用方式:
// 调用 SaveDC 时,不需要保存返回值:
SaveDC(hdc);
// 然后,您可以更改某些属性并再次调用 SaveDC,要将设备描述表恢复到一个已经保存的状态,调用:
RestoreDC(hdc,-1);
// 这就将设备描述表恢复到最近由 SaveDC 函数保存的状态中