设置坐标映射

   (1Windows坐标系统

Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系。一般而言,

GDI的文本和图形输出函数使用逻辑坐标,而在客户区移动或按下鼠标的鼠标位置是采用设备坐标。

<1>逻辑坐标系是面向DC的坐标系,这种坐标不考虑具体的设备类型,在绘图时,Windows会根据当前设置的映射模式将逻辑坐标转换为设备坐标。

<2>设备坐标系是面向物理设备的坐标系,这种坐标以像素或设备所能表示的最小长度单位为单位,X轴方向向右,Y轴方向向下。设备坐标系的原点位置(0, 0)不限定在设备显示区域的左上角。

设备坐标系分为屏幕坐标系、窗口坐标系和客户区坐标系三种相互独立的坐标系。

l       屏幕坐标系以屏幕左上角为原点,一些与整个屏幕有关的函数均采用屏幕坐标,如GetCursorPos()、SetCursorPos()、CreateWindow()、MoveWindow()。弹出式菜单使用的也是屏幕坐标。

l       窗口坐标系以窗口左上角为坐标原点,它包括窗口标题栏、菜单栏和工具栏等范围。

l       客户区坐标系以窗口客户区左上角为原点,主要用于客户区的绘图输出和窗口消息的处理。鼠标消息的坐标参数使用客户区坐标,CDC类绘图成员函数使用与客户区坐标对应的逻辑坐标。

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

l       编程时,有时需要根据当前的具体情况进行三种设备坐标之间或与逻辑坐标的相互转换。

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

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

(3)映射模式

l       映射模式确定了在绘制图形时所依据的坐标系,它定义了逻辑单位的实际大小、坐标增长方向,所有映射模式的坐标原点均在设备输出区域(如客户区或打印区)的左上角。此外,对于某些映射模式,用户还可以自定义窗口的长度和宽度,设置视图区的物理范围。

l       Windows定义了8种映射模式,见下表。

l       映射模式使得程序员可不必考虑输出设备的具体设备坐标系,而在一个统一的逻辑坐标系中进行图形的绘制。

映射方法(Mapping Mode)

逻辑单位

坐标轴方向

MM_TEXT(默认方式)

1 pixel

X轴正方向朝右,Y轴正方向朝下

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)

自定义

当绘制的图形需要随着窗口的大小改变而自动改变的时候,一般选择MM_ISOTROPIC和MM_ANISOTROPIC映射方式。它们的唯一区别 就是前者的X轴和Y轴的逻辑单位的大小是相同的,单词“isotropic”就是各个方向相等的意思,此映射方式适合绘制圆或正方形。而实际应用中,常常 给X轴和Y轴取不同的比例,这时候选择MM_ANISOTROPIC映射方式。单词“anisotropic”就是各个方向相异的意思。

(4)自定义映射模式

“窗口”和“视口”的概念:

窗口(Window):对应逻辑坐标系上程序员设定的区域

视口(Viewport):对应实际输出设备上程序员设定的区域

l       窗口原点是指逻辑窗口坐标系的原点在视口(设备)坐标系中的位置,视口原点是指设备实际输出区域的原点。

l       除了映射模式,窗口和视口也是决定一个点的逻辑坐标如何转换为设备坐标的一个因素。一个点的逻辑坐标按照如下式子转换为设备坐标:

设备(视口)坐标 = 逻辑坐标 – 窗口原点坐标      + 视口原点坐标

//定义坐标映射方式

WINGDIAPI int   WINAPI SetMapMode(HDC, int);

此API函数在MFC中封装为CDC::virtual int SetMapMode(int nMapMode);

//定义逻辑窗口区域,单位为逻辑单位(Logical)

WINGDIAPI BOOL  WINAPI SetWindowExtEx (HDC, int, int, LPSIZE);

此API函数在MFC中封装为CDC::virtual CSize SetWindowExt(int cx, int cy);

//设置逻辑窗口的原点坐标,缺省原点为(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时才有意义。

//定义视口的坐标轴方向及区域、定义域和值域,单位为像素(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时才有意义。

//设置视口的原点坐标,缺省原点为(0,0)。

WINGDIAPI BOOL  WINAPI SetViewportOrgEx(HDC, int, int, LPPOINT);

此API函数在MFC中封装为CDC:: virtual CPoint SetViewportOrg(int x, int y);

windows 屏幕坐标 窗口坐标 客户区坐标 逻辑坐标 设备坐标之间的关系及转换的更多相关文章

  1. WINDOWS 逻辑坐标 设备坐标 屏幕坐标 客户区坐标

    转自:http://blog.csdn.net/lovesunshine2008/article/details/4048158 设置坐标映射    (1)Windows坐标系统 Windows坐标系 ...

  2. 调用API函数,在窗口非客户区绘图(通过GetWindowDC获得整个窗口的DC,就可以随意作画了)

    http://hi.baidu.com/3582077/item/77d3c1ff60f9fa5ec9f33754 调用API函数,在窗口非客户区绘图 GDI+的Graphics类里有个FromHdc ...

  3. VC----SDK下对窗口非客户区的操作

    窗口分成两大部分:客户区和非客户区.非客户区再次细分:标题栏,如图片中顶部深蓝色:左边框,如图片中红色部分:上边框,如图片中绿色部分:右边框,如图片中右侧天蓝色部分:底边框,如图片中下面棕色部分. 之 ...

  4. git工作区、暂存区、版本库之间的关系

    区分三者关系 Git最让你迷惑的无非是它里面的各种概念了,如果是刚开始接触Git希望看完本篇介绍之后有一个清晰的认识,笔者认识也有限这里只说说个人对使用Git的感受,说一下它里面的几个最常用的概念的理 ...

  5. 老话题:自己编写只截窗口客户区的截屏软件(VB2010)

    现在能实现截屏的软件很多,就不一一列举了,连WIN7都自带截屏软件,甚至OFFICE2010开始都有截屏的功能. 截屏软件虽多,无外乎三种截屏方式:全屏截图.窗口截图.自定义矩形截图. 其中,窗口截图 ...

  6. Windows常见窗口样式和控件风格

    Windows常见窗口样式和控件风格 王佰营 徐丽红 一.窗口样式 WS_POPUP 弹出式窗口(不能与WS_CHILDWINDOW样式同时使用)WS_CHILDWINDOW 子窗口(不能与WS_PO ...

  7. Win窗口坐标二维坐标与OpenGl的世界坐标系的之间的相互转换

    Win窗口坐标二维坐标与OpenGl的世界坐标系的转换 几何处理管线擅长于使用视图和投影矩阵以及用于裁剪的视口把顶点的世界坐标变换为窗口坐标. 但是,在有些情况下,需要逆转这个过程.一种常见的情形是: ...

  8. 一句话为当前窗口客户区捉图: GetFormImage 来自万一的博客

    一句话为当前窗口客户区捉图: GetFormImage http://www.cnblogs.com/del/archive/2008/10/24/1318738.html unit Unit1; i ...

  9. [转]Windows的窗口刷新机制

    1.Windows的窗口刷新管理 窗口句柄(HWND)都是由操作系统内核管理的,系统内部有一个z-order序列,记录着当前窗口从屏幕底部(假象的从屏幕到眼睛的方向),到屏幕最高层的一个窗口句柄的排序 ...

随机推荐

  1. python学习-- 在django中,执行原始sql语句

    from django.shortcuts import render, redirect from news.models import Article, Column def test(reque ...

  2. Leetcode 650.只有两个键的键盘

    只有两个键的键盘 最初在一个记事本上只有一个字符 'A'.你每次可以对这个记事本进行两种操作: Copy All (复制全部) : 你可以复制这个记事本中的所有字符(部分的复制是不允许的). Past ...

  3. CodeForces Round #515 Div.3 B. Heaters

    http://codeforces.com/contest/1066/problem/B Vova's house is an array consisting of nn elements (yea ...

  4. mysql中游标的使用案例详解(学习笔记)(转)

    1.游标是啥玩意?简单的说:游标(cursor)就是游动的标识,啥意思呢,通俗的这么说,一条sql取出对应n条结果资源的接口/句柄,就是游标,沿着游标可以一次取出一行.我给大家准备一张图: 2.怎么使 ...

  5. [Gym101138G][容斥原理]LCM-er

    [Gym101138G][容斥原理]LCM-er 题意描述 给定\(n,a,b,x\)四个数字,需要计数满足如下条件序列的个数(答案对\(10^9+7\)取模),条件如下. \[ {a \le A_1 ...

  6. canvas图片跨域问题

    canvas的drawImage使用跨域图片时候,会报错,解决方法如下: 1. 使用base64替换跨域图片 如果图片不大,且只有几张,可以使用base64,来代替跨域引用图片. 2. 设置image ...

  7. ofbiz16 idea 启动

    1.下载gradle并安装到本地 2.idea引入gradle 3.gradle右键选择refresh,项目会重新编译并加载gradle的task 4.可以再编译一下 5.没问题的话打开,jar ap ...

  8. hdu 1025 n*logn最长上升子序列

    /* TLE */ #include <iostream> #include <cstdio> #include <cstring> using namespace ...

  9. Playing with String(codeforces 305E)

    题意:刚开始你只有一个字符串每次能选择一个有的字符串 s,找到 i,满足s[i - 1] = s[i + 1],将其分裂成 3 个字符串s[1 · · · i - 1]; s[i]; s[i + 1 ...

  10. 地精部落(bzoj 1925)

    Description 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi, ...