MFC的坐标转换GetClientRect/GetWindowRect/ClientToScreen/GetCursorPos/ScreenToClient

注意:windows的屏幕左上点为基点,也即原点,向右x轴正向,向下y轴正向

注意:区分两个概念 (假设显示器1024*768)

             屏幕-左上点:1024*768的屏幕(显示器),屏幕(显示器)的左上点 就是 (0,0)

             窗口-左上点:我们双击了notepad图标,它弹出了Notepad窗口,窗口的大小是600 * 400(假设),位于屏幕中央。Notepad窗口的左上点计算为:(1024-600)/2, (768-400)/2 --(212, 184),也就是窗口左上点对于 显示器来说,坐标是(212, 184),当然相对于其本身来说仍是(0,0)了。

 

1. MFC多数方法传入的point,他们的取值为相对的坐标(以当前窗口左上点为基点的相对坐标)

   void CDlgSelectCity::OnLButtonDown(UINT nFlags, CPoint point)

   转换为windows的坐标,使用ClientToScreen,把相对于窗口的坐标转换为以当前屏幕的左上点为基点的坐标

ClientToScreen(&point);

+  point {x=489 y=132} CPoint                转换前相对于窗口的坐标

+  screentPoint {x=678 y=251} CPoint  转换后相对于屏幕的坐标

 

2. GetCursorPos所获取到的坐标,为以屏幕左上点为基点的坐标

   //也或我们获取的CPoint

   POINT apoint;

   GetCursorPos(&apoint);

+  apoint {x=678 y=251} tagPOINT

 

3. GetClientRect 获取的为相对于自身的范围(相对于自身而言,左上点为0,可以看到获取的结果 top=0, left=0) 

获取的为相对于自身左上点的left,right,top,bottom。Points to a 
RECT
 structure or aCRect object to receive the client coordinates. Theleft andtop members will be 0. The
right andbottom members will contain the width and height of the window. m_PicDraw.GetClientRect(&picClientRect);
+  picClientRect {top=0 bottom=512 left=0 right=690} tagRECT 

注意:像Dialog的窗口,它的GetClientRect的范围是比GetWindowRect取出的范围小的,因为GetClientRect去除了边界的信息:提供的是可供使用的内部大小。The client coordinates specify the upper-left and lower-right corners of the client area.

如下面这个:

+                clientRect         {top=0 bottom=510 left=0 right=902}     CRect   相对于自身的范围

 

 

4. GetWindowRect获取到的为相对于屏幕的范围

获取的为相对于屏幕左上点的left,right,top,bottom范围的Points to a CRect object or aRECT structure that will receive thescreen coordinates of the upper-left and lower-right corners.

 m_PicDraw.GetWindowRect(&picWindowRect);

+  picWindowRect {top=119 bottom=631 left=401 right=1091} tagRECT

 

5. ScreenToClient/ClientToScreen坐标系转换

这两个函数完成相对坐标系的转换

The ScreenToClient function converts the screen coordinates of a specified point on the screen to
client-area coordinates

The ClientToScreen function converts the client-area coordinates of a specified point to
screen coordinates.

 

在一个窗口中的组件:

client-area coordinates

组件相当于 窗口区域内左上点(此处非窗口的左上点,为窗口内部区域的左上点) 的坐标。

常用与动态创建组件的时候,例如XTP库中很多组件create的时候,都会需要一个CRect参数,这个参数的坐标系就是client-area coordinates

 

screen coordinates

组件相当于屏幕左上点的坐标。

常用于MoveWindows时的操作,通过GetWindowRect所获取的为该坐标系的数据

DialogClientRect (0, 0), (719, 555)   // 窗口GetClientRect
DialogWindowsRect (0, 42), (735, 635) // 窗口GetWindowsRect

ListCtrlClientRect (0, 0), (512, 512)     // List GetClientRect
ListCtrlWindowsRect (206, 76), (722, 592) // List GetWindwsRect
ScreenToClient(ListCtrlWindowsRect) (198, 4), (714, 520)  // <strong>ScreenToClient转换得到client-area coordinates坐标数据</strong>

 

应用场景:坐标系转换

当创建一个XTP组件的时候,如果参考另一组件的位置,我们可以使用GetWindowRect获得屏幕坐标,在通过ScreenToClient获取区域坐标。

区域坐标就可以用于创建XTP组件。

 

 

 

例子说明:

屏幕大小              800*600

程序的窗口大小 300*150         程序窗口位置,相对于左上点 100,50

坐标所在点(pt): 相对于程序(100,100)   相对于屏幕(100+100, 100+50),为 (200,150)

(左上点为基点,也即原点,下右x轴正向,向下y轴正向)

a. 在该坐标点pt坐标触发OnLButtonDown(UINT nFlags, CPoint point),传入的point为(100,100)

b. GetCursorPos(&apoint);获取到的点坐标为(200,150)

c. 窗口this->GetClientRect获取到得是(top=0, bottom=150, left=0, right=300)

d. 窗口this->GetWindowRect获取到的是(top=100, bottom=250, left=100, right=400)

要在 MFC 项目中建立一个名为 ClockDlg 的对话框类,可以按照以下步骤操作: 1. 打开 MFC 项目,在 Solution Explorer 中右键单击项目名称,选择 Add -> Class。 2. 在 Add Class 对话框中,选择 MFC Class,然后输入 Class Name 为 ClockDlg。 3. 在基类中选择 CDialog,然后单击 Add。 4. 在 ClassWizard 中添加 ClockDlg 的消息处理程序。 5. 在 ClockDlg.h 文件中添加以下代码: ``` #pragma once #include "afxwin.h" class CClockDlg : public CDialog { // Construction public: CClockDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data enum { IDD = IDD_CLOCK_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: HICON m_hIcon; // Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() }; ``` 6. 在 ClockDlg.cpp 文件中添加以下代码: ``` #include "stdafx.h" #include "ClockDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CClockDlg dialog CClockDlg::CClockDlg(CWnd* pParent /*=NULL*/) : CDialog(CClockDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CClockDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CClockDlg, CDialog) ON_WM_PAINT() ON_WM_QUERYDRAGICON() END_MESSAGE_MAP() // CClockDlg message handlers BOOL CClockDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control } void CClockDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CClockDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } ``` 现在,您已经成功创建了一个名为 ClockDlg 的对话框类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值