Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sending lparam as a pointer to class, and use it in WndProc()

i have this abstract code : i want to use lParam (last parameter) in CreateWindowEx() to save a pointer to a class thats declared in the begining of main - SaveArr. then, i want to use it in the function WndProc. in the begining i did a global array, and then i could use it anywhere, but its not so "clever" as far as c++ concern, so im trying to upgrade it a bit.

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.

}

}
like image 509
dusm Avatar asked Oct 10 '22 00:10

dusm


1 Answers

Adding caller information to the window:

m_window = CreateWindow(..., this);

Similar for the extended CreateWindowEx.

Obtaining a pointer to the caller:

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));
    }
}

This method needs to be called in your message callback.

like image 135
Matthias Avatar answered Jan 01 '23 11:01

Matthias