第四章 文本输出

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负责如下的任务:

  • 处理滚动条中的所有鼠标消息
  • 当用户单击滚动条的时候,提供一种反向显示的闪烁
  • 当用户拖动滑块的时候,在滚动条内移动滑块
  • 向拥有滚动条的窗口的窗口过程发送滚动条消息

 

程序负责如下任务:

  • 初始化滚动条的位置和范围
  • 处理传送给窗口过程的滚动条消息
  • 更新滑块位置
  • 根据滚动条的变化更新客户区的内容

Windows程序设计(第五版)学习:第四章 文本输出的更多相关文章

  1. Windows程序设计(第五版)学习:第二章 Unicode简介

    第二章 Unicode简介 1,Windows通过双字节技术DBCS解决这个问题,代码页定义不同的字符集,称为ANSI字符集,比如日文为CP932,韩文为CP949,繁体中文为CP950,简体中文为C ...

  2. Windows程序设计(第五版)学习:第一章 起步

    第一章 起步 1,windows主要的三个动态库: kernel32.dll负责操作系统的传统工作,包括内存管理.文件输入以及任务管理等. user32.dll负责用户界面的操作,即所有窗口的管理 g ...

  3. Windows程序设计(第五版)学习:第三章 窗口与消息

        第三章 窗口与消息 1,windows窗口过程:应用程序所创建的每一个窗口都有一个与之关联的窗口过程,用于处理传递给窗口的消息. 2,窗口依据窗口类来创建.窗口类标识了用于处理传递给窗口的消息 ...

  4. C#高级编程 (第六版) 学习 第四章:继承

    第四章 继承 1,继承的类型 实现继承: 一个类派生于一个基类型,拥有该基类型所有成员字段和函数. 接口继承 一个类型只继承了函数的签名,没有继承任何实现代码.   2,实现继承 class MyDe ...

  5. python cookbook第三版学习笔记四:文本以及字符串令牌解析

    文本处理: 假设你存在一个目录,下面存在各种形式的文件,有txt,csv等等.如果你只想找到其中一种或多种格式的文件并打开该如何办呢.首先肯定是要找到满足条件的文件,然后进行路径合并在一一打开. pa ...

  6. 《Windows程序设计第5版》学习进度备忘

    书签:另外跳过的内容有待跟进 __________________学习资源: <Windows程序设计第5版珍藏版> __________________知识基础支持: _________ ...

  7. 《C++Primer》第五版习题答案--第一章【学习笔记】

    C++Primer第五版习题解答---第一章 ps:答案是个人在学习过程中书写,可能存在错漏之处,仅作参考. 作者:cosefy Date: 2022/1/7 第一章:开始 练习1.3 #includ ...

  8. 《Python学习手册 第五版》 -第14章 迭代和推导

    承接上一章for循环的讲解,迭代和推导,是对for循环的一种深入的探索和扩展 本章重点内容 1.迭代 1)什么是迭代?都有哪些分类 2)常规的使用方法 3)多遍迭代器VS单遍迭代器 2.列表推导 1) ...

  9. 《Python学习手册 第五版》 -第18章 参数

    在函数的定义和调用中,参数是使用最多喝最频繁的,本章内容就是围绕函数的参数进行讲解 本章重点内容如下: 1.参数的传递 1)不可变得参数传递 2)可变得参数传递 2.参数的匹配模式 1)位置次序:从左 ...

随机推荐

  1. sublime 的使用

    常见问题: ctrl+`快捷见弹不出console怎么办! 解决方法: 估计适合电脑其他软件的快捷键冲突了,在sublime里面重新设置下快捷键 点击菜单中Preferences下面的Key Bind ...

  2. union all 取代 select中的case when 提高查询效率

    首先union all不是适用于所有情况,其次,case when的可读性肯定要强.所以在不是特别在意性能的情况下, 可以考虑用case when. 再者,不是所有情况下的union all都要比ca ...

  3. redis 集群环境搭建-redis集群管理

    集群架构 (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽. (2)节点的fail是通过集群中超过半数的节点检测失效时才生效. (3)客户端与redi ...

  4. PHP如何批量生成手机号-使用PHP 如何生成一组不重复的手机号码?

    <?php //匹配手机号的正则表达式 #^(13[0-9]|14[47]|15[0-35-9]|17[6-8]|18[0-9])([0-9]{8})$# $arr = array( 130,1 ...

  5. 类似于C# using() java 语法

    From :   https://www.infoq.com/news/2010/08/arm-blocks try(Jedis jedis = jedisPool.getResource()){ S ...

  6. 12-factor

    简介 如今,软件通常会作为一种服务来交付,它们被称为网络应用程序,或软件即服务(SaaS).12-Factor 为构建如下的 SaaS 应用提供了方法论: 使用标准化流程自动配置,从而使新的开发者花费 ...

  7. 如何在linux sqlplus 下实现方向健和回退键操作而避免乱码

    在window下的sqlplus可以通过箭头键,来回看历史命令,用起来非常的方便.但是在linux里就没有这么方面了,错了一个命令,我们必须重新敲一次,辛苦了手指头. 通过rlwrap包实现linux ...

  8. php-fpm 老是warning 进程退出问题

    http://yangjunwei.com/a/723.html 分析Centos系统下LNMP频繁502 Bad Gateway问题 2012-01-28 杨俊伟 )     最近VPS总是出现 N ...

  9. MSClass 和setInterval 的并发,ajax定时有采集信息滚动显示

    setTimeout 用于延时器,只执行一次. setInterval:用于多次执行. //****************************************** 项目中引用到jquer ...

  10. 用友的凭证update

    select pk_glorgbook from bd_glorgbook where glorgbookcode='0100-0001';--0001N510000000006K4X ' and p ...