如何获取窗口客户区相对于屏幕的坐标?
我考虑过使用GetClientRect
和ClientToScreen
。另外,在浏览器窗口中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文档空间的准确坐标。如果有人得到了如何做的建议,那就会很乐意尝试。
答案 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
。
要做反向,减去。