坐标和多少个函数的用法表达,客户坐标系

By admin in 美高梅手机版4858 on 2019年1月17日

多年来在学Win32的编程,看的是《Windows程序设计第5版》一书,这本书是台湾人翻译的,有些译法和陆上不雷同,书中还有部分荒唐的地点,很多时候需要中英文对照阅读,下载请点击

Windows应用程序绘制图形时行使的是一种逻辑单位,每个逻辑单位的高低由映射格局决定,
这么些逻辑单位既可以与设施单位(屏幕或打印机上的一个像素点)相同,也可以是一种物理单
位(如毫米),仍可以够是用户自定义的一种单位。在Windows应用程序中,只要与输出有关联,都
要使用映射格局。本文的目标是协助读者了然映射形式的片段基本知识,并对在运用中不时
出现的一部分题材提议解决方案。

(1)Windows坐标系列
Windows坐标系分为逻辑坐标系和设备坐标系二种,GDI襄助这二种坐标系。一般而言,
GDI的文本和图纸输出函数使用逻辑坐标,而在客户区移动或按下鼠标的鼠标地点是运用配备坐标。
<1>逻辑坐标系是面向DC的坐标系,那种坐标不考虑现实的装置项目,在绘图时,Windows会依据当下设置的映照情势将逻辑坐标转换为设备坐标。
<2>设备坐标系是面向物理设备的坐标系,这种坐标以像素或设施所能表示的纤维长度单位为单位,X轴方向向右,Y轴方向向下。设备坐标系的原点地点(0,
0)不限制在装置显示区域的左上角。

(1)Windows坐标体系

一、映射形式基本知识
当Windows应用程序在其客户区绘制图形时,必须付出在客户区的职务,其地点用x和y
多个坐标表示,x表示横坐标,y表示纵坐标。在具有的GDI绘制函数中,这多少个坐标使用的是一
种”逻辑单位”。当GDI函数将出口送到某个物理设备上时,Windows将逻辑坐标
转换成设备坐标(如屏幕或打印机的像素点)。逻辑坐标和设备坐标的转移是由映射情势决
定的。映射形式被储存在装置条件中。GetMapMode函数用于从设备条件得到当前的照耀格局,SetMapMode函数用于安装设备条件的炫耀模式。
1.逻辑坐标

 

Windows坐标系分为逻辑坐标系和装置坐标系二种,GDI襄助那两种坐标系。一般而言,GDI的文件和图片输出函数使用逻辑坐标,而在客户区移动或按下鼠标的鼠标地点是运用配备坐标。

好了,下边起头正文:

逻辑坐标是单独于设备的,它与设备点的深浅无关。使用逻辑单位,是促成”所见即所得”的基础。当程序员在调用一个画线的GDI函数LineTo,画出25.4mm(1英寸)
长的线时,他并不需要考虑输出的是何种设备。若设备是VGA显示器,Windows自动将其转化为96个像素点;若设备是一个300dpi的激光打印机,Windows自动将其转会为300个像素点。

设备坐标系分为屏幕坐标系、窗口坐标系和客户区坐标系两种互动独立的坐标系。
1.屏幕坐标系以屏幕左上角为原点,一些与成套屏幕有关的函数均运用屏幕坐标,如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow()。弹出式菜单使用的也是屏幕坐标。
2.窗口坐标系以窗口左上角为坐标原点,它概括窗口标题栏、菜单栏和工具栏等限定。
3.客户区坐标系以窗口客户区左上角为原点,重要用来客户区的绘图输出和窗口音讯的拍卖。鼠标音讯的坐标参数使用客户区坐标,CDC类绘图成员函数使用与客户区坐标对应的逻辑坐标。

<1>逻辑坐标系(Logical
Coordinate)是面向DC的坐标系,这种坐标不考虑实际的配备项目,在绘图时,Windows会依照当下设置的炫耀情势将逻辑坐标转换为设备坐标。

在看到GDI(GDI Graphic Device
Interface图形设备接口)
照耀格局这一节的时候,书中又是逻辑坐标,又是装备坐标,又是视口,窗口,又是视埠什么的,搞得人头都大了。即使自己今日还没有完全读懂,不过本人深感我已经抓住了明白那个事物的主线,下边的事物就作为自己的笔记吧:

2.装备坐标

 

<2> 设备坐标(Device Coordinate)又称作物理坐标(Physical
Coordinate),是指输出设备上的坐标。平时将屏幕上的设备坐标称为屏幕坐标。设备坐标用对象距离窗口左上角的程度距离和垂直距离来指定对象的地方,是以像素为单位来表示的,设备坐标的X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角,不限定在装置突显区域的左上角。

1.逻辑坐标和装备坐标

Windows将GDI函数中指定的逻辑坐标映射为装备坐标,在所有的装备坐标体系中,单位以像素点为准,水平值从左到右增大,垂直值从上到下增大。

(2)坐标之间的相互转换
 编程时,有时需要遵照当前的具体状况举办二种装备坐标之间或与逻辑坐标的相互转换。
1.MFC提供了多个函数CDC::DPtoLP()和CDC::
LPtoDP()用于装备坐标与逻辑坐标之间的并行转换。
2.MFC提供了四个函数CWnd::ScreenToClient()和CWnd::ClientToScreen()用于屏幕坐标与客户区坐标的相互转换。

配备坐标系分为屏幕坐标系、窗口坐标系和客户区坐标系二种互动独立的坐标系。

 
 首先,逻辑坐标这多少个名词就让很三个人心神不定,确实,不可以“望文生义”地领悟的翻译就不是好翻译 
 ——鲁迅。哈哈,开个噱头,大家要明了这六个东西,首先要想到即便您要用Win32要绘制一个事物,该如何是好吗?比如绘制一个矩形,假使我们调用的是Rectangle(hdc,30,20,50,80),(那么些函数的用法是Rectangle(hdc,left,top,right,bottom),我叫雷锋,不用谢我)。能够见到,跟很多GDI函数一样,这些函数里面使用了广大数字,坐标。让大家想起一下完小文化,绘制一个事物,不仅应该搞了解她的尺寸,还应当搞了然他的单位,那么这里的30,20,50,80的单位是哪些啊?很六个人会说,是像素!这一个答案是对的,可是又不全对。事实上,Windows默认的映照模式(Mapping
Mode,简称就是MM)是MM_TEXT,在MM_TEXT映射情势(TEXT实际上跟文字没有多大关系,是那种映射形式下的坐标方向,从左到右,从上到下,跟文字阅读模式相同)下,那多少个单位确实是像素。实际上,逻辑坐标和配备坐标的区分就在于他们的单位不雷同!

Windows中概括以下3种配备坐标,以满意各样不同需要:

 

  • 屏幕坐标系以屏幕左上角为原点,一些与任何屏幕有关的函数均运用屏幕坐标,如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow()。弹出式菜单使用的也是屏幕坐标。
  • 窗口坐标系以窗口左上角为坐标原点,它概括窗口标题栏、菜单栏和工具栏等限制。
  • 客户区坐标系以窗口客户区左上角为原点,紧要用来客户区的绘图输出和窗口音讯的处理。鼠标音讯的坐标参数使用客户区坐标,CDC类绘图成员函数使用与客户区坐标对应的逻辑坐标。

下边我们拿出一个公式

(1)客户区域坐标,包括应用程序的客户区域,客户区域的左上角为(0,0)。

GetWindowRect()得到的是在屏幕坐标系下的RECT(即以屏幕左上角为原点)
美高梅手机版4858,GetClientRect()拿到的是在客户区坐标系下的RECT(即以所在窗口左上角为原点,去掉了标题栏统计,仅仅是个分寸,再次回到值的左上角永远为0,0) 
  
CRect rect;

上面二种都是来得设备的物理坐标,它们在屏幕上用真实的物理像素表示

         
 美高梅手机版4858 1

(2)屏幕坐标,包括所有屏幕,屏幕的左上角为(0,0)。屏幕坐标用在WM_MOVE音信中(对于非子窗口)以及上面的Windows函数中:CreateWindow和MoveWindow(都对此非子窗口)、GetMessage、GetCursorPos、GetWindowRect、WindowFromPoint和SetBrushOrg中。用函数ClientToScreen和ScreenToClient可以将客户区域坐标转换成屏幕区域坐标,或反之。

GetWindowRect(&rect);

  • 屏幕坐标 Screen   coordinates:   原点(0,0)位于屏幕的左上角  
  • 窗口坐标 Window   coordinates:  
    原点(0,0)位于窗口的左上角(包括非客户区,如标题条)  
  • 坐标和多少个函数的用法表达,客户坐标系。客户区坐标 Client-window   coordinates:  
    原点(0,0)位于客户窗口的左上角

要讲上边的公式,就要先说一下视口(Viewport 四川译作视埠)和窗口(Window
黑龙江译作视窗)

(3)全窗口坐标,包括一个主次的总体窗口,包括标题条、菜单、滚动条和窗口框,窗口的左上角为(0,0)。使用GetWindowDC得到的窗口设备条件,可以将逻辑单位转换成窗口坐标。

ScreentoClient(&rect);

  逻辑坐标是GDI函数在屏幕上出示数据所用的坐标,逻辑坐标除非与物理坐标相关联,否则没有义。windows依靠映射格局解释逻辑坐标。比如缺省的情势为MM_TEXT,该形式下,物理坐标与逻辑坐标是一对一的关系。

率先,不要被这四个名字迷惑了,那多少个坐标是跟映射有关的,跟屏幕坐标系,窗口坐标系,客户端坐标系是相对独立的五个知识。

3.逻辑坐标与设备坐标的转移模式

不相同

      逻辑坐标(Logical
Coordinate)是系统作为记录的坐标。在缺省的情势(MM_TEXT)下,逻辑坐标的可行性和单位与装备坐标的自由化和单位一律,也是以像素为单位来
表示的,X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。逻辑坐标和装备坐标尽管在缺省情势下其数值也不至于相同,除了在偏下二种情形下:
  1. 窗口为非滚动窗口
  2.
窗口为滚动窗口,但垂直滚动条位于滚动边框的最下边,水平滚动条位于最左端,但即使运动了滚动条这三种坐标就不平等了。
  在VC中鼠标坐标的坐标地方用配备坐标表示,但所有GDI绘图都用逻
坐标表示,所以用鼠标绘图时,那么必须将设备坐标转换为逻辑坐标,可以利用CDC
函数DptoLP()将装备坐标转化为逻辑坐标,同样可以用LptoDP()将逻辑坐标转化为装备坐标。

实际上公式拿出来,学数学的小伙伴是不是就懂了大半了,这一个公式非凡关键,了解了这么些公式,前边的很多事物就能掌握,首先,公式中的Window,WinOrg,WinExt,就是带了Win的事物,就是使用的逻辑坐标的值,就跟GDI函数中的一样,逻辑坐标的单位或者是像素(MM_TEXT映射)、毫米(单位是0.1mm,在MM_LOMETRIC映射下)等等等等(看下图).

炫耀格局定义了Windows怎么样将GDI函数中指定的逻辑坐标映射为装备坐标。要持续探讨映射模式大家要介绍Windows有关映射形式的一部分术语:大家将逻辑坐标所在的坐标系称为”窗口”,将设备坐标所在的坐标系称为”视口”。

CRect rect;

(2)坐标之间的交互转换

美高梅手机版4858 2

“窗口”依赖于逻辑坐标,可以是像素点、分米或程序员想要的别样条件。

GetClient(&rect);
举个例如:有个单文档程序

编程时,有时需要遵照当下的具体情况举办三种配备坐标之间或与逻辑坐标的互动转换。

身为咱们在调用Win32函数绘图的时候,要通晓自己使用的单位(遵照映射模式确定的)。因为绘图函数里的数值,使用的就是这个单位,即便默认的MM_TEXT映射情势拔取的单位尽管像素,不过众多时候任何单位也很有用,比如您要做一个屏幕尺子的时候,你要用尺子量一下物体有几分米。尺子上的刻度就足以用任何的照射形式来画。不过屏幕在彰显的时候却不可以只知道逻辑坐标几毫米啊,屏幕得知道具体的像素地方才行啊!这这几个时候,就需要动用下边的公式转换了。讲到这里,公式里的ViewExt/WinExt是什么样看头就很显著了。那就是在此时此刻逻辑坐标系下(比如几毫米,打比方哈),实际上是下面映射形式表格里的单位)对应的设施坐标应该是有些个像素!这样转换之后,得到实际的Viewport,就是该逻辑点在屏幕上的职务。

“视口”看重于设备坐标(像素点)。通常,视口和客户区域等同。但是,假使程序员用GetWindowDC或CreateDC获取了一个设施条件,则视口也足以指全窗口坐标或屏幕坐标。点(0,0)是客户区域的左上角。x的值向右扩充,y的值向上增加。

CRect rect;

MFC提供了五个函数CDC::DPtoLP()和CDC::
LPtoDP()用于装备坐标与逻辑坐标之间的相互转换。

就此说视口和窗口实际上是意味着的如出一辙块区域,只不过是因为单位和原点的不同,需要举行映射,逻辑单位就是窗口,就是Window,就是像素,分米,英寸,就是给人用的单位,就是设备无关的单位,设备单位就是视口,就是Viewport,就只可以是像素,就是给配备用的单位,确定的一毫米,在不同的配备上的像素数可能会有分别,所以是装备相关的单位。

对于有所映射格局,Windows都用下边多少个公式将窗口坐标转换成视口坐标:

View调用GetWindwoRect(&rect),
得到的坐标是:左上角(33,99),右下角(1040,524),这是View绝对于屏幕的坐标,当调用ScreenToClient(&rect),rect变成为:左上角(-2,-2),右上角(1007,423),-2,-2是client和window之间的间隔差–border。

MFC提供了两个函数CWnd::ScreenToClient()和CWnd::ClientToScreen()用于屏幕坐标与客户区坐标的互动转换。

 

  1. xViewport = (xWindow – xWinOrg) * (xViewExt / xWinExt) + xViewOrg
  2. yViewport = (yWindow – yWinOrg) * (yViewExt / yWinExt) + yViewOrg

rect =
CRect(0,0,1,1),当调用ClientToScreen(&rect),rect变成为:左上角(35,101),右上角(36,102),这是也有2个单位的border的功力。

(3)映射格局

要注意的是在上述的5映射形式下,ViewExt/WinExt的比例都是现已确定了,不可能更改的,如果要改变多少个值,只能在MM_ISOTROPIC和MM_ANISOTROPIC映射模式下采纳SetViewportExtEx()和SetWindowExtEx()更改。而且这多少个函数在下边5种炫耀模式下无效。

中间,(xWindow,yWindows)是待转换的逻辑点,(xViewport,yViewport)是更换后的设备点。假如设备坐标是客户区域坐标或全窗口坐标,则Windows在画一个对象前,还必须将那一个坐标转换成屏幕坐标。

Frame调用GetWindowRect(&rect),拿到的坐标是:左上角(25,25),右下角(1050,551),那是Frame相对于屏幕的坐标,与View的坐标有反差是因为Frame还有菜单栏,工具栏。

照耀格局确定了在绘制图形时所依照的坐标系,它定义了逻辑单位的莫过于尺寸、坐标增长势头,所有映射形式的坐标原点均在设施出口区域(如客户区或打印区)的左上角。另外,对于一些映射模式,用户还足以自定义窗口的长度和增幅,设置视图区的物理范围。

末了,这多少个映射格局,视口原点(ViewOrg),窗口原点(WinOrg)等,都是设备内容(DC
Device
Context,又译作装置内容、设备上下文等)的性质,设备内容其实就是您绘制的区域。有三种BeginPaint(在WM_PAINT时绘制无效区域),GetDC是客户端区域(在更新时绘制整个客户区域),GetWindowsDC是整整窗口区域(可以绘制包括窗口标题栏,菜单栏区域)。这么些文化细讲的话又是另一篇博客了

这多少个公式使用了各自指定窗口和视口原点的点:(xWinOrg,yWinOrg)是逻辑坐标的窗口原点;(xViewOrg,yViewOrg)是装备坐标的视口原点。在缺省的配备条件中,这多少个点均安装为(0,0),但它们得以更改。此公式意味着,逻辑点(xWinOrg,yWinOrg)总被映射为设备点(xViewOrg,yViewOrg)。

 

Windows定义了8种炫耀模式,见下表。

 

Windows还是可以将视口(设备)坐标转换为窗口(逻辑)坐标:

(3).映射形式

 

 

  1. xWindow=(xViewport-xViewOrg)*(xWinExt/xViewExt)+xWinOrg
  2. yWindow=(yViewport-yViewOrg)*(yWinExt/yViewExt)+yWinOrg

     
映射情势规定了在绘制图形时所按照的坐标系,它定义了逻辑单位的实际上尺寸、坐标增长方向,所有映射形式的坐标原点均在设备出口区域(如客户区或打印区)的左上角。另外,对于一些映射格局,用户还足以自定义窗口的尺寸和幅度,设置视图区的大体范围。
Windows定义了8种炫耀格局,见下表。
炫耀格局使得程序员可不用考虑输出设备的有血有肉设备坐标系,而在一个联结的逻辑坐标系中举办图片的绘图。

注意:
先是,要牢记两点:
1。设备坐标的(0, 0)点一贯是客户区的左上角。 
2。我们在绘图时指定的点全体都是逻辑坐标点。
坐标转换
调用CDC::LPtoDP可以将逻辑坐标转换为设备坐标;
高用CDC::DPtoLP可以将配备坐标转换为逻辑坐标;
什么日期用怎么样坐标系
 可以认为CDC的所有成员函数皆以逻辑坐标作为参数 
 可以认为CWnd的富有成员函数皆以设施坐标作为其参数 

就此假设记住起头的公式,拿到正确的应和的参数,就足以画出需要的图片。

可以使用Windows提供的多少个函数DPtoLP和LPtoDP在装备坐标及逻辑坐标之间交互转换。

照耀方法(Mapping Mode)
 逻辑单位               坐标轴方向
MM_TEXT(默认情势)
 1 pixel                X轴正方向朝右,Y轴正方向朝下

享有入选测试操作中都应该考虑配备坐标。区域的概念应利用配备坐标。
或多或少像CRect::PtInRect之类的函数只有在应用配备坐标参数时才会保证有正确的结果 
将一部分亟待漫长拔取的值用逻辑坐标或物理坐标来保存。 如若用逻辑坐标来保存某点的坐标的话,那么只要用户对窗口举行一下滚动,该点的坐标就不再灵光了。 
鼠标单击事件下拿到的坐标都是设备坐标! 
运动原点
CDC::SetViewportOrg()移动视口的原点  CDC::SetWindwosOrg()移动窗口的原点
正常情状下,只可以采用其中之一,同时利用多少个会搞提一团糟。
赢得装备音讯 得到系统分辨率
CClientDC dc(this);
int cx = dc.GetDeviceCaps(HORZRES);
int cy = dc.GetDeviceCaps(VERTRES);

 

4.映射形式的类型

MM_LOMETRIC
 0.1 mm                 X轴正方向朝右,Y轴正方向朝上
 
MM_HIMETRIC
 0.01 mm                X轴正方向朝右,Y轴正方向朝上
 
MM_LOENGLISH
 0.01 inch              X轴正方向朝右,Y轴正方向朝上
 
MM_HIENGLISH
 0.001 inch             X轴正方向朝右,Y轴正方向朝上
 
MM_TWIPS
 1/1440 inch            X轴正方向朝右,Y轴正方向朝上
 
MM_ISOTROPIC
 自定义(X=Y)            自定义
 
MM_ANISOTROPIC
 自定义(X!=Y)           自定义
 

Windows定义了表1所列出的8种炫耀格局。

   
当绘制的图样需要随着窗口的轻重缓急改变而活动改变的时候,一般选用MM_ISOTROPIC和MM_ANISOTROPIC映射模式。它们的绝无仅有区别就是前者的X轴和Y轴的逻辑单位的大小是千篇一律的,单词“isotropic”就是逐一方向相等的意思,此映射格局符合绘制圆或正方形。而其实应用中,通常给X轴和Y轴取不同的百分比,这时候采用MM_ANISOTROPIC映射情势。单词“anisotropic”就是各类方向相异的情致。

映 射 方 式 逻 辑 单 位 X 轴 增 加 Y 轴 增 加 毫 米
MM_TEXT 像 素 点 与 设 备 有 关
MM_LOMETRIC 0. 1mm 0.1
MM_HIMETRIC 0. 01mm 0.01
MM_LOENGLISH 0. 01英寸 0.254
MM_HIENGLISH 0.001英寸 0.0254
MM_TWIPS 1/1440英寸 0.0176
MM_ISOTROPIC 任 意(x=y) 可 选 可 选 可 设
MM_ANISOTROPIC 任 意(x!=y) 可 选 可 选 可 设

    在缺省的形式(MM_TEXT)下,逻辑坐标的大势和单位与设备坐标的来头和单位一律,也是以像素为单位来表示的,X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。逻辑坐标和设备坐标即使在缺省形式下其数值也不一定相同,除了在以下两种境况下:
  1.   窗口为非滚动窗口
  2.  
窗口为滚动窗口,但垂直滚动条位于滚动边框的最顶端,水平滚动条位于最左端,但万一运动了滚动条这二种坐标就不等同了。

注:MM_TWIPS平常在打印机上,单位是1/20磅(1磅=1/72英寸)。

 

上述映射模式中又可分为以下3类:

(4).自定义映射格局

  1. MM_TEXT映射形式这种映射情势被称为”文本”映射情势,不是因为它对
    于文本最合适,而是轴的来头与读文件的来头一致。Windows提供了函数SetViewportOrg和SetWindowOrg
    用来安装视口和窗口的原点。缺省的窗口原点和视口原点均为(0,0),可以改变;缺省的窗
    口范围和视口范围均为(1,1),不可改变。
  2. 心胸映射情势MM_LOMETRIC、MM_HIMETRIC、MM_LOENGLISH、MM_HIENGLISH和MM_TWIPS
    将1个逻辑单位映射为定位的实际单位,其中1twip相当0.0176mm(1/1440英寸)。其他映射情势对应的物理单位参见表1。设置了炫耀格局之后,Windows自动设置了窗口及视口的界定,范围本身的值并不首要,但范围比是一个原则性的值,对于MM_LOMETRIC,Windows总结范围比xViewExt/xWinExt=0.1mm中水平像素的罗列。
  3. 自定义映射情势MM_ISOTROPIC和MM_ANISOTROPIC两种炫耀形式允许程序员设置自己的窗口和视口范围。MM_ISOTROPIC和MM_ANISOTROPIC的区别是所设置的x轴和y轴的的范围必须一律,而MM_ANISOTROPIC所设置的x轴和y轴的的范围可以不同。isotropi的趣味是”
    在具备矛头一致”,anisotropic的意趣正相反。自定义映射形式中窗口和视口的原点和范围都得以变动,程序员可以设置自己索要的照射格局。函数SetWindowExt和SetViewportExt
    用于转移窗口和视口的界定。下边的代码将1个逻辑单位映射成0.396mm(1/64英寸)。

“窗口”和“视口”的概念:
窗口(Window):对应逻辑坐标系上程序员设定的区域
视口(Viewport):对应实际输出设备上程序员设定的区域
1.窗口原点是指逻辑窗口坐标系的原点在视口(设备)坐标系中的地点,视口原点是指设备实际出口区域的原点。
2.除了映射形式,窗口和视口也是控制一个点的逻辑坐标怎样更换为设备坐标的一个因素。一个点的逻辑坐标遵照如下式子转换为设备坐标:
  设备(视口)坐标 = 逻辑坐标 – 窗口原点坐标      + 视口原点坐标

//定义坐标映射情势
WINGDIAPI int   WINAPI SetMapMode(HDC, int);
此API函数在MFC中封装为CDC::virtual int SetMapMode(int nMapMode);

SetMapMode(hDC, MM_ISOTROPIC); 
SetWindowExt(64, 64); 
SetViewportExt(hdc,GetDeviceCaps(hdc,LOGPIXELSX),GetDeviceCaps(hdc, LOGPIXELSY)); 

//定义逻辑窗口区域,单位为逻辑单位(Logical)
WINGDIAPI BOOL  WINAPI SetWindowExtEx (HDC, int, int, LPSIZE);
此API函数在MFC中封装为CDC::virtual CSize SetWindowExt(int cx, int cy);

二、与映射模式有关的问题的缓解
实在利用中,程序员会遭遇一些与彰显格局有关的题材。例如OLEServer中映射形式的装置、怎样缩小逻辑坐标与装备坐标间相互转换的误差等。下边,笔者就研商一下这两个问题的解决形式。
1.OLEServer中映射格局的安装格局

//设置逻辑窗口的原点坐标,缺省原点为(0,0)。
WINGDIAPI BOOL  WINAPI SetWindowOrgEx(HDC, int, int, LPPOINT);
此API函数在MFC中封装为CDC::CPoint SetWindowOrg(int x, int y);
只顾:SetWindowOrg(Ex)
只有在炫耀格局为MM_ANISOTROPIC或MM_ISOTROPIC时才有意义。

开发OLEServer应用程序时,即便程序员直接调用SetMapMode函数将映射格局设置成度量映射形式中的一种后,在Windows95/98上程序会正常运转,但在WindowsNT上对象出示的尺寸比边框小。经过作者研讨后,发现WindowsNT上OLEServer应使用基于逻辑英寸的映照形式。在议论什么设置基于逻辑英寸的照耀情势前,我们先介绍一下逻辑英寸的定义。

//定义视口的坐标轴方向及区域、定义域和值域,单位为像素(Pixel)
WINGDIAPI BOOL  WINAPI SetViewportExtEx(HDC, int, int, LPSIZE);
此API函数在MFC中封装为CDC::virtual CSize SetViewportExt(int cx, int
cy);
只顾:SetViewportExt(Ex)
唯有在炫耀情势为MM_ANISOTROPIC或MM_ISOTROPIC时才有含义。

Windows在显示时以”逻辑英寸”为单位,逻辑英寸比其实的英寸要大。假若Windows程序行使实际英寸,则通常的10磅文本在展现器上就会小到几乎难以辨认,由此Windows使用放大了的”逻辑英寸”来表示文本。逻辑英寸只影响展现,而不影响打印。

//设置视口的原点坐标,缺省原点为(0,0)。
WINGDIAPI BOOL  WINAPI SetViewportOrgEx(HDC, int, int, LPPOINT);
此API函数在MFC中封装为CDC:: virtual CPoint SetViewportOrg(int x, int y);

行使GetDeviceCaps函数可得到当前装备的各样能力,其首先个参数nIndex提醒要获裁撤息的序列。当nIndex为HORZSIZE和VERTSIZE时,可获取突显区域的小幅和惊人;当nIndex
为HORZRES和VERTRES时,可取得每个水平和垂直方向的像素数即分辨率;当nIndex的值为LOGPIXELSX
和LOGPIXELSY时,可得到水平和垂直方向每逻辑英寸所含像素数。

void   MoveWindow(   int   x,   int   y,   int   nWidth,   int  
nHeight,   BOOL   bRepaint   =   TRUE   );   
void   MoveWindow(   LPCRECT   lpRect,   BOOL   bRepaint   =   TRUE  
);   
 参数:
  x指定了CWnd的左侧的新职务。  
  y指定了CWnd的顶部的新职务。  
  nWidth指定了CWnd的新宽度。  
  nHeight指定了CWnd的新中度。  
 
bRepaint指定了是否要重画CWnd。假设为TRUE,则CWnd象平常这样在OnPaint音信处理函数中收受到一条WM_PAINT消息。假如那多少个参数为FALSE,则不会时有发生其他项目标重画操作。这应用于客户区、非客户区(包括标题条和滚动条)和出于CWnd移动而显露的父窗口的别样部分。当以此参数为FALSE的时候,应用程序必须明确地使CWnd和父窗口中必须重画的一些低效或重画。lpRectCRect对象或RECT结构,指定了新的尺寸和地方。表明这几个函数改变窗口的岗位和大小。对于顶层的CWnd对象,x和y参数是争持于屏幕的左上角的。对于子对象,它们是相对于父窗口客户区的左上角的。
 
 
MoveWindow函数发送一条WM_GETMINMAXINFO音讯。处理这么些信息时,CWnd得到一个改成最大和纤维的窗口缺省值的机遇。假使传递给MoveWindow成员函数的参数超越了这一个值,则在WM_GETMINMAXINFO处理函数中得以用很小或最大值来顶替这个值。   
    
  BOOL  CWnd::SetWindowPos(const  CWnd* pWndInsertAfter,  int   x, int
 y, int  cx, int  cy,UINT  nFlags   );  
  再次来到值假设函数成功,则赶回非零值;否则再次回到0。  
 
参数pWndInsertAfter标识了在Z轴次序上位居这些CWnd对象从前的CWnd对象。这个参数能够是指向CWnd对象的指针,也足以是指向下列值的指针:l
  wndBottom      
将窗口放在Z轴次序的底层。假设这个CWnd是一个顶层窗口,则窗口将失去它的顶层状态;系统将以此窗口放在其他具有窗口的底部。l
  wndTop       将窗口放在Z轴次序的顶部。l   wndTopMost      
将窗口放在所有非顶层窗口的下面。这一个窗口将保障它的顶层地点,即便它失去了活动状态。wndNoTopMost
     
将窗口重新定位到持有非顶层窗口的顶部(这象征在颇具的顶层窗口之下)。那个标志对这多少个已经是非顶层窗口的窗口没有效能。有关这些函数以及这么些参数的利用规则参见表明部分。x指定了窗口左侧的新岗位。y指定了窗口顶部的新岗位。cx指定了窗口的新宽度。cy指定了窗口的新中度。nFlags指定了尺寸和职务选项。那些参数可以是下列值的三结合:l
  SWP_DRAWFRAME       围绕窗口画出边框(在创造窗口的时候定义)。l  
SWP_FRAMECHANGED      
向窗口发送一条WM_NCCALCSIZE音信,虽然窗口的深浅不会改变。假设没有点名这一个标志,则仅当窗口的高低暴发变化时才发送
WM_NCCALCSIZE消息。l   SWP_HIDEWINDOW       隐藏窗口。SWP_NOACTIVATE
     
不激活窗口。假若没有设置这一个标志,则窗口将被激活并活动到顶层或非顶层窗口组(依赖于pWndInsertAfter参数的安装)的顶部。l
  SWP_NOCOPYBITS      
摒弃这多少个客户区的始末。假若没有点名那一个参数,则客户区的可行内容将被保存,并在窗口的深浅或岗位变动之后被拷贝回客户区。l
  SWP_NOMOVE       保持近日的岗位(忽略x和y参数)。l  
SWP_NOOWNERZORDER       不改动拥有者窗口在Z轴次序上的岗位。l  
SWP_NOREDRAW      
不重画变化。倘若设置了这些标志,则不发生任何类型的变化。那适用于客户区、非客户区(包括标题和滚动条)以及被移动窗口覆盖的父窗口的此外部分。当以此标志被安装的时候,应用程序必须精通地无效或重画要重画的窗口和父窗口的其它部分。l
  SWP_NOREPOSITION       与SWP_NOOWNERZORDER相同。l  
SWP_NOSENDCHANGING       防止窗口接收WM_WINDOWPOSCHANGING消息。l  
SWP_NOSIZE       保持最近的大小(忽略cx和cy参数)。l   SWP_NOZORDER  
    保持近期的先后(忽略pWndInsertAfter)。l   SWP_SHOWWINDOW      
显示窗口。  
   
 
调用那一个成员函数以改变子窗口、弹出窗口和顶层窗口的尺寸、地点和Z轴次序。窗口在屏幕上依照它们的Z轴次序排序。在Z轴次序上高居顶端的窗口将顺序在富有此外窗口的顶部。子窗口的富有坐标都是客户坐标(相对于父窗口客户区的左上角)。窗口可以被移位到Z轴次序的顶部,既可以由此将
pWndInsertAfter参数设为&wndTopMost,并确保没有安装SWP_NOZORDER标志,也可以由此设置窗口的Z轴次序使它座落所有现存的顶层窗口上方。当一个非顶层窗口被设为顶层窗口时,它具备的窗口也被设为顶层的。它的拥有者不暴发变化。如若顶层窗口被再度定位到Z轴次序的底层(&wndBottom)或其余非顶层窗口之后,则它将不再是顶层窗口。当顶层窗口被成为非顶层窗口时,它拥有的拥有者和它具有的保有窗口都被变成非顶层窗口。假设既没有点名SWP_NOACTIVE标志也绝非点名SWP_NOZORDER标志(这象征应用程序要求窗口被同时激活并放入指定的Z轴次序),则pWndInsertAfter参数中指定的值将只在下列条件下适用:l
  在pWndInsertAfter参数中既没有点名&wndTopMost也并未点名&wndNoTopMost。
 
 
这一个窗口不是移动窗口。应用程序无法激活一个非活动窗口但同时又不把它带到Z轴次序的顶部。应用程序能够没有其他限制地改成活动窗口的Z轴次序。非顶层窗口或者持有一个顶层窗口,但是反之则不创造。任何被顶层窗口拥有的窗口(例如对话框)都将协调成为顶层窗口,以担保所有被有着的窗口位于它们的拥有者上方。在Windows
 
3.1或更新的版本中,可以将窗口移动到Z轴次序的顶部,并经过设置它们的WS_EX_TOPMOST风格而将之锁定在这边。这种顶层窗口尽管在错过活动状态将来也会维持顶层地方。例如,拔取WinHelp的Always
  On  
Top命令会使救助窗口变为顶层,并且在您回到应用程序之后它还保持可见。要创设一个顶层窗口,应在调用SetWindowPos的时候将
pWndInsertAfter参数设为&wndTopMost,或者在创建窗口的时候设置WS_EX_TOPMOST风格。假使Z轴次序中带有了别样具有WS_EX_TOPMOST风格的窗口,则用&wndTopMost移动的窗口将被内置所有非顶层窗口的顶部,然而放在任何顶层窗口的底下。当应用程序激活一个不享有WS_EX_TOPMOST风格的非活动窗口时,该窗口将被活动到所有非顶层窗口的顶端,可是放在所有顶层窗口的花花世界。假使在调用SetWindowPos的时候pWndInsertAfter参数被设为&wndBottom,并且CWnd是一个顶层窗口,则该窗口失去顶层状态(WS_EX_BOTTOM风格被铲除),并且系统将窗口放在Z轴次序的底层。

在介绍了逻辑英寸的知识未来,很容易将OLEServer设置为遵照逻辑英寸的投射格局。要是程序员仅仅调用SetMapMode(hdc,MM_LOENGLISH)来安装映射情势,当前的投射形式为大体英寸,而不是逻辑英寸。设置逻辑英寸必须自定义窗口和视口的限定,使xViewExt/xWinExt
=0.01逻辑英寸中水平像素的罗列,当xViewExt=LOGPIXELSX,xWinExt=100时,其比率正好满意上述要求。

 

以下是安装映射情势的代码。

from:

intxLogPixPerInch = GetDeviceCaps(hdc, LOGPIXELSX); 
intyLogPixPerInch = GetDeviceCaps(hdc, LOGPIXELSY); 
SetMapMode(MM_ANISOTROPIC); 
SetWindowExt(100, 100); 
SetViewportExt(xLogPixPerInch, yLogPixPerInch); 

上述代码中调用SetMapMode函数将映射情势设置为自定义的,该调用必须放在SetWindowExt
和SetViewportExt调用往日,否则设置将会失效。
上述代码实际司令员映射格局设置成逻辑MM_LOENGLISH,若程序员需要安装逻辑MM_LOMETRIC、MM_HIMETRIC、MM_HIENGLISH
或MM_TWIPS,只需修改上述代码中的SetWindowExt的参数,该参数实际上是每英寸所涵盖的各个映射情势下的单位数。依照表1中各映射情势的参数,可收获表2中每英寸所对应的各逻辑单位的个数。

比如说,要安装逻辑MM_TWIPS,函数SetWindowExt中的参数为应1440。

2.逻辑坐标与设施坐标转换时误差的拍卖

表2

映 射 模 式 每 英 寸 所 对 应 的 逻 辑 单 位 数
MM_LOENGLISH 100
MM_HIENGLISH 1000
MM_LOMETRIC 254
MM_HIMETRIC 2540
MM_TWIPS 1440

当大家将映射模式设置成基于逻辑英寸的MM_LOMETRIC时,窗口的界定设为256,视口的界定设为96(在VGA呈现器下LOGPIXELSX的值),约2.6个逻辑单位对应1个像素,这眼看会招致不小的误差,它会显现在应用程序的各样方面:客户区的一个局部没有被刷新;对象之间自然从没间隔,却呈现出有间距;对象在屏幕的两样地方上会缩小或附加一个像素等题材。

可以行使以下多少个步骤制止转换误差。(1)尽量选取窗口范围和视口范围比可以整除的照射格局,例如基于逻辑英寸的MM_TWIPS其窗口范围和视口范围比1440/96,可简化为15/1,从设备坐标转化为逻辑坐标时没有误差,从消除误差角度看,MM_TWIPS比其他多少个映射情势都要好。(2)窗口范围和视口范围比无法整除时,也硬着头皮将其简化,例如,当使用0.3900mm
中的将1个逻辑单位映射成1/64英寸的映照形式时,其窗口范围和视口范围比值为64/96,可简化为2/3。假如大家将逻辑单位的值都取为2的倍数,设备单位的值都取为3的翻番,转换后就从不精度的遗失了。

综上所述,假诺我们可以遵照映射格局值的表征,逻辑坐标和装备坐标都取经简化的窗口和视口范围值的倍数,则逻辑坐标和设备坐标间的转向将没有误差。

(作者地址:南开高校科技产业楼401室,100084)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有