5

我有这个抽象代码:我想在 CreateWindowEx() 中使用 lParam(最后一个参数)来保存指向在 main 开头声明的类的指针 - SaveArr。然后,我想在函数 WndProc 中使用它。一开始我做了一个全局数组,然后我可以在任何地方使用它,但就 c++ 而言,它并不是那么“聪明”,所以我试图对其进行升级。

class Samples
{
        int arr[ITERATIONS+1];
        int index;
        ...
}

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{
        Samples * SaveArr;
        ...
    hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                          ClsName,
                          WindowCaption,
                          WS_OVERLAPPEDWINDOW,
                          INITIAL_WIN_LOCAT_X,
                          INITIAL_WIN_LOCAT_Y,
                          WIN_WIDTH,
                          WIN_HIGHT,
                          NULL,
                          NULL,
                          hInstance,
                          NULL);    //here i want to pass SaveArr, so that i can use it in the WndProc(...) function

...
return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
   ...      //here i would like to use lParam as the class pointer, meaning using the 
              SaveArr declared in the main function.

}

}
4

5 回答 5

2

最好的方法是

    LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
    {
           Samples *savearr = (Samples*)GetWindowLong(hWnd,GWL_USERDATA)
           switch(Msg)
           {
                case WM_CREATE:
                    SetWindowLong(hWnd, GWL_USERDATA, (LONG)lParam);
                    break;
           }
    }

下次调用 WndProc 时,该值将在 savearr 中,并且可以使用。

于 2011-09-12T08:10:07.617 回答
1

参考

lpParam [输入,可选]

Type: LPVOID

Pointer to a value to be passed to the window through the

WM_CREATE 消息的 lParam 参数指向的 CREATESTRUCT 结构(lpCreateParams 成员)。此消息在返回之前由该函数发送到创建的窗口。

If an application calls CreateWindow to create a MDI client

窗口中,lpParam 应该指向一个 CLIENTCREATESTRUCT 结构。如果一个 MDI 客户窗口调用 CreateWindow 来创建一个 MDI 子窗口,lpParam 应该指向一个 MDICREATESTRUCT 结构。如果不需要其他数据,lpParam 可能为 NULL。

您期望 lParam 始终传递给 WndProc,但它仅通过 WM_CREATE 传递。

请注意,即使那样它也不是直接传递的,而是通过一个结构,它是 WM_CREATE 的实际 lParam。

于 2011-09-12T08:00:42.357 回答
1

将调用者信息添加到窗口

m_window = CreateWindow(..., this);

类似的扩展CreateWindowEx

获取指向调用者的指针

template< typename CallerT >
[[nodiscard]]
CallerT* WindowCaller(HWND window, UINT message, LPARAM lParam) noexcept
{
    if (message == WM_NCCREATE) [[unlikely]]
    {
        const auto caller = reinterpret_cast< CallerT* >(
                            reinterpret_cast< CREATESTRUCT* >(lParam)->lpCreateParams);

        // Change the user data of the window for subsequent messages.
        ::SetWindowLongPtr(window, GWLP_USERDATA,
                           reinterpret_cast< LONG_PTR >(caller));

        return caller;
    }
    else
    {
        // Retrieve the user data of the window.
        return reinterpret_cast< CallerT* >(
                    ::GetWindowLongPtr(window, GWLP_USERDATA));
    }
}

此方法需要在您的消息回调中调用。

于 2018-02-26T21:21:03.100 回答
0

您读取 lParam 的唯一机会是在 WM_CREATE 期间。如果您想稍后继续使用该值,则必须将其存储在某个地方。也许作为 WndProc 的静态或以其他方式将其分配给将要作用域的其他东西。

于 2011-09-12T08:08:40.340 回答
0

为什么坚持使用最后一个,lpParam 值设置为 X,然后在 WM_CREATE 上捕获它(通过所有间接结构的东西,不少于!)然后设置 GWL_USERDATA?!

为什么不切入正题并执行以下操作: HWND H=CreateWindow(.....) SetWindowLong(H,GWL_USERDATA,X) 换句话说,只需将 X 直接放在那里,您自己,就在窗口创建语句之后。

在我的测试中,它可以工作,只要您针对某些已知句柄列表测试窗口句柄,您就可以防止您的程序接收到一些错误消息,并防止不当使用其他用户数据。

于 2014-08-06T05:01:10.137 回答