???????客户区:整个应用程序窗口中未被标题栏、窗口边框以及可选的菜单栏、工具栏、状态栏和滚动条占据的部分驱动。就是可以由程序任意书写和传递可视信息的部分。
1、绘制和刷新
???????在Windows中,只能在窗口的客户区绘制文本和图形,而且不能确保在客户区内显示的内容会一直保留到程序有意地改写它。
1.1 WM_PAINT消息
???????大多数Windows程序在WinMain中进入消息循环之前的初始化期间都要调用函数UpdateWindow。Windows利用这个机会给窗口过程发送一个wm_paint消息,通知必须绘制客户区。在这之后窗口过程要在任何时候都准备好处理其他的wm_paint消息。发生以下事件时窗口过程会接收到一个wm_paint消息:
场景 | 说明 |
---|
在用户移动窗口或显示窗口时,窗口中先前被隐藏的区域重新可见 | | 用户改变窗口的大小 | | 程序使用ScrollWindow或ScrollDC函数滚动客户区的一部分 | | 程序使用InvalidateRect或InvalidateRgn函数显式产生WM_PAINT消息 | | Windows擦除覆盖可部分窗口的对话框或消息框 | 可能 | 菜单选啦出来,接着被释放 | 可能 | 显示工具提示 | 可能 |
???????某些情况下,Windows总是保存它所覆盖的显示区域,接着恢复它。例如鼠标光标穿越客户区或图表拖过客户区。 ???????程序应该组织成可以保留绘制客户区需要的所有信息,以便在有需求的时候进行绘制。
1.2 有效矩形和无效矩形
???????虽然窗口过程接收到WM_PAINT消息后就会准备更新整个客户区,但实际上只需要更新一个较小的区域。同样,在擦除对话框之后,需要重画的也只是先前被对话框遮住的矩形区域。这个区域称为“无效区域”或“更新区域”。因为有无效区域的存在,Windows才会将一个WM_PAINT消息放在应用程序的消息队列中,只有客户区存在失效区域时窗口才会接收WM_PAINT消息。Windows不会将多个WM_PAINT消息都放在消息队列中。 ???????窗口过程可以通过调用IInvalidateRect使客户区内的矩形失效。如果消息队列中存在一个WM_PAINT消息,Windows将计算新的无效区域;否则它将一个新的WM_PAINT消息放入消息队列中。在接收到消息时窗口过程可以获取调用GetUpdateRect在人恶化时候获取无效矩形的坐标。窗口过程在调用了BeginPaint之后,整个客户区就变成了有效,也可以通过程序调用ValidateRect函数使客户区内的任意矩形区域变为有效。若ValidateRect使整个无效区域变为有效,那当前队列中的任意WM_PAINT消息都会被删除。
2、GDI
???????GDI:图形设备接口。每个GDI函数都需要一个设置描述表句柄作为第一个参数。
2.1 设备描述表
???????设备描述表,简称DC,实际上是GDI内部保存的数据结构。设备描述表与特定的显示设备相关,其中有些值是图形化的“属性”,定义了一些GDI绘图函数工作情况的特殊内容。在需要绘图的时候必须先获取设备描述表句柄。在获取句柄之后Windows用默认的属性值填充内部设备描述表结构,如果需要修改这些属性的值可以通过对应的GDI函数实现,当客户区绘图完毕之后,必须释放设备描述表句柄。句柄被释放后不再有效且不能再使用,因此程序必须在处理单个消息期间获取和释放句柄(除了CreateDC产生的句柄),设备描述表句柄不能在两个消息之间保存。
2.2 获取设备描述表句柄的方法
2.2.1 BeginPaint和EndPaint函数
???????一般在处理WM_PAINT消息时使用这种方法。我们知道,窗口过程在处理WM_PAINT消息时首先会调用BeginPaint,该函数在准备绘制时导致无效区域的背景被擦除,其返回的值是设备描述表句柄,通常被保存在HDC的变量中,接下来就可以使用该值进行操作GDI函数,操作完成后使用EndPaint函数释放设备描述表句柄。 ???????在处理WM_PAINT消息时,必须成对调用BeginPaint和EndPaint,不管是自定义的窗口过程还是Windows默认的窗口过程DefWindowProc,因为Windows将WM_PAINT消息放到队列就说明客户区存在无效区域需更新,若不调用则不会将无效区域变为有效。这种情况下Windows就会发送另一个WM_PAINT消息并一直发送下去。
2.2.2 GetDC函数
???????虽然大多数都是在处理WM_PAINT消息期间更新整个客户区,但是也会存在处理非WM_PAINT消息期间需要绘制客户区的某个区域的需求,或者希望将设备描述表句柄用于其他目的等。这种情况就可以使用GetDC获取句柄了,在使用完成之后调用ReleaseDC释放即可。处理一个消息时GetDC和ReleaseDC也是必须成对使用的,和BeginPaint的不同有:1)GetDC返回的设备描述表句柄具有一个剪取矩形,等于整个客户区,可以在客户区的某一个部分绘图,而不只是在无效矩形上绘图;2)GetDC不会使任何无效区域变为有效,如需要变为有效,可以调用validateRect。
3、系统字体
???????在Windows中默认字体是“系统字体”,标识符SYSTEM_FONT,是Windows用来在标题栏、菜单栏和对话框中显示文本串的默认字体。系统字体是一种点阵字体。但是要注意,系统字体的大小取决于Windows锁运行的视频显示器的分辨率,在某些情况下取决于用户选取的系统字体的大小。
|