7

如何获取窗口客户区相对于屏幕的坐标?

我考虑过使用GetClientRectand ClientToScreen。另外,在浏览器窗口中是什么ClientRect?只有HTML显示文档的矩形,或者它包括浏览器栏和弹出菜单,可能会缩小HTML文档的尺寸?

我试过这个:

HWND hWnd;
RECT rc;
if (GetClientRect(hWnd, &rc)) // get client coords 
{
    MapWindowPoints(hWnd, NULL, reinterpret_cast<POINT*>(&rc), 2); // converts rect rc points
    return rc.top;
}

但可悲的是,浏览器的客户矩形包括所有弹出的浏览器菜单和栏,因此不能用于检测浏览器 HTML 文档空间的准确坐标。如果有人对如何完成提出建议,将很乐意尝试。

4

4 回答 4

13

是的,您可以使用以下ClientToScreen功能执行此操作:

RECT rc;
GetClientRect(hWnd, &rc); // get client coords
ClientToScreen(hWnd, reinterpret_cast<POINT*>(&rc.left)); // convert top-left
ClientToScreen(hWnd, reinterpret_cast<POINT*>(&rc.right)); // convert bottom-right

浏览器中的“客户端”矩形是什么取决于浏览器的实现。您可以使用 Spy++ 自己发现这一点。

于 2013-03-31T21:11:06.310 回答
3

要将窗口的客户矩形转换为屏幕坐标,请调用MapWindowPoints函数。它实现了特殊处理以始终返回一个 valid RECT,即使在涉及从右到左布局的窗口的场景中使用时也是如此:

如果hWndFromhWndTo(或两者)是镜像窗口(即具有WS_EX_LAYOUTRTL扩展样式)并且恰好两个点在lpPoints中传递,MapWindowPoints则将这两个点解释为 aRECT并可能自动交换该矩形的左右字段以确保左不大于右。

相反,在这两点上调用ClientToScreen无法考虑 RTL 布局,并且可能会产生无效的RECT. 它未能遵守矩形坐标不变量之一:

矩形右侧的坐标值必须大于其左侧的坐标值。同样,底部的坐标值必须大于顶部的坐标值。

在屏幕坐标中返回窗口的客户矩形的可靠函数如下所示:

RECT client_rect_in_screen_space(HWND const hWnd) {
    RECT rc{ 0 };
    if (!::GetClientRect(hWnd, &rc)) {
        auto const err_val{ ::GetLastError() };
        throw std::system_error(err_val, std::system_category());
    }

    ::SetLastError(ERROR_SUCCESS);
    if(::MapWindowPoints(hWnd, nullptr, reinterpret_cast<POINT*>(&rc), 2) == 0) {
        auto const err_val{ ::GetLastError() };
        if (err_val != ERROR_SUCCESS) {
            throw std::system_error(err_val, std::system_category());
        }
    }

    return rc;
}

问题更新要求一个不同的、不相关的问题。系统中没有内置 API,可让您查询 Web 浏览器的显示区域以获取其 HTML 内容。最有希望的解决方案是使用UI 自动化。然而,这个问题过于宽泛,无法在此处提供更详细的答案。

于 2018-03-29T09:24:28.663 回答
1

正如 评论的Raymond Chen那样,这样做的首选方式应该类似于以下内容:

inline POINT get_client_window_position(const HWND window_handle)
{
    RECT rectangle;

    GetClientRect(window_handle, static_cast<LPRECT>(&rectangle));
    MapWindowPoints(window_handle, nullptr, reinterpret_cast<LPPOINT>(& rectangle), 2);

    const POINT coordinates = {rectangle.left, rectangle.top};

    return coordinates;
}
于 2019-06-26T09:52:35.303 回答
0
POINT origin;
origin.x = 0;
origin.y = 0;
ClientToScreen(hWnd, &origin);

现在origin,在屏幕坐标中,客户区的左上角。

要将 (x,y) 从客户区坐标转换为屏幕坐标,请添加origin. 做相反的事情,减去。

于 2016-04-19T23:41:27.923 回答