第四章 文本输出
1,客户区:整个应用程序窗口中没有被标题栏、边框、菜单栏、工具栏、状态栏和滚动条占用的区域。简而言之,客户区就是窗口中程序可以在上面绘制并向用户传达可视化信息的区域。
2,大多数Windows程序在WinMain函数初始化过程中会在进入消息循环之前调用UpdateWindow函数,Windows利用这个机会向窗口过程发送最初的WM_PAINT消息,这个消息通知窗口过程绘制客户区。
以下任何一个事件发生时,窗口过程都会收到一条WM_PAINT消息
- 用户移动窗口,导致原来被覆盖的部分窗口暴露出来
- 用户调整窗口的大小(窗口的类型设定为CS_HREDRAW和CS_VREDRAW)
- 程序调用ScrollWindow或ScrollDC函数滚动客户区
- 程序调用InvalidateRect或InvalidateRgn函数显式生成WM_PAINT
以下情况,Windows可能会发送WM_PAINT,或者恢复自动保存的
- Windows关闭一个覆盖了部分窗口的对话框或消息框
- 下拉菜单被拉下然后收回
- 显示提示信息
少数情况,Windows总是会保存被覆盖部分的显示内容,然后恢复。
- 鼠标指针在客户区内移动
- 在客户区内拖动图标
3,有效矩形和无效矩形
收到WM_PAINT后,需要绘制部分客户区,需要重新绘制的部分称为"无效区域"或者"更新区域"。在客户区中有一个无效区域将导致Windows在应用程序消息队列中放置一条WM_PAINT消息。只有当程序客户区的一部分失效时,窗口过程才会接受WM_PAIN消息。调用的时机是无效区域大于绘制信息结构中保存的最小矩形面积时。在等候时,如果又有一部分失效了,会重新更新绘制信息结构,而不会再次放置一个WN_PAINT消息。
窗口过程可以通过调用InvalidateRect函数来强制使自己客户区中的一个矩形失效。可以通过GetUpdateRect函数来获得这些坐标。可以使用ValidateRect使客户区有效。
如果InvalidateRect最后一个参数设为FALSE, 随后调用的BeginPaint不会擦除背景。
4,设备环境
设备环境实际上是GDI内部维护的一个数据结构。对于视频显示,设备环境通常与屏幕上的一个特定窗口相关联。设备环境与特定的显示设备相关联。程序在绘制前必须获取一个设备环境句柄。
获得设备环境的方法:
(1)BeginPaint(),最后EndPaint,只能重绘裁剪区域,InvalidateRect可以绘制整个区域
(2)GetDC后ReleaseDC,绘制整个客户区
5,TextOut函数
TextOut(hdc,x,y,psText,iLength)
设备环境的属性决定了文本显示的特性。例如,设备环境中的一个属性决定了文本的颜色,默认是黑色,设备环境同时默认文本的背景颜色为白色。当程序输出文本时,将用这个颜色填充每个字符周围的矩形区域,称为"字符框"。
文本的背景色和窗口类中设定的背景色不是一样的。窗口类中的背景色是Windows用来擦除客户区的刷子,并不是设备环境的一部分。iLength为字符串的字符数,控制字符显示为空心或者实心方块,不使用\0而是使用iLength计算长度。
参数x,y决定了输出字符串的起始位置,(x,y)为第一个字符相对于客户区左上角的坐标。
类似于TextOut的GDI绘图函数中,传给函数的坐标值为逻辑坐标。
Windows有各种映射模式来决定怎样将GDI的逻辑坐标转化为显示器上的物理像素坐标。
设备环境同时定义了一个裁剪区域。从GetDC得到的设备环境句柄中,该裁剪区域就是整个客户区,从BeginPaint得到的设备环境句柄中,该裁剪区域是无效区域。在调用TextOut时,Windows不会将显示字符落在裁剪区域的外部。
设备环境同时还定义了在调用TextOut函数时Windows使用的字体。默认字体称为系统字体或者SYSTEM_FONT,系统字体是Windows在标题栏、菜单栏和对话框中使用的默认字体。
系统字体是一种点阵字体,每个字符由像素点构成。某种程度上,系统字体中字符的大小取决于显示器的大小,系统字体的设计要求能够至少在显示器上起码显示25行80列字符。
6,字符大小
Windows最低的分辨率为640x480,
可以通过GetTextMetrics函数来获取字体的尺寸。GetTextMetrics需要一个设备环境句柄来返回该设备环境中字体的信息。TEXTMETRICS结构中有字符尺寸的各种值。字段值的单位取决于设备环境的映射模式。
TEXTMETRIC结构中几个参数表示的值如下图所示。tmExternalLeading代表行间距,tmAveCharWidth代表小写字符的平均宽度,tmMaxCharWidth代表最宽字符的宽度,大写字符的平均宽度一般为tmAveCharWidth的1.5倍。
7,滚动条
要让窗口包含滚动条,需要在CreateWindow中的第三个参数窗口风格设置为WS_HSCROLL或者WS_VSCROLL,滚动条的具体图例见下图:
每个滚动条都有相应的范围和位置,范围为一对整数,分别表示滚动条最小值和最大值。位置是指滑块在范围中所取的值,顶端或者左端,最小值,右端或者下端为最大值。
滚动条的默认范围为0-100,可以设置范围:
SetScrollRange(hwnd,ibar, iMin, iMax, bRedraw),
可通过SetScrollPos设置滚动条的位置。
程序在使用滚动条的时候,windows负责如下的任务:
- 处理滚动条中的所有鼠标消息
- 当用户单击滚动条的时候,提供一种反向显示的闪烁
- 当用户拖动滑块的时候,在滚动条内移动滑块
- 向拥有滚动条的窗口的窗口过程发送滚动条消息
程序负责如下任务:
- 初始化滚动条的位置和范围
- 处理传送给窗口过程的滚动条消息
- 更新滑块位置
- 根据滚动条的变化更新客户区的内容