![](/img/trans.png)
[英]WM_MOUSEMOVE GET_X_LPARAM AND GET_Y_LPARAM Catch wrong Coordinates
[英]How to use WM_MOUSEMOVE LParam value outside of WndProc in a separate translation unit?
也許這只是一個代碼組織問題,也許我缺少一些非常基本的 C++ 知識——我已經嘗試了幾個小時來找到一個合理的解決方案,但似乎沒有任何效果,所以我轉向了 inte.net .
我正在編寫一個用於游戲開發的 Direct2D 應用程序,當出現 WM_MOUSEMOVE 消息時,我試圖從 WndProc lParam 獲取鼠標坐標,正如此處的 MSDN 文章中概述和推薦的那樣。 以下是項目相關部分的配置方式。
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);
};
}
主.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;
}
我的問題:如何使用 window.cpp 中WndProc function 的xPosAbsolute /yPosAbsolute值合理分配(和更新) main.cpp中的absolute_mouse_pos_x和absolute_mouse_pos_y ?
首先想到的是實例化 WndProc function 以便它可以訪問 Window 結構的成員,但這是不可能/不切實際的,因為成員 function 的簽名具有隱藏的“this”參數,如其他答案Stack Overflow 上比如這個有詳細的。
之后,我嘗試在 window.h 中創建全局變量,在 window.cpp 中的 WndProc function 中分配它們,並在 main.cpp 中引用它們。 main.cpp 可以使用兩個全局變量的初始值,但是稍后用新值更新這些全局變量似乎對 main.cpp 完全不可見(我想知道這些全局變量是否隱式只讀,但這可能只是缺乏我的理解/用戶錯誤)。 除了這種行為之外,普遍的看法是除非絕對必要,否則不應使用全局變量,而且必須將全局變量用於看似簡單的事情似乎很奇怪。 有沒有更簡單/更好的方法?
謝謝!
這里有一些可能的方法來實現這一點。
這非常簡單,返回 cursor 的屏幕坐標,而不是 window 中的坐標。根據您正在制作的應用程序,這可能是(不)理想的。 您可以使用ScreenToClient()將這些坐標轉換為 window 坐標。
這是一個使用 main.cpp 的簡單示例,但可以在任何其他翻譯單元中完成。
主.cpp
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
// ...
POINT p;
while (true) {
GetCursorPos(&p);
int absolute_mouse_pos_x = p.x;
int absolute_mouse_pos_y = p.y;
// etc...
}
return 0;
}
這更復雜,但會為您提供 cursor 的window 坐標(通過 WM_MOUSEMOVE 消息的 lParam),並允許您在 WndProc 中獲取/設置您選擇的自定義結構的 state。 以下是實現此功能所需的對 window.h 和 window.cpp 的更改,以及從單獨的翻譯單元 (main.cpp) 訪問這些變量的示例。
window.h
struct Window {
HWND _hwnd;
int mouse_x;
int mouse_y;
bool Initialize(int width, int height);
// etc..
};
window.cpp
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Window* window;
if (msg == WM_CREATE)
{
CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
window = reinterpret_cast<Window*>(pCreate->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)window);
}
else
{
LONG_PTR ptr = GetWindowLongPtr(hwnd, GWLP_USERDATA);
window = reinterpret_cast<Window*>(ptr);
}
switch (msg)
{
case WM_MOUSEMOVE:
window->mouse_x = GET_X_PARAM(lParam);
window->mouse_y = GET_Y_PARAM(lParam);
break;
// etc...
}
return 0;
}
bool Window::Initialize(int width, int height) {
WNDCLASS wc;
wc.lpfnWndProc = WndProc;
// etc...
CreateWindowEx(.., this); // add the "this" pointer as the last argument to CreateWindowEx()
}
主.cpp
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, INT nCmdShow)
{
// ...
Window w;
w.Initialize(width, height);
while (true) {
int absolute_mouse_pos_x = w.mouse_x;
int absolute_mouse_pos_y = w.mouse_y;
// etc...
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.