关于vc++中的坐标转换的几点认识

  初次接触 VC++ 的坐标转换突然有点摸不到头脑,经过一番反来覆去的折腾之后找到一些窍门和方法,拿出来与大家共享。
  在此之前我想先搞清几个概念性的东西:
一:句柄
书上定义:句柄是操作系统为管理生存对象而动态随机分配的一个 32 位整形标识符。
我的理解:我们设计一个程序的类的时候是要考虑,当这个应用运行的时候它要完成那些功能的。当运行的时候这个类通过你的一些系统调用,让操作系统将它变成一个对象安放在内存中的某个区域。这时候这个对象就成为操作系统管理的一个对象了,它的所有的属性和功能是你在设计程序的时候设计好了的。这个时候这个对象是归操作系统管理和负责的。操作系统为了管理它就在这个对象创建的时候为之分配一个全局唯一的 32 位标识,这个标识就叫句柄。不同的句柄表示的意义和操作系统用它来完成的功能是不同的。
那么有了这个句柄操作系统用它到底做那些工作呢?
如窗口句柄 HWND ,我们知道当我们在设计一个窗口类的步骤是这样的:
第一:声明 WNDCLASS 结构,初始化结构;
第二:注册这个窗口类;
第三:创建窗口; // 创建窗口时就返回了这个窗口的句柄。
第四:显示这个窗口。
其实返回的这个窗口句柄是操作系统黏附给你创建的这个对象的。这个句柄实际指向了谁呢?我理解它指向了显卡的缓存区,这个缓存区中存放了当前你创建的这个对象的拷贝。一旦你调用了 showwindow(SW_SHOW) 操作系统就将这个你创建的窗口显示在屏幕上。
说到这里我们可能明白了这个句柄的意义了。有了这样的解释,我们就不难理解句柄的意义了。也可以解释我们为什么可以 Detach 这个句柄,销毁内存中的对象但显示器中对应的窗口却不消失了。
我们是否可以这样认为:就是认为句柄是操作系统所管理的某个活动资源的标识(不是指针),它能和某个类对象关联,关联的时候两个对象可以通信。而这个资源到底是什么则和这个句柄的类型有很大的关系,这是有操作系统去定义的我们则知到的很少,只有通过对象本身的系统调用去深挖它的妙处。
好了句柄说完了下面说坐标转换:
第二:我们设计程序的时候会涉及到几个坐标空间
1 、世界坐标空间;
2 、页面坐标空间;
3 、设备坐标空间;
4 、物理坐标空间;
我们用到的坐标主要:逻辑坐标值(前两种坐标空间使用)和设备坐标值(后两种坐标空间使用);
还要用到窗口和视口的概念:窗口对应逻辑坐标、视口对应设备坐标,概念性的东西请到相关资料或书籍上查找。
这几种坐标空间是什么意思大家可以查找相关的资料看个明白, MSDN 种也有详细的解释。我们在作图的时候主要用到页面坐标空间到设备坐标空间的转换,这种转换的依据就是我们在程序设计时用到的:影射模式。影射模式决定了你的程序代码中用到的坐标值和显示或打印时转换后的坐标值。
影射模式有:
MM_ANISOTROPIC,MM_ISOTROPIC: 表示窗口和视口坐标原点及窗口和视口范围由用户定义,并且逻辑坐标的正方向也由用户定义。视口坐标的正方向和显示器的坐标定义相同的(既设备坐标 X 轴向右、 Y 轴向下)。
MM_HIENGLISH:
MM_LOENGLISH:
MM_HIMETRIC:
MM_LOMETRIC: 以上四定义了逻辑单位,设备单位永远为 1*1 像素。
MM_TWIPS :以上五种逻辑坐标都是: X 轴正向向右, Y 轴正向向上。
MM_TEXT: 逻辑单位与设备单位坐标定义一样,即原点( 0 0 );单位:像素;坐标方向, X 轴正向向右, Y 轴正向向下;
下面通过一段代码分析我们来学习这影射模式和坐标转换:
void CLesn11View::OnLButtonUp(UINT nFlags, CPoint point)
{
         // TODO: Add your message handler code here and/or call default
         CClientDC dc(this);
当视图显示在桌面时操作系统需要将我们设计的视图对象( Clesn11View 对应的对象)从内存中调度到显存中( m_hwnd 中保存的 HWND 指向的空间),操作系统将显存的状态信息保存在一个内存区 m_hdc )中,每次把视图对象调度到 m_hWnd 中都要匹配 m_hdc 中的某些状态,如画笔呀、笔刷呀、映射模式呀等等然后经过转换调度进来。
即:对象要输出显示时要匹配 m_hdc 中的设置、然后放到 m_hwnd 中显示。
每次我们要设置操作系统中的显示设备参数时呢,先要在内存中创建该设备的一个对象( MFC 设计好了的模拟显示设备或其它输出设备结构和方法设计的类 CDC GetDC() 建立两者的关联通过 HDC ,通过成员方法设置好之后就可以进行输出工作了。 */
 
         dc.SetMapMode (MM_LOENGLISH);
     /*  设置显示设备的影射模式为 MM_LOENGLISH ,即逻辑原点为( 0 0 ),逻辑单位为 0.01 英寸, X 坐标向右为正, Y 坐标向上为正。 */
         dc.MoveTo (0,-100);
        /* 在逻辑坐标为( 0 -100 )的地方设置一个点,即物理为( 0 -1 英寸)的地方设置一点 */
         dc.LineTo (1000,-100);
      /* 连接( 0 -1 )英寸到( 10 英寸, -1 )这个点连成一条线 */
CScrollView::OnLButtonUp(nFlags, point);
}
从中我们可以领悟到几点:
凡是带有句柄成员的对象都会在创建的时候占用操作系统某方面的资源。操作系统完成建立你创建对象与相关资源的关联。多个对象之间也会有关联,你所建立对象之间的关联最终要反映在句柄代表的对象间的关联。
 
譬如窗口对象 与 m_hWnd对象,设备上下文对象与m_hdc对象,画笔与m_hpen对象等等,他们一个是用户创建的对象,一个是操作系统管理的动态的对象,它们之间关联了,你的对象就发挥作用了,它们之间分离了,你的对象就无用了。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值