热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

也浅谈WinAPI函数SetWindowOrgEx与SetViewportOrgEx

在阅读学习CharlesPetzold大牛名作《ProgrammingWindows,5thEdition》过程中,对于第5章中讲解的SetWindow

在阅读学习Charles Petzold大牛名作《Programming Windows,5th Edition》过程中,对于第5章中讲解的SetWindowOrgEx与SetViewportOrgEx一直不明不白,文中所说的坐标系的移动之类更是弄得我一头雾水。阅读完该章节后,想想似乎只是明白了一点,再想想似乎只是更加糊涂一点。

在MM_TEXT映射模式下,假设cxClient和cyClient分别为客户区x轴和y轴的长度。

使用以下参数调用SetViewportOrgEx函数SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;则调用函数后,logical point(0,0)将映射到device point(cxClient/2, cyClient/2)。原来坐标系统系统(图一)将变为新的坐标系统(图二)。对于这点想想似乎明白。

 

                                                                     

                                            图一                                                                     图二

使用以下参数调用SetWindowOrgEx (hdc, -cxClient / 2, -cyClient / 2, NULL) ;则调用函数后,所得结果同上述调用SetViewportOrgEx 函数。坐标系的变换同图一坐标系统到图二坐标系统的变化。对于这点想想似乎糊涂。

引用《Programming Windows,5th Edition》书中第5章的一段

If you change the viewport origin to (xViewOrg, yViewOrg), the logical point (0, 0) will be mapped to the device point (xViewOrg, yViewOrg). If you change the window origin to (xWinOrg, yWinOrg), the logical point (xWinOrg, yWinOrg) will be mapped to the device point (0, 0), which is the upper left corner. Regardless of  any changes you make to the window and viewport origins, the device point (0, 0) is always the upper left corner of the client area.

这段话描述的是这两个函数的作用,读起来一知半解,或许个人的理解能力有待进一步提高吧。不理解,于是求助谷歌。原来不理解这两个函数的人不只是我一个人,很多人都已经讨论过,在博客上,在论坛上。浏览开始的一些讨论文章,情况还停留在即解却尚未解的状态。直到最后阅读了以下的一篇文章《SetViewportOrgEx与SetWindowOrgEx》,然后再在骑车回家的路上一想,恍然大悟,原来是可以这样简单的理解。

在《Programming Windows,5th Edition》书中第5章的The Viewport and the Window一节,讲解了何谓Viewport,何谓Window。因为没有自己的理解顿悟,接下来的SetViewportOrgEx和SetWindowOrgEx函数的迷惑也就理所当然。参考了“包子的小窝~~结庐在人境”的文章后,下面说下自己对于Viewport和 Window的理解:Viewport与屏幕设备相关,或者说同程序的客户区大小相关。在一应用程序当中,不管你调整程序的大小如何,你没有拖动滚动条所能完整看到的客户区内容的大小即是Viewport的大小。

Window与客户区内包含界面大小相关。在一应用程序当中,把滚动条从最左边拖动到最右边,从最上面个拖动到最下面,在这期间你所看到的客户区内全部内容的大小即是Window的大小。它们的关系就如同你从一扇可以平行移动的窗户观看外面的美丽风景。Viewport即是在这扇平行移动窗户静止时,你从这个窗口看出去所能看到的大小(类似滚动条静止你所看到整个客户区)。Window即是在这扇平行移动窗户从可以移动的初始位置移动到最终位置期间你所看到的大小(类似滚动条从左到右从上到下你所看到的内同)。

如果对于Viewport和Window这两个术语有了理解,理解SetViewPortOrgEx和SetWindowOrgEx函数也就顺理成章了。

不管是SetViewportOrgEx函数,还是SetWindowOrgEx函数,调用后的结果都是移动上面Viewport和Window所表示区域原点的相对位置。在MM_TEXT映射模式下,没有调用这两个函数前,Windows操作系统应用程序客户区所表示的Viewport和Window的原点(0,0)均位于客户区最左最顶一角。若调用SetViewportOrgEx函数,则移动Viewport所表示区域坐标系相对Window所表示区域坐标系统相应参数个长度距离。若调用SetWindowOrgEx函数,则移动Window所表示区域坐标系相对Viewport所表示区域坐标系统相应参数个长度距离。不知道大家是否回忆起小时候数学学习的坐标系统移动的经历。若使用正值作为参数移动某个坐标系统,则这个坐标系统相对另外的坐标系统将左移上移某个单位距离;若使用负值作为参数移动某个坐标系统,则这个坐标系统相对另外的坐标系统将右移下移某个单位距离。不管坐标系怎样移动,Window所对应的逻辑坐标系的原点都是固定不变,即你用相应的输出函数在相应的逻辑坐标系上输出的内容仍然是在原来的地方,只是相对于Viewport坐标系的移动,你所能看到的内容有所不同。

以下是根据我的理解调用相应函数的截图。

本程序在客户区输出左上角和右下角分别输出两个圆形(Viewport区域和Window区域一样大小),没调用SetViewportOrgEx函数和SetViewportOrgEx函数,截图如图三。

                                                                     图三

调用SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);即是Viewport区域左移上移相应参数长度,于是看到将是原先左上角的圆形将在右下角出现,截图如图四。

                                                                             图四

调用SetWindowOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);即是Window区域左移上移相应参数长度,于是看到的将是原右下角的圆形将在左上角出现,截图如图五

                                                                  图五

(全文完)

转:https://www.cnblogs.com/aoniao/archive/2012/06/18/2553762.html



推荐阅读
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • 本文介绍了lintcode(12)题目的要求和解题思路,以及给出了相应的代码实现。题目要求在给定的字符串source中找到包括所有目标字符串字母的最短子串,并且时间复杂度为O(n)。解题思路是使用滑动窗口的方法,通过维护一个unordered_map来记录目标字符串中每个字符的出现次数,并使用双指针来寻找最小子串。代码实现部分给出了具体的实现代码。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
author-avatar
书友36431060
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有