3

At some point, I have this

LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if(msg==WM_CREATE)
    {
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
            D2DResources* pD2DResources = (D2DResources*)pcs->lpCreateParams;

            ::SetWindowLongPtrW(
                hWnd,
                GWLP_USERDATA,
                PtrToUlong(pD2DResources)
                );
    }
    else
    {
        D2DResources* pD2DResources = reinterpret_cast<D2DResources*>(static_cast<LONG_PTR>(
            ::GetWindowLongPtrW(
                hWnd,
                GWLP_USERDATA
                )));

        switch(msg)
        {

    case WM_PAINT:
        {
            pD2DResources->OnRender();
            ValidateRect(hWnd, NULL);
        }
        break;

    case WM_SIZE:
        {
            UINT width = LOWORD(lParam);
            UINT height = HIWORD(lParam);
            pD2DResources->OnResize(width, height);
        }
        break;

So my WinProc has access to a previously created D2DResources. Now I want it to have access to another previously created object. How do I do that? I mean, can it have access to more than one previously created object? If so, how?

Edit: Raymond Chen said: "Pass a pointer to a structure as the lpCreateParams. You can put anything you want in the structure." How do I do that? Can anyone give me an exemple?

Mickael Bergeron Néron
  • 1,472
  • 1
  • 18
  • 31
  • Pass a pointer to a structure as the lpCreateParams. You can put anything you want in the structure. – Raymond Chen Mar 15 '13 at 01:38
  • I don't get it. How do I do that? – Mickael Bergeron Néron Mar 15 '13 at 01:39
  • @MickaelBergeronNéron: You already ARE doing that, passing a pointer to a `D2DResources` structure. Instead, make a structure that contains `D2DResources` and whatever other data you need, and pass its address. – Ben Voigt Mar 15 '13 at 01:58
  • Thank you. I hoped there was another way since I didn't want to have to change my code that much. – Mickael Bergeron Néron Mar 15 '13 at 02:00
  • 2
    duplicate of [sending lparam as a pointer to class, and use it in WndProc()](http://stackoverflow.com/questions/7384823/sending-lparam-as-a-pointer-to-class-and-use-it-in-wndproc), explained in MSDN step by step [here](http://msdn.microsoft.com/en-us/library/ff381400%28d=printer,v=vs.85%29.aspx). – Raymond Chen Mar 15 '13 at 02:21

1 Answers1

2

Create your own structure and pass it to the window when you create it. You can put anything you like in there, including pointers to other things.

e.g.

struct MyWindowData
{
    D2DResources*   pD2DResources;
    void*       pMyOtherData;
    int     iSomethingElse;
};


// on window creation
MyWindowData* pData = new MyWindowData(...);
HWND hWnd = CreateWindowEx(..., pData); // window will own the data and destroy it itself

// in the window procedure
if (msg == WM_CREATE)
{
    MyWindowData* pData = ((LPCREATESTRUCT)lParam)->lpCreateParams;
    SetWindowLongPtr(hWnd, GWLP_USERDATA, (ULONG_PTR)pData);
}
else
{
    MyWindowData* pData = (MyWindowData*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    switch (msg)
    {
        case WM_PAINT:
            pData->pD2DResources->OnRender();
            break;

        case WM_NCDESTROY:
            delete pData; // delete data on destroy
            break;
    }

    ...
}
Jonathan Potter
  • 36,172
  • 4
  • 64
  • 79