簡體   English   中英

如何在單獨的翻譯單元中使用 WndProc 之外的 WM_MOUSEMOVE LParam 值?

[英]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_xabsolute_mouse_pos_y

首先想到的是實例化 WndProc function 以便它可以訪問 Window 結構的成員,但這是不可能/不切實際的,因為成員 function 的簽名具有隱藏的“this”參數,如其他答案Stack Overflow 上比如這個有詳細的。

之后,我嘗試在 window.h 中創建全局變量,在 window.cpp 中的 WndProc function 中分配它們,並在 main.cpp 中引用它們。 main.cpp 可以使用兩個全局變量的初始值,但是稍后用新值更新這些全局變量似乎對 main.cpp 完全不可見(我想知道這些全局變量是否隱式只讀,但這可能只是缺乏我的理解/用戶錯誤)。 除了這種行為之外,普遍的看法是除非絕對必要,否則不應使用全局變量,而且必須將全局變量用於看似簡單的事情似乎很奇怪。 有沒有更簡單/更好的方法?

謝謝!

這里有一些可能的方法來實現這一點。

  1. 獲取光標位置()

這非常簡單,返回 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;
}
  1. 獲取/設置WindowLongPtr

這更復雜,但會為您提供 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM