屏幕坐标系和窗口客户区坐标

屏幕坐标系和窗口客户区坐标系最明显的区别在于坐标原点,屏幕坐标系的坐标原点在整个屏幕的左上角,而窗口客户区坐标系的坐标原点在窗口客户区的左上角,通常这两个点是不重合的。

一 设备坐标和逻辑坐标

  设备坐标(Device Coordinate)又称为物理坐标(Physical Coordinate),是指输出设备上的坐标。通常将屏幕上的设备坐标称为屏幕坐标。设备坐标用对象距离窗口左上角的水平距离和垂直距离来指定对象的位置,是以像素为单位来表示的,设备坐标的X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。

  逻辑坐标(Logical Coordinate)是系统用作记录的坐标。在缺省的模式(MM_TEXT)下,逻辑坐标的方向和单位与设备坐标的方向和单位相同,也是以像素为单位来表示的,X轴向右为正,Y轴向下为正,坐标原点位于窗口的左上角。逻辑坐标和设备坐标即使在缺省模式下其数值也未必一致,除了在以下两种情况下:

  1. 窗口为非滚动窗口

  2. 窗口为滚动窗口,但垂直滚动条位于滚动边框的最上端,水平滚动条位于最左端,但如果移动了滚动条这两种坐标就不一致了。

  在VC中鼠标坐标的坐标位置用设备坐标表示,但所有GDI绘图都用逻

  坐标表示,所以用鼠标绘图时,那么必须将设备坐标转换为逻辑坐标,可以使用CDC 函数DptoLP()将设备坐标转化为逻辑坐标,同样可以用LptoDP()将逻辑坐标转化为设备坐标。

  二 坐标模式

  为了在不同的领域使用逻辑坐标,Windows提供了以下8种坐标模式:

  分别为MM_TEXT、MM_HIENGLISH、MM_LOENGLISH、MM_HIMETRIC、MM_LOMETRIC、MM_TWIPS、MM_ANISOTROPIC和MM_ISOTROPIC。
三 实例解析

  (一) 建立以左上角为原点,X轴和Y轴为1000的坐标,如下图

  我们可以用以下代码:

  void CTtView::OnDraw(CDC* pDC)
   {
    CTtDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    CRect rect;
    GetClientRect(&rect);

    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetViewportOrg(0,0);
    pDC->SetViewportExt(rect.right,rect.bottom);

    pDC->SetWindowOrg(0,0);
    pDC->SetWindowExt(1000,1000);

    pDC->MoveTo(50,50);
    pDC->LineTo(50,950);
    pDC->LineTo(950,950);
    pDC->LineTo(50,50);
   }

  代码分析:

  1. GetClientRect(&rect); 取得客户区矩形区域,将其存放在rect中

  2. 用pDC->SetMapMode(MM_ANISOTROPIC); 设置映射模式

  3. 通过pDC->SetViewportOrg(0,0);设置逻辑坐标的原点

  4. 通过pDC->SetViewportExt(rect.right,rect.bottom);和

   pDC->SetWindowExt(1000,1000);来确定逻辑坐标下和设备坐标下的尺寸对应关系

  5. 在MM_ANISOTROPIC模式下,X轴单位和Y轴单位可以不相同

  6. 坐标方向的确定方法是如果逻辑窗范围和视口范围符号相同,则逻辑坐标的方向和视口的方向相同,即X轴向右为正,Y轴向下为正。

  7. 如果将显示模式改为MM_ISOTROPIC,那么X轴单位和Y轴单位一定相同,感兴趣的读者可以自己使一下。

  (二) 建立以视窗中心为原点的坐标,如下图

  用如下代码:

  void CTtView::OnDraw(CDC* pDC)
   {
    CTtDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    CRect rect;
    GetClientRect(&rect);

    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetViewportOrg(rect.right/2,rect.bottom/2);
    pDC->SetViewportExt(rect.right,rect.bottom);

    pDC->SetWindowOrg(0,0);
    pDC->SetWindowExt(1000,-1000);

    pDC->MoveTo(150,150);
    pDC->LineTo(-150,-200);
    pDC->LineTo(150,-150);
    pDC->LineTo(150,150);
   }

  代码分析:

  1. 用 pDC->SetViewportOrg(rect.right/2,rect.bottom/2); 设置视口的原点。

  2. 用pDC->SetViewportExt(rect.right,rect.bottom);和pDC->SetWindowExt(1000,-1000);来确定设备坐标和逻辑坐标的单位对应关系。

  3. 因为逻辑窗范围和视口范围的符号不一致,纵坐标取反,所以Y轴向上为正。

时间: 2024-11-10 01:05:45

屏幕坐标系和窗口客户区坐标的相关文章

Windows的三种坐标系:屏幕坐标系,非客户区坐标系,客户区坐标系

1. 屏幕坐标系:以屏幕的左上角为原点,如图所示GetWindowRect() 函数获得的 RECT 就是以屏幕坐标系算的. 2. 非客户区坐标系(窗口坐标系)包括标题栏的部分.GetWindowDC 返回的设备环境就是基于此坐标系,一般只在 WM_NCPAINT 消息中使用. 3. 客户区坐标系不包括标题栏,坐标的原点在标题栏下的客户区的左上角.BeginPaint 函数返回的设备环境是基于客户区坐标系的,只在 WM_PAINT 消息中使用,与 EndPaint 函数成对使用.GetDC 函数

逻辑坐标与设备坐标——全窗口坐标、屏幕坐标、客户区坐标的总结

Windows应用程序绘制图形时使用的是一种逻辑单位,每个逻辑单位的大小由映射模式决定,这个逻辑单位既可以与设备单位(屏幕或打印机上的一个 像素点)相同,也可以是一种物理单位(如毫米),还可以是用户自定义的一种单位.在Windows应用程序中,只要与输出有关系,都要使用映射模式. 首先谈谈映射模式基本知识,当Windows应用程序在其客户区绘制图形时,必须给出在客户区的位置,其位置用x和y 两个坐标表示,x表示横坐标,y表示纵坐标.在所有的GDI绘制函数中,这些坐标使用的是一种"逻辑单位&quo

逻辑坐标系 设备坐标系 客户坐标系 屏幕坐标系

(1)Windows坐标系统 Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系.一般而言,GDI的文本和图形输出函数使用逻辑坐标,而在客户区移动或按下鼠标的鼠标位置是采用设备坐标. <1>逻辑坐标系(Logical Coordinate)是面向DC的坐标系,这种坐标不考虑具体的设备类型,在绘图时,Windows会根据当前设置的映射模式将逻辑坐标转换为设备坐标. <2> 设备坐标(Device Coordinate)又称为物理坐标(Physical Coor

MFC光标移动到按钮上时编辑框显示时间,并显示光标的窗口位置和客户区位置

建立MFC应用程序 选择基于对话框 添加一个按钮三个编辑框,三个编辑框分别用来显示系统时间.光标在windows的位置.光标在client的位置. 将Button的captain改为Time,ID改为IDC_time. 点击 项目/类向导/成员变量/  , 为按钮和编辑框添加变量m_time,m_showtime,m_client,m_window,(方法有很多). 注意类别为control,变量类型分别为cbutton和cedit 在类向导里 点击消息 找到mousemove,双击, 以上红字

窗口非客户区的绘制

1.根据需要,要改变nc区的大小. 响应WM_NCCALCSIZE可改变nc区的大小.关键在于lParam,msdn上说当wParam为True时, lParam为LPNCCALCSIZE_PARAMS的指定,当wParam为False时为LPRECT,做了些实验发现 只有第一次时wParam为False,LPNCCALCSIZE_PARAMS的语义相当复杂,不过我们只用 看第一个RECT就成.它表是窗口客户区的大小.当lParam为LPRECT时,也同样.只用改变 客户区的大小,相应的就改变了

2算法:客户区坐标转换成屏幕坐标

//显示菜单 POINT point = { 0 }; //转换时需要POINT数据结构 point.x = LOWORD(lParam); //客户区坐标 point.y = HIWORD(lParam); //转换成屏幕坐标 ClientToScreen(hWnd, &point); //point.x //point.y 这两个坐标可以直接使用 来自为知笔记(Wiz)

EVT_NC_PAINT 窗口非客户区的绘制

说明 NC就是non client意思,非客户区主要包括标题栏,状态栏,工具栏和边框等区域,目前wxwidgets只是提供了EVT_NC_PAINT 唯一的一个非客户区的事件,在MFC中,还有提供WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCMOUSEMOVE等事件操作,如果需要关联这些事件,就必须要过滤该事件,或者在源码中实现该类事件 目前需要拖动边框的时候,客户区域不变,只是边框变大,等到边框拖动到合适的地方,鼠标弹起,客户区域重绘

Windows客户区窗口大小设置

#define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 Windows下设置的窗口(非客户区)长宽分别为800 x 600 所以当我们用函数GetClientRect(hwnd, &rect)获取客户区大小 rect.right为782   rect.bottom为555 所以如果要设置客户区成800 x 600 RECT rect1;RECT rect2;GetWindowRect(hwnd, &rect1);   // 四个坐标分别表示窗口

windows编程笔记(5):客户区输出字符

在客户区的界面显示程序是在放在回调函数的WM_PAINT消息的处理中,当客户区需要被重绘时,Windows系统会给应用程序窗口发送一个WM_PAINT消息.窗口在收到这个消息时,它就会重绘它的客户区. 显示文字的步骤: 1 用BeginPaint()函数得到客户区的设备环境句柄. 2 用TextOut()函数显示文字. 3 用EndPaint()函数结束显示. 显示文字的代码如下: case WM_PAINT: hdc=BeginPaint(hWnd,&ps); TextOut(hdc,10,1