多显示器同样可以通过顶点坐标(Top,Left)和宽高来描述它的尺寸。顶点坐标是相对于桌面坐标系原点的,也就是相对于主显示器的顶点。
工作区的概念比较简单,它是指显示器中除了任务条和其他停靠在桌面上的窗体之外的矩形区域。
Windows为多显示器应用程序的开发提供了一组API。VCL将这些API封装起来,非常自然的融入整个Framework之中,使得开发多显示器应用程序变得非常简单。下面就介绍与之相关的内容。
在VCL之中大家最熟悉的恐怕非TCustomForm莫属了,它是所有窗体的基类。TCustomForm的Position属性用来设置窗体的现实位置,其可选值中有两个是值得关心的:一个是poScreenCenter,当Position属性被设置成poScreenCenter时,窗体会显示到主显示器的中央;另一个是poDesktopCenter,当Position属性被设置成poDesktopCenter时,窗体显示在整个桌面的中央。如果把这个属性设成poDesktopCenter,程序又运行在一个有多台显示器的系统上,那么这个窗口就会显示在两个显示器之间,会给用户带来不必要的麻烦。因此即使我们的程序不是针对多显示器而设计的,也应该细心处理这个值。另外一个属性是DefaultMonitor,它的作用与Position有些类似,决定窗口最初显示在哪个显示器内。它有四个备选值:dmDesktop,dmPrimary,dmMainForm和dmActiveForm。他们的含义如下:
Value
Meaning
dmDesktop
不特别处理
dmPrimary
将窗体显示到第一个显示器上。这又是一个陷阱,字面上理解是主显示器,而事实上它是指Screen.Monitor[0]这个显示器。
dmMainForm
将窗体显示到主窗体所在的显示器
dmActiveForm
将窗体显示到桌面上活动窗体所在的显示器
工作区的概念比较简单,它是指显示器中除了任务条和其他停靠在桌面上的窗体之外的矩形区域。
Windows为多显示器应用程序的开发提供了一组API。VCL将这些API封装起来,非常自然的融入整个Framework之中,使得开发多显示器应用程序变得非常简单。下面就介绍与之相关的内容。
在VCL之中大家最熟悉的恐怕非TCustomForm莫属了,它是所有窗体的基类。TCustomForm的Position属性用来设置窗体的现实位置,其可选值中有两个是值得关心的:一个是poScreenCenter,当Position属性被设置成poScreenCenter时,窗体会显示到主显示器的中央;另一个是poDesktopCenter,当Position属性被设置成poDesktopCenter时,窗体显示在整个桌面的中央。如果把这个属性设成poDesktopCenter,程序又运行在一个有多台显示器的系统上,那么这个窗口就会显示在两个显示器之间,会给用户带来不必要的麻烦。因此即使我们的程序不是针对多显示器而设计的,也应该细心处理这个值。另外一个属性是DefaultMonitor,它的作用与Position有些类似,决定窗口最初显示在哪个显示器内。它有四个备选值:dmDesktop,dmPrimary,dmMainForm和dmActiveForm。他们的含义如下:
Value
Meaning
dmDesktop
不特别处理
dmPrimary
将窗体显示到第一个显示器上。这又是一个陷阱,字面上理解是主显示器,而事实上它是指Screen.Monitor[0]这个显示器。
dmMainForm
将窗体显示到主窗体所在的显示器
dmActiveForm
将窗体显示到桌面上活动窗体所在的显示器
TCustomForm还有一个只读的共有属性(没有Published)Monitor,它提供了访问窗体所在显示器实例的引用,这个值与DefaultMonitor是有紧密的关联的。
那么怎么在使窗体在不同的显示器之间移动呢?这并不困难,估计你也想到了。这里介绍两种方法:
第一, 可以设置TCustomForm的Top和Left使窗体显示在桌面的任意位置。正如前面所述,桌面是由所有显示器组成的。它们有共同的坐标系,所以可以根据显示器的逻辑位置决定窗体的位置。现在的问题是如何获得每个显示器的逻辑位置和尺寸,后面就会介绍。
第二, 可以调用TCustomForm的MakeFullyVisible方法将窗体完全显示到指定的显示器之中。可以通过这个方法避免窗口在两个显示器上各显示一部分。
刚才我们提出了一个问题:如何获得每个显示器的逻辑位置和尺寸。为了解答这个问题,需要再介绍连个类:TScreen和TMonitor。
TScreen描述与显示设备有关的一些信息,我们主要关心与显示器逻辑位置和尺寸有关的信息。其他方面的内容可以在Delphi的文档中获知。在程序运行的时候VCL自动创建一个TScreen的实例——全局变量,所以通常情况下程序是不需要实例化TScreen的。
TScreen有一组形如Desktop*的属性,这些属性描述了整个桌面的尺寸和各顶点坐标。还有对开发多显示器应用程序有重要意义的连个属性:MonitorCount和Monitors。通过这两个属性我们可以枚举出系统中所有的显示器(TMonitor)的实例,每个实例都反映了相应显示器的相对位置和分辨率等信息(后文会详细说明)。
在TScreen的众多属性之中,我们会找到Height和Width这两个属性。要特别警惕它们不是指整个桌面的尺寸,而是指主显示器的高度和宽度。这非常容易让人产生错觉,无以为是整个桌面的尺寸。与之类似的还有形如WorkArea*的一组属性,它们描述了主显示器的工作区域的尺寸和各顶点坐标。是不是觉得少了什么?为什么没有获取主显示器相对位置的属性?原因就像前面所说的:Windows是以主显示器的左上角为坐标系原点的,所以主显示器的相对位置必然是(0,0)。
除了这些属性之外,还要介绍TScreen的三个成员函数:MonitorFromPoint,MonitorFromRect和MonitorFromWindow。顾名思义,他们分别是获取个坐标、某个区域和某个窗口所在的显示器的实例。在实际的开发中可能也会用到。
最好,再来看看TMonitor类。它封装了物理显示器的有关属性——这些属性都是只读的。下表简单介绍了这些属性的含义,它们对编写多显示器应用程序非常有用:
属性
说明
Handle
获取该显示器的Windows句柄
MonitorNum
获取显示器的编号
Primary
获取该显示器是否是主显示器。又且仅有一个显示器的Primary是True。
Top
获取显示器的上边界
Left
获取显示器的左边界
Height
获取显示器的高度
Width
获取显示器的宽度
BoundsRect
获取显示器的对应桌面的区域,它与上面四个属性是等价的
WorkareaRect
获取显示器的工作区对应桌面的区域。
清楚地了解了TScreen和TMonitor之后,前面的问题也就自然解决了。到这里,本文已经介绍了开发多显示器应用程序所需的全部知识。相信你可以利用这些知识开发出非常实用的 软件产品。
附:你可以 下载一个DEMO,帮助理解本文。
http://my.6to23.com/yukin2010/download/MultiMonitorDemo.rar
那么怎么在使窗体在不同的显示器之间移动呢?这并不困难,估计你也想到了。这里介绍两种方法:
第一, 可以设置TCustomForm的Top和Left使窗体显示在桌面的任意位置。正如前面所述,桌面是由所有显示器组成的。它们有共同的坐标系,所以可以根据显示器的逻辑位置决定窗体的位置。现在的问题是如何获得每个显示器的逻辑位置和尺寸,后面就会介绍。
第二, 可以调用TCustomForm的MakeFullyVisible方法将窗体完全显示到指定的显示器之中。可以通过这个方法避免窗口在两个显示器上各显示一部分。
刚才我们提出了一个问题:如何获得每个显示器的逻辑位置和尺寸。为了解答这个问题,需要再介绍连个类:TScreen和TMonitor。
TScreen描述与显示设备有关的一些信息,我们主要关心与显示器逻辑位置和尺寸有关的信息。其他方面的内容可以在Delphi的文档中获知。在程序运行的时候VCL自动创建一个TScreen的实例——全局变量,所以通常情况下程序是不需要实例化TScreen的。
TScreen有一组形如Desktop*的属性,这些属性描述了整个桌面的尺寸和各顶点坐标。还有对开发多显示器应用程序有重要意义的连个属性:MonitorCount和Monitors。通过这两个属性我们可以枚举出系统中所有的显示器(TMonitor)的实例,每个实例都反映了相应显示器的相对位置和分辨率等信息(后文会详细说明)。
在TScreen的众多属性之中,我们会找到Height和Width这两个属性。要特别警惕它们不是指整个桌面的尺寸,而是指主显示器的高度和宽度。这非常容易让人产生错觉,无以为是整个桌面的尺寸。与之类似的还有形如WorkArea*的一组属性,它们描述了主显示器的工作区域的尺寸和各顶点坐标。是不是觉得少了什么?为什么没有获取主显示器相对位置的属性?原因就像前面所说的:Windows是以主显示器的左上角为坐标系原点的,所以主显示器的相对位置必然是(0,0)。
除了这些属性之外,还要介绍TScreen的三个成员函数:MonitorFromPoint,MonitorFromRect和MonitorFromWindow。顾名思义,他们分别是获取个坐标、某个区域和某个窗口所在的显示器的实例。在实际的开发中可能也会用到。
最好,再来看看TMonitor类。它封装了物理显示器的有关属性——这些属性都是只读的。下表简单介绍了这些属性的含义,它们对编写多显示器应用程序非常有用:
属性
说明
Handle
获取该显示器的Windows句柄
MonitorNum
获取显示器的编号
Primary
获取该显示器是否是主显示器。又且仅有一个显示器的Primary是True。
Top
获取显示器的上边界
Left
获取显示器的左边界
Height
获取显示器的高度
Width
获取显示器的宽度
BoundsRect
获取显示器的对应桌面的区域,它与上面四个属性是等价的
WorkareaRect
获取显示器的工作区对应桌面的区域。
清楚地了解了TScreen和TMonitor之后,前面的问题也就自然解决了。到这里,本文已经介绍了开发多显示器应用程序所需的全部知识。相信你可以利用这些知识开发出非常实用的 软件产品。
附:你可以 下载一个DEMO,帮助理解本文。
http://my.6to23.com/yukin2010/download/MultiMonitorDemo.rar