zoukankan      html  css  js  c++  java
  • GDI 设备环境句柄(2)

    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 函数使客户区无效区域有效化。
  • 相关阅读:
    document.getElementById("mytxt").style.left=""style.left在IE的FF中注意
    asp.net 用户控件中 使用相对路径的解决方法 图片路径问题(用户控件、图片路径) ,ResolveUrl
    探索 Block (一) (手把手讲解Block 底层实现原理)
    iOS 多线程开发 (概念与API简介)
    iOS 性能小点
    iOS runtime (二)(runtime学习之AutoCoding源码分析)
    探索 NSRunLoop (二)(NSRunLoop 自己动手实现SimpleRunLoop)
    iOS NSNotificationCenter (自己实现一个通知中心XMCNotificationCenter)
    iOS runtime (三)(runtime学习之YYModel源码分析)
    iOS runtime(一)(runtime 分析理解)
  • 原文地址:https://www.cnblogs.com/yenyuloong/p/9076528.html
Copyright © 2011-2022 走看看