从WM_DISPLAYCHANGE消息的角度谈谈分辨率

  众所周知,WM_DISPLAYCHANGE是当Windows显示器分辨率改变之后发送给所有的窗口的消息。但是不知道你有没有想过,显示器的分辨率不是固定的吗?为什么会有这条消息呢?

  这里就要说一下逻辑分辨率和物理(设备)分辨率了:

  我们说某个品牌的显示器的分辨率为80DPI(Dots Per Inch),是指在显示器的有效显示范围内,显示器的的显像设备可以在每英寸荧光屏上产生80个光点。举个例子来说,一台14英寸的显示器(荧光屏对角线长度为14英寸),其点距为0.28mm,那么:显示器分辨率=25.3995mm/inch÷0.28mm/Dot≈90DPI(1 inch=25.3995mm)。   显示器出厂时一般并不标出表征显示器分辨率的DPI值,只给出点距,我们根据上述公式即可算出显示器的分辨率。根据我们算出的DPI值,我们进而可以推算出显示器可支持的最高显示模式。假设该14英寸显示器荧光屏有效显示范围的对角线长度为11.5英寸,因显示器的水平方向和垂直方向的显示比例为4:3,故可设有效显示范围水平宽度为4X英寸,垂直高度为3X英寸,根据数学上的勾股定理,可得X=11.5÷5=2.3英寸。所以有效显示范围宽度为2.3×4=9.2英寸,垂直高度为2.3×3=6.8英寸。最高显示模式约为:800(9.2×90)×600(6.8×90),这时是用一个点(Dot)表示一个像素(pixel)。

  这里点的概念并非是书中所说的字体点的概念,而是指:

  DPI中的点(Dot)与图像分辨率中的像素(Pixel)是容易混淆的两个概念,DPI中的点可以说是硬件设备最小的显示单元,而像素则既可是一个点,又可是多个点的集合。

  而书中所指的字体点的概念则是指:

  在传统的排版中,字体字符的大小是由“点值”(point size 亦称磅值)来表示的。一点大约是1/72英寸(inch)。在计算机排版中,1点通常假定正好是1/72英寸。

  从这里我们可以很清楚的知道,设备分辨率,或者说这里的显示器的物理分辨率,就是指每英寸的物理硬件可显示的点数。而像素则是一个一个或多个点形成的一个集合单位,但从编程的角度讲,编程人员所能操纵的最小的单位就是像素。所以其实在我看来,像素其实是可以理解为一个逻辑分辨率所拥有的概念。由以上设备分辨率的概念对比《Windows程序设计》中分辨率的概念:

  在本书中,“分辨率”被阉割定义为每度量单位(通常是英寸)中含有的像素数。

  不难理解,这里的分辨率其实指的是逻辑分辨率,其中像素正是程序所能操纵的最小逻辑单位。由此也可以引出这个问题的答案了:系统软件控制了逻辑分辨率的大小,定义为每英寸的像素数。但显然这个逻辑分辨率是受到物理分辨率(即每英寸的点数)的限制的,最大的情况即为一个点代表一个像素,此时逻辑分辨率和物理分辨率是相同的,而当一个像素包含多个点时(由软件算法控制调整),逻辑分辨率就会变得不同。这也正是Windows中分辨率可以调整的原因。

  然后说一下有关GetDeviceCaps函数中获取的分辨率和尺寸的关系。

  首先,当我们以HORZRES或VERTRES为参数调用GetDeviceCaps()函数时,你所得到的是显示器的(逻辑)水平分辨率或(逻辑)物理分辨率。这没有问题。而我们又知道,当以LOGPIXELSX和LOGPIXELSY为参数调用GetDeviceCaps()函数时候,所得到的则是“每英寸的像素数”(当然,如果不具有正方形像素,所得到的两个值可能会不同。),而这两个值则是由用户在【控制面板】的【显示】中选择的以每英寸的像素点数为单位的假定的分辨率。这也没有问题,而在WindowsNT 中,以VERTSIZE或HORZSIZE为参数调用GetDeviceCaps()函数所得到值则是由以上两者计算出来的,我们知道,这两个值所表示的是指的“以毫米为单位的物理屏幕宽度(高度)”。这也正是《Windows程序设计》中所解释的东西。因为它并不是真正的物理尺寸,而是指对于用户来说(因为LOGPIXELSX和LOGPIXELSY为参数调用GetDeviceCaps()函数所得的值是用户所选择的(很大程度上是用户认为最舒适的分辨率)值)最合适的“物理尺寸”,所以对于程序而言,这正是它所需要的。在这种情况下,无论是连接多个显示设备还是连接投影仪,都会显示出来对用户非常合适的分辨率大小(其实就是如果不合适就可以直接通过上述的【显示】中更换值)。

  这正是《Windows程序设计》中所说的“并不是真正的物理尺寸”,和“如果程序需要视频显示器的实际物理尺寸怎么办?,最好的解决办法可能是使用一个对话框来实际要求用户输入他们”的原因。

原文地址:https://www.cnblogs.com/FWFC/p/8185655.html

时间: 2024-10-03 17:23:48

从WM_DISPLAYCHANGE消息的角度谈谈分辨率的相关文章

【NLP】基于机器学习角度谈谈CRF

基于机器学习角度谈谈CRF 作者:白宁超 2016年8月3日08:39:14 [摘要]:条件随机场用于序列标注,数据分割等自然语言处理中,表现出很好的效果.在中文分词.中文人名识别和歧义消解等任务中都有应用.本文源于笔者做语句识别序列标注过程中,对条件随机场的了解,逐步研究基于自然语言处理方面的应用.成文主要源于自然语言处理.机器学习.统计学习方法和部分网上资料对CRF介绍的相关的相关,最后进行大量研究整理汇总成体系知识.文章布局如下:第一节介绍CRF相关的基础统计知识:第二节介绍基于自然语言角

从JVM内存管理的角度谈谈JAVA类的静态方法和静态属性

在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JVM的内存分为两部分:Stack和Heap.(stack和heap都是位于RAM中的) stack(栈)是JVM的内存指令区.stack管理很简单,push一定长度字节的数据或者指令,stack指针压栈相应的字节位移:pop一定字节长度数据或者指令,stack指针弹栈.stack的速度很快,管理很简单,并

关于AngularJS 1.x 从Flex程序员角度谈谈我的一些看法(一)

用AngularJS开发了2个很小的项目,多少积累了点经验,这里稍微谈下我一个Flex程序员的角度对它的看法. 你可能会有疑问什么是AngularJS?为什么我们要用它?它有什么用 1:它是google开发的一套前台MVC开发框架,这个框架的健康度很好,社区完善,资料也好找 2:一般说到JS框架,我们第一个想到的就是JQuery.AngularJs其实和它的前驱者JQuery做着差不多的事情,都是对html元素进行动态操作. 两者最大不同之处在于理念,JQuery是操作Dom对象的一套强大工具,

以计算机科学的角度谈谈科班出身和非科班出身的一些看法

在当今的计算机行业里面从事计算机软件,硬件等设计开发工作的人其实有相当一部分大学时所学的专业并不是计算机科学,我们在此暂且简单的把这个行业里面的人分为学习计算机专业的科班,以及其他非科班两类.本文意在简单讨论一下对于不同问题的想法,这两类人到底会有什么区别,无意触及任何人,所以请不要对号入座. 当然科班出身的也存在一部分没有好好学的,不在本文讨论之内,非科班出身的也有自学了相关的全部知识技术,而且理解的相当深入的人,那么本文也将这类人算成是科班出身的. 想写这篇文章已经很久了,因为看到了太多的人

从法学的角度谈谈“接口”--基于C#

接口(interface),这是C#的基础之一,是实现多态的必要工具. 然而,由于中文中"接口"的多意性,使得我在学习的时候陷入了一个误区,大大困扰了我的学习进度. 因为我在学习这个知识时,第一反应的是下面这种接口: 看网上的视频,老师们首先举的例子也是这种.然而,这种举例是不恰当的.因为,这种接口英文是input/output,也就是所谓的I/O.顾名思义,这种接口的主要作用是传递输入和输出信息.不同的I/O实际上是规定了不同的连接方式和信息传播方式. 那该怎么理解C#中的接口呢?最

关于AngularJS 1.x 从Flex程序员角度谈谈我的一些看法(二)

再来看看关于Angularjs其它一些特性 1.依赖注入这个是老概念了,Angularjs通过参数的形式把实例传递到调用的模块中去,例如下图 灰色的Service 实例就作为一个参数传递到业务逻辑Controller中去的,从而分层,这种方式在Flex Parsley中也是非常常见的,只不过Flex中常用是先用config文件来定义注入关系. Angularjs中又n种注入声明的方法,controller filter directive factory config run.前三个分别用于An

从浏览器渲染的角度谈谈html标签的语义化

大家都看过报纸或者杂志的排版,里面最主要的一些概念,就是版面的分割,标题的分级等等,web页面作为一种信息展示的形式,其基本的排版形式是从报纸杂志等传统媒介借鉴过来的,看一看html一些常用的tag就可以知道,比如h1-h6,p,img等等. html的语义化从字面的意思来看,就是你选用的tag要尽可能的符合它适用的场景.为什么要语义化呢?可以从浏览器开始说起,报纸和杂志作为信息的载体是通过印刷机将其呈现在大众面前的,同理html是通过浏览器的界面将其展现在用户面前的.html页面展现在我们面前

windows消息常量值

WM_NULL = 0WM_CREATE = 1应用程序创建一个窗口WM_DESTROY = 2一个窗口被销毁WM_MOVE = 3移动一个窗口WM_SIZE = 5改变一个窗口的大小WM_ACTIVATE = 6一个窗口被激活或失去激活状态:WM_SETFOCUS = 7获得焦点后WM_KILLFOCUS = 8失去焦点WM_ENABLE = 10改变enable状态WM_SETREDRAW = 11设置窗口是否能重画 WM_SETTEXT = 12应用程序发送此消息来设置一个窗口的文本WM_

WINDOWS特有的消息常量标识符

'========================================'WINDOWS特有的消息常量标识符'========================================Public Const WM_NULL = &H0&Public Const WM_CREATE = &H1& '应用程序创建一个窗口Public Const WM_DESTROY = &H2& '一个窗口被销毁Public Const WM_MOVE = &