windows 窗口坐标

这是 Windows / GUI 编程中三种最常见的坐标系概念,用通俗方式给你解释:


🧭 三种坐标系空间关系概览

🖥️ 屏幕 Screen (0,0) 为原点

🪟 窗口 Window(含标题栏、边框)

直接获取

ScreenToClient

ClientToScreen

屏幕坐标

📐 客户区 Client (0,0) 为原点

绘图操作:WM_PAINT、TextOut

🧩 子控件 (20,30) 以父窗口客户区左上角为原点

🖱️ 鼠标位置:GetCursorPos → 屏幕坐标

图例说明:

  • 蓝色矩形:屏幕坐标系(原点在屏幕左上角)
  • 紫色矩形:客户区坐标系(原点在窗口客户区左上角)
  • 绿色矩形:父窗口坐标(子控件相对父窗口客户区偏移)
  • 箭头指示 ClientToScreen / ScreenToClient 等转换方向

1️⃣ 屏幕坐标(Screen Coordinates)

以整个屏幕左上角为原点 (0, 0)

  • X 轴向右增大,Y 轴向下增大
  • 适用于:鼠标全局位置、SetWindowPos(HWND_TOPMOST)、GetCursorPos()

示例:

+-- 屏幕 ----------------------+
| (0,0)                        |
|    +---- 窗口 --------------+|
|    | (client 0,0)           ||
|    +------------------------+|
+------------------------------+

API 例:

POINT pt;
GetCursorPos(&pt);   // pt.x, pt.y 是屏幕坐标

2️⃣ 客户区坐标(Client Coordinates / 客户区 DC)

以窗口"客户区"左上角为原点 (0, 0)

  • 不含标题栏、边框、菜单、滚动条
  • 只算可绘制区域
  • 适用于:WM_LBUTTONDOWNlParam、CDC 绘图(TextOutLineTo

示例:

+---------------- 窗口边框 ----------------+
| 标题栏                                    |
| +----------- 客户区 --------------------+ |
| | (0,0)  这里是客户区坐标原点           | |
| |                                         | |
| +----------------------------------------+ |
+--------------------------------------------+

代码:

// WM_LBUTTONDOWN 中
int x = LOWORD(lParam);  // 客户区 X
int y = HIWORD(lParam);  // 客户区 Y

3️⃣ 父窗口坐标(Parent / Window Coordinates)

子窗口相对于其父窗口客户区左上角为 (0,0)

  • 用于 CreateWindowEx() 中指定子控件位置(按钮、编辑框等)
  • 父窗口可以是主窗口,也可以是容器(Group Box 等)
  • 对话框单位(DLU)最终也会转成这个坐标系

示例:

// 在父窗口 hWnd 上创建按钮
CreateWindowEx(
    0,
    L"BUTTON",
    L"确定",
    WS_CHILD | WS_VISIBLE,
    20, 30,    // ← 相对于父窗口客户区 (20,30)
    100, 30,
    hWnd,      // 父窗口
    (HMENU)IDC_BTN_OK,
    hInst,
    NULL
);

🔄 坐标相互转换(非常重要)

Windows 提供 API 做转换:

// 客户区 → 屏幕
ClientToScreen(hWnd, &pt);

// 屏幕 → 客户区
ScreenToClient(hWnd, &pt);

// 子窗口坐标 → 父窗口坐标(其实就是 ClientToScreen 再 ScreenToClient 到父)
MapWindowPoints(hChild, hParent, &pt, 1);

坐标系关系与转换流程图

父窗口-子窗口关系

鼠标点击事件发生

获取屏幕坐标
GetCursorPos(&pt)

屏幕坐标
(Screen Coordinates)

ScreenToClient(hWnd, &pt)

客户区坐标
(Client Coordinates)

窗口绘图操作
WM_PAINT, TextOut等

ClientToScreen(hWnd, &pt)

父窗口客户区坐标
(Parent Coordinates)

子窗口控件位置
CreateWindowEx(x,y)

MapWindowPoints(hChild, hParent, &pt, 1)

图表说明:

  1. 屏幕坐标(蓝色):以整个屏幕左上角为原点,通过GetCursorPos获取
  2. 客户区坐标(紫色):以窗口客户区左上角为原点,通过ScreenToClient从屏幕坐标转换
  3. 父窗口坐标(绿色):子控件相对于父窗口客户区的位置,通过MapWindowPoints转换

转换方向:

  • 屏幕 ↔ 客户区:ScreenToClient / ClientToScreen
  • 客户区 ↔ 父窗口坐标:MapWindowPoints(实际是ClientToScreen+ScreenToClient组合)

📌 一句话记忆

坐标系原点在哪常见用途
屏幕坐标屏幕左上角 (0,0)鼠标位置、置顶窗口、拖拽
客户区坐标窗口客户区左上角WM_PAINT、鼠标点击客户区
父窗口坐标父窗口客户区左上角CreateWindowEx 子控件位置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值