分享
 
 
 

Windows 映射模式

王朝system·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

Windows 映射模式

I_Love_CPP

(电子科技大学)

注:版权所有!如果要刊登、转载请给稿费!!!

联系方式: I.Love.Cpp@126.com

一、 映射模式

这是一个初级话题,但好像很多人都没有弄明白,因为几乎每过几天就用人发帖问这个。半年前有人问我这个问题时就想写这篇文章了,但一直觉得没有时间(因为除了学习、工作和玩耍,几乎就没有多少空时间了)。本文现在其实只能算着《 Programming Windows 》中关于“映射模式”的加工,以咱们中国读者更易懂的方式写出;我将逐步往其中添加一些相关内容。

首先,从一个十分简单但又很常用的函数开始:

BOOL TextOut( HDC hdc , // handle to DC

int nXStart , // x-coordinate of starting position

int nYStart , // y-coordinate of starting position

LPCTSTR lpString , // character string

int cbString // number of characters );

这里的( nXstart , nYStart )是字符串显示的起始坐标点,这里的坐标就是“逻辑坐标”。为了最终将文字显示到设备(屏幕)上, Windows 必须将这些逻辑坐标“翻译”成“设备坐标” —— 其实就是“像素 (pixels) ”。 Windows 一共定义了 8 种映射模式,如下表所示:

-----------------------------------------------------------------------------------

Increasing Value

Mapping Mode Logical Unit x-axis y-axis

MM_TEXT Pixel Right Down

MM_LOMETRIC 0.1 mm Right Up

MM_HIMETRIC 0.01 mm Right Up

MM_LOENGLISH 0.01 in. Right Up

MM_HIENGLISH 0.001 in. Right Up

MM_TWIPS 1/1440 in. Right Up

MM_ISOTROPIC Arbitrary (x = y) Selectable Selectable

MM_ANISOTROPIC Arbitrary (x !=y) Selectable Selectable

--------------------------------------------------------------------------------------

表 1

注: in. 表 英寸 ; Windows 默认的映射模式是 MM_TEXT ,其实就是 设备坐标 !!!

趁热打铁,看一下例子:

例: 如果我们没有用 SetMapMode 设定 Windows 的映射模式,那么 Windows 将使用默认的 MM_TEXT 映射模式,

TextOut (hdc, 8, 16, TEXT ("Hello"), 5);

的结果是文字将从离客户区左边界 8 个像素、离上边界 16 个像素的位置从左向右输出文字。

SetMapMode (hdc, MM_LOENGLISH);

TextOut (hdc, 50, -100, TEXT ("Hello"), 5);

的结果将是 从离客户区左边界 50* 0.01 in .= 0.5 in . 、离上边界 100*0.01 = 1 in . 的位置从左向右输出文字。

但 TextOut 的第 3 个参数为什么是 -100 呢?因为客户区左上角的坐标的默认值始终是 (0,0) 的(后面将详细讲到),而上面的列表不适写了吗 ? 在 MM_LOENGLISH 下, Y 轴值递增的方向是向上,也就是说向下递减,当然此时第 3 个参数为负值了。

Windows 设定这些映射模式是为了让用户使用起来更方便,因此你选定合适的映射模式来简化你的工作;或者选用 MM_ISOTROPIC 、 MM_ANISOTROPIC 自己设定逻辑坐标的单位,数值递增方向;或者干脆就用 MM_TEXT (相当于直接使用设备坐标),需要缩放时用 GetDeviceCap 获得必要的信息后 自己去计算得了。

二、坐标原点

常看到网友问 CDC::SetWindowOrg 和 CDC:: SetViewportOrg 的用法,它们实质是封装了 GDI 函数 SetWindowOrgEx 和 SetViewportOrgEx :

而 CSDN 的解释是:

The SetWindowOrgEx function specifies which window point maps to the viewport origin (0,0). The SetViewportOrgEx function specifies which device point maps to the window origin (0,0).

初学者往往一头雾水。

其实“映射模式”中的“映射”就是数学中的“映射”,一种对应关系或者说是一个数学表达式而已。这个表达式就是:

公式一:

xViewport = (xWindow - xWinOrg) × Kx + xViewOrg

yViewport = (yWindow - yWinOrg) × Ky + yViewOrg

等价公式二:

xWindow = (xViewport - xViewOrg) /Kx + xWinOrg

yWindow = (yViewport - yViewOrg) /Ky + yWinOrg

其中( xWinOrg,yWinOrg ),( xViewOrg,yViewOrg )分别表示逻辑坐标和设备坐标的原点,默认值均为( 0,0 );

( xWindow,yWindow )表示逻辑坐标点,( xViewport,yViewport )表示与之对应的设备坐标点(也就是说,在当前的映射模式下, Windows 将( xWindow,yWindow )影射为( xViewport,yViewport )。);

常数 Kx,Ky 是缩放系数(后面将详细介绍),不同的映射模式下缩放系数不同。

因此,在默认的情况下,( xWinOrg,yWinOrg ) = ( xViewOrg,yViewOrg ) = ( 0,0 ),公式一其实就是:

xViewport = xWindow / Kx yViewport = yWindow / Ky 。

因此,可以看出,映射模式其实就是设定了一个比例而已,没有什么了不起的!

例:

SetMapMode(hdc,MM_TEXT); // 在 MM_TEXT 下缩放比例 K = 1;

SetWindowOrgEx (hdc,100,100,NULL); // 此时( xWinOrg,yWinOrg )被赋值为( 100 , 100 );

// 而 ( xViewOrg,yViewOrg )保持不变为( 0 , 0 )。

那么公式一即为:

xViewport = xWindow -100 yViewport = yWindow -100

因此

TextOut (hdc, 520, 530, TEXT ("ILoveYou,MyGirl"), 15);

// ( xWindow,yWindow ) = ( 520 , 530 )

将会从( 520 , 530 ) - ( 100 , 100 ) = ( 220 , 230 )点开始在设备上显示。

而 SetViewportOrgEx 是用来设定( xViewOrg,yViewOrg )的值的,使用方法与 SetWindowOrgEx 的使用类似。从公式一可以看出,在 MM_TEXT 中,

SetWindowOrgEx (hdc, x, y , NULL) ;

SetViewportOrgEx (hdc, - x, - y, NULL);

等价的。

三、缩放系数

缩放系数

Kx = xViewExt / xWinExt

Ky = yViewExt / yWinExt

(xViewExt,yViewExt)和(xWinExt,yWinExt)可分别由 GetViewportExt 和 GetWindowExtEx 得到。

在 MM_TEXT 下, Kx = Ky = 1 ;其它映射模式下Kx、Ky均为常数,它们可以由下表来计算(Window NT,显示设备:1024x768 pixels):

--------------------------------------------------------------------------------------

Mapping Mode Viewport Extents (x, y) Window Extents (x, y)

MM_LOMETRIC (1024, -768) (3200, 2400)

MM_HIMETRIC (1024, -768) (32000, 24000)

MM_LOENGLISH (1024, -768) (1260, 945)

MM_HIENGLISH (1024, -768) (12598, 9449)

MM_TWIPS (1024, -768) (18142, 13606)

------------------------------------------------------------------------------------

表 2 Windows NT Extents (1024 x 768)

参考文献:

MSDN by Microsoft

《 Visual C++ 技术内幕》 by David J. Kruglinski et al

《 Programming Windows 》 5 th Edition ,by Petzoldi

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~The End

本人才疏学浅,本文若有什么不当之处,请告知,谢谢。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有