客户端矩形坐标在屏幕上

时间:2013-03-31 21:06:32

标签: c++ winapi plugins browser

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

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

我试过这个:

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 个答案:

答案 0 :(得分:11)

是的,您可以使用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 ++自己发现它。

答案 1 :(得分:0)

要将窗口的客户端矩形转换为屏幕坐标,请调用MapWindowPoints函数。它实现特殊处理以始终返回有效的RECT,即使在涉及right-to-left layout的窗口的场景中使用时也是如此:

  

如果 hWndFrom hWndTo (或两者)都是镜像窗口(即WS_EX_LAYOUTRTL扩展样式)并且正好在 lpPoints ,MapWindowPoints会将这两个点解释为RECT,并可能自动交换该矩形的左右字段,以确保左边不大于右边。

相反,在两个点上调用ClientToScreen无法考虑RTL布局,并且可能产生无效的RECT。它无法遵守rectangle coordinate不变量之一:

  

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

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

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 Automation。然而,这个问题过于宽泛,无法在此提供更详细的答案。

答案 2 :(得分:0)

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;
}

答案 3 :(得分:-1)

POINT origin;
origin.x = 0;
origin.y = 0;
ClientToScreen(hWnd, &origin);

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

要将(x,y)从客户区域坐标转换为屏幕坐标,请添加origin。 要做反向,减去。