Windows编程入门-设备环境句柄

设备环境(也被称为DC)实际上是GDI内部维护的一个数据结构。设备环境与特定的显示设备(例如显示器或打印机)相关联。对于视频显示,设备环境通常与屏幕上的一个特定的窗口相关联。
设备环境中的某些值是图形“属性”。这些属性决定了GDI绘图函数的工作细节。例如在TextOut函数中,设备环境的属性决定着文本得颜色、文本背景的颜色、函数的参数x和y如何映射到窗口的客户区,以及Windows用什么字体显示文本。程序在绘制前必须获取一个设备环境句柄。在获取句柄后,Windows会在内部的设备环境结构中填入默认的属性值。当程序完成了对客户区的绘制后,它必须释放设备环境句柄。在程序释放句柄之后,这个句柄不再有效并且不能再被使用。程序必须在处理同一条消息的过程中获取句柄和释放句柄,不能再两条消息中间传递一个设备句柄。唯一的例外是通过CreateDC函数创建的设备环境句柄。
Windows应用程序需要在屏幕上绘图时,通常有两种方法获取设备环境句柄。
方法一:通过BeginPaint和EndPaint函数
这种方法可以在处理WM_PAINT消息时使用。这两个函数需要两个参数:一个是窗口句柄,这是窗口消息处理过程的参数;另一个是一个类型为PAINTSTRUCT结构的变量的地址,程序通常将这个变量命名为ps,在窗口过程中定义如下:
PAINTSTRUCT ps;
在处理WM_PAINT消息时,窗口过程首先调用BeginPaint函数。这个函数通常会擦去无效区域的背景以便绘图。它同时还会填充ps结构的各个字段。函数的返回值就是设备环境句柄。通常将它保存在一个名为hdc的变量中。这个变量在窗口过程中定义如下:
HDC hdc;
HDC数据类型定义为32位无符号整数。此后程序可以调用任何一个需要设备环境句柄的GDI函数了,例如TextOut。调用一次EndPaint函数将释放设备环境句柄。通常,处理WM_PAINT消息的代码如下所示:
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
[使用GDI函数]
EndPaint(hwnd, &ps);
return 0;
窗口过程在处理WM_PAINT消息时必须成对地调用BeginPaint和EndPaint。如果窗口过程不处理WM_PAINT消息,WM_PAINT消息就会被传送给Windows默认的窗口过程DefWindowProc。在DefWindowProc中,WM_PAINT消息处理的代码如下:
case WM_PAINT:
BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
这里除了将原来的无效区域有效化以外,在BeginPaint和EndPaint的中间不包含其他代码。
以下代码是错误的:
case WM_PAINT:
return 0;
由于部分客户区是无效的,Windows才会在消息队列中放置一条WM_PAINT消息。除非调用BeginPaint和EndPaint函数对(或者ValidateRect),否则Windows不会将那个区域有效化。因此Windows将会不停的发送WM_PAINT消息,直到永远。
方法二:通过BeginPaint和EndPaint函数
尽管最好让程序在处理WM_PAINT消息时才更新整个客户区,但有时也会发现在处理非WM_PAINT消息时绘制部分客户区也是很有用的。有些时候,还需要设备环境句柄用作其他用途,例如获取设备环境的信息。
这时可以调用GetDC函数来获得窗口客户区的设备环境句柄,在使用完以后,调用ReleaseDC函数将它释放:
hdc = GetDC(hwdn);
[使用GDI函数]
ReleaseDC(hwnd, hdc);
与BeginPaint和EndPaint类似,GetDC和ReleaseDC必须成对使用。在处理一条消息时,当调用GetDC函数后,应该在退出窗口过程之前调用ReleaseDC。不要在处理一条消息时调用GetDC,然后在处理另一条消息时调用ReleaseDC。
与从BeginPaint函数返回的设备环境句柄不同,从GetDC返回的设备环境句柄中的裁剪矩形时整个客户区。这意味着你可以在客户区的任意部分绘制,而不仅仅是在无效矩形里,也就是说如果不存在无效矩形也没有关系。与BeginPaint不同,GetDC不会将无效区域有效化。如果需要将整个客户区有效化,可以像下面这样调用函数:
ValidateRect(hwnd,NULL);
通常,GetDC和ReleaseDC函数用于处理键盘消息(例如在字处理程序中)或者鼠标消息(例如绘图程序中)。使用这两个函数,程序可以在收到用户的键盘或者鼠标输入时及时地绘制客户区,而不必为了生成WM_PAINT消息去可以使客户区的一部分无效化。但是,即使程序在处理非WM_PAINT消息时进行了绘制,它仍然必须收集足够的信息以便在收到WM_PAINT时能更新显示。
另一个与GetDC类似的函数是GetWindowDC。GetDC返回的是窗口客户区的设备环境句柄,GetWindowDC返回的则是整个窗口的设备环境句柄。例如程序可以使用从GetWindowDC返回的设备句柄在窗口的标题栏输出,相应的,程序也必须要处理WM_NCPAINT(非客户区绘制)消息。
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值