【发布时间】:2020-08-19 02:40:06
【问题描述】:
也许这只是一个代码组织问题,也许我缺乏一些极其基础的 C++ 知识——我已经尝试了几个小时来找到一个合理的解决方案,但似乎没有任何效果,所以我转向互联网。
我正在编写一个用于游戏开发的 Direct2D 应用程序,当出现 WM_MOUSEMOVE 消息时,我试图从 WndProc lParam 获取鼠标坐标,正如 MSDN article here 中所概述和推荐的那样。以下是项目相关部分的配置方式。
window.h
struct Window {
HWND _hwnd;
bool Initialize(int width, int height);
void RunMessageLoop();
};
window.cpp
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_MOUSEMOVE:
int xPosAbsolute = GET_X_PARAM(lParam); // as is suggested by MSDN
int yPosAbsolute = GET_Y_PARAM(lParam); // as is suggested by MSDN
...
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
bool Window::Initialize(int width, int height) {
WNDCLASS wc;
wc.lpfnWndProc = WndProc;
// etc...
}
void Window::RunMessageLoop() {
MSG Msg;
while (true)
{
GetMessage(&Msg, NULL, 0, 0);
TranslateMessage(&Msg);
DispatchMessage(&Msg);
};
}
main.cpp
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
// ...
while (true) {
int absolute_mouse_pos_x = ???;
int absolute_mouse_pos_y = ???;
// etc...
}
return 0;
}
我的问题:如何在 main.cpp 中合理分配(和更新)absolute_mouse_pos_x 和 absolute_mouse_pos_y使用 window.cpp 中 WndProc 函数的 xPosAbsolute/yPosAbsolute 值?
首先想到的是实例化 WndProc 函数,以便它可以访问 Window 结构的成员,但这是不可能/不切实际的,因为成员函数的签名具有隐藏的“this”参数, as other answers on Stack Overflow such as this one have detailed.
之后,我尝试在 window.h 中创建全局变量,在 window.cpp 的 WndProc 函数中分配它们,并在 main.cpp 中引用它们。 main.cpp 可以使用两个全局变量的初始值,但是后来用新值更新这些全局变量似乎对 main.cpp 完全不可见(我想知道这些全局变量是否是隐式只读的,但这可能只是缺少我的理解/用户错误)。除了这种行为之外,普遍的看法是除非绝对必要,否则不应使用全局变量,而且对于看似简单的事情必须使用全局变量似乎很奇怪。没有更简单/更好的方法吗?
谢谢!
【问题讨论】:
-
你当然可以使用全局变量,尽管你必须正确地做——大概你没有(尽管你没有展示你做了什么)。另一种方法是忽略
WM_MOUSEMOVE消息,只要你想要当前光标位置就调用GetCursorPos()。 -
我觉得可以使用
POINT cursor;GetCursorPos(&cursor);获取当前鼠标位置信息。你能解释一下为什么需要通过 WndProc 传递它吗? -
@ZhuSong 对于我自己的目的,它不一定需要通过 WndProc 传递,这似乎是基于 MSDN 推荐的用法(至少对于 UI 样式的光标坐标)。感谢大家的帮助。今天早上我尝试了 GetCursorPos() 和 Get/SetWindowLongPtr 方法。我会尝试在我的结果中发布答案,以帮助其他遇到类似问题的人。