【问题标题】:Getting mouse position within a window在窗口中获取鼠标位置
【发布时间】:2018-10-26 18:30:47
【问题描述】:

我希望在我的应用程序/游戏的主循环中获取光标位置。

通过一些研究,似乎有两种方法可以做到这一点: 首先监听 WM_MOUSEMOVE 事件并检查 lParam。 其次使用 GetCursorPos(),然后使用 ScreenToClient()。

我有一个设置为 1680x1050 的窗口,但是当查看来自任一方法的数据时,我最终在窗口的最右侧得到大约 1660 的值。

我找不到任何资源来解释为什么会发生这种情况,我想知道它是否与窗口创建有关?

这是我用来为我的应用程序创建窗口的代码

//Register the window class
WNDCLASS windowClass;
windowClass = {};
windowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = handleWindowMessages;
windowClass.hInstance = hInstance;
windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
windowClass.lpszClassName = L"D3D11 Rendering";
if (!RegisterClass(&windowClass))
{
    return 0;
}

//Create the window
HWND windowHandle
    = CreateWindowEx(0,
        windowClass.lpszClassName,
        L"D3D11 Rendering", 
        (WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME) | WS_VISIBLE,         //According to stackoverflow.com WS_OVERLAPPEDWINDOW ^ (XOR) WS_THICKFRAME will prevent window resizing
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        gResolutionX,
        gResolutionY,
        0, 0, hInstance, 0);

然后在主循环中我正在执行以下操作:

POINT p;
GetCursorPos(&p);
ScreenToClient(windowHandle, &p);

任何指针、提示或信息将不胜感激。

编辑:应用程序窗口未最大化和/或未超出任务栏。该问题发生在 x 轴和 y 轴上。我注意到顶部的标题栏将 y 位置保持在 0,而光标在其中。有没有办法到达屏幕的可渲染区域?在创建具有我希望游戏运行的分辨率的窗口时,我希望中间的位(不确定实际术语 - 没有边框和标题栏的位)与分辨率匹配。

【问题讨论】:

  • 最大化的窗口不会越过任务栏。客户区也不包括窗口标题。

标签: c++ winapi directx game-development


【解决方案1】:

窗口内的区域(不包括标题栏和边框等)称为客户区。 WM_MOUSEMOVE 消息将为您提供客户区中的坐标,该坐标位于该内部部分左上角的 (0, 0) 处。

GetCursorPos 将返回鼠标光标在屏幕空间中的位置(因此您对ScreenToClient 的调用是正确的)。由于窗口未最大化,并且您仍在指定边框(WS_OVERLAPPEDWINDOW 定义为 WS_OVERLAPPED | WS_THICKFRAME | etc...,并且您正在删除 WS_THICKFRAMEWS_OVERLAPPED 仍然包含边框)我的猜测是窗口的包括边框在内的布局会占用额外的 20 像素。如果您创建一个全屏无边框窗口(大小和位置都可以填满屏幕,并且仅使用WS_POPUP 样式),您应该会看到客户区填满了可用空间。

【讨论】:

  • 或者,调用GetWindowRect 并从GetCursorPos 返回的值中减去左上角。处理WM_MOUSEMOVE 通常没问题,但它无法让您查询特定时间点的鼠标位置,而这在游戏中可能是可取的。
  • 感谢您提供的信息。使我的应用程序全屏显示正确的数字,这意味着@Steve Smith 是正确的,他们假设边框占用了额外的像素。在使用此处给出的信息进行更多挖掘之后,我偶然发现了 Windows 函数“AdjustWindowRect”,它将获取所需的客户区域并提供创建窗口时要使用的“RECT”。感谢您的帮助
猜你喜欢
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 2013-01-20
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多