GDI 设备环境句柄

Posted yenyuloong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDI 设备环境句柄相关的知识,希望对你有一定的参考价值。

WM_PAINT 消息的触发

Windows 程序在以下情况会触发WM_PAINT消息:

  • 窗口被移动导致被遮盖部分暴露出来
  • 用户调整窗口的大小(当窗口类的 style 字段被设置为 CS_HREDRAW 和 CS_VREDRAW)
  • 调用 ScrollWindow 或 ScrollDC 函数滚动客户区
  • 调用 InvalidateRect 或 InvalidateRgn 函数生成 WM_PAINT

获取设备环境句柄

需要在屏幕上绘图的时候,需要先获取到设备环境句柄,这里有两种方式:

1、调用 BeginPaint 函数(用于响应 WM_PAINT 消息)

第一个参数是当前的窗口句柄,第二个参数是 PAINTSTRUCT 结构的地址,它将返回一个设备环境句柄。BeginPaint 函数的原型如下:

HDC BeginPaint(
  HWND hwnd,            // 当前的窗口句柄
  LPPAINTSTRUCT lpPaint // PAINTSTRUCT 结构的地址
)

Windows 为每个窗口维护一个“绘制信息结构”,即 PAINTSTRUCT,这里给出了它的定义:

typedef struct tagPAINTSTRUCT { 
  HDC  hdc;             // 设备环境句柄,即 BeginPaint 函数的返回值
  BOOL fErase;          // 背景刷状态,如果为 TRUE,表示无效背景区域需要进行擦除,为 FALSE,表示已经擦除了无效区域的背景
  RECT rcPaint;         // 无效矩形边界,是一个 RECT 结构,包含 left、top、right、bottom 四个参数
  BOOL fRestore; 
  BOOL fIncUpdate; 
  BYTE rgbReserved[32]; 
} PAINTSTRUCT;

调用 BeginPaint 函数时,PAINTSTRUCT 结构中的字段将被自动填充。

当调用 BeginPaint 函数获得设备环境句柄,并处理 WM_PAINT 消息后,必须使用 EndPaint 函数释放获取到的设备环境句柄,该函数原型如下:

BOOL EndPaint(
  HWND hWnd,                  // 当前的窗口句柄
  CONST PAINTSTRUCT *lpPaint  // PAINTSTRUCT 结构的地址
);

源码片段示例:

// ......
case WM_PAINT:
    hdc = BeginPaint(hwnd, &ps);
    // 其他GDI代码
    EndPaint(hwnd, &ps);
    return 0;
// ......

2、调用 GetDC 函数(用于响应非 WM_PAINT 消息)

GetDC 函数只有一个参数,即当前的窗口句柄,它将设备环境句柄作为返回值返回。在使用完设备环境句柄后,必须调用 ReleaseDC 函数将其释放,它有两个参数,第一个是当前的窗口句柄,第二个是要释放的设备环境句柄。

源码片段示例:

// ......
    hdc = GetDC(hwnd);
    // 其他GDI代码
    ReleaseDC(hwnd, hdc);
    return 0;
// ......

GetDC / ReleaseDC 组合通常用于处理键盘消息或(与)鼠标消息。

需要注意的地方(小结)

  • WM_PAINT 消息的产生,表示窗口客户区需要重绘。
  • BeginPaint 函数返回的是无效矩形客户区(PAINTSTRUCT 结构中的 rcPaint 字段)的设备环境句柄,而 GetDC 函数返回的是整个客户区的设备环境句柄。
  • BeginPaint 函数调用后,无效矩形区域将变得有效化;而 GetDC 函数本身不会使客户区无效区域有效化,需要自行调用 ValidateRect 函数使客户区无效区域有效化。

以上是关于GDI 设备环境句柄的主要内容,如果未能解决你的问题,请参考以下文章

如何获取传递给 DrvEnablePDEV 的属于 GDI 引擎的“逻辑设备句柄”HDEV?

Windows程序设计--绘图基础

《逐梦旅程 WINDOWS游戏编程之从零开始》源码分析2——GDI

《windows程序设计》文本输出(02)

Winform API "user32.dll"中的函数

MFC里的DC是啥意思