В какой-то момент у меня есть это

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;

Итак, мой WinProc имеет доступ к ранее созданным D2DResources. Теперь я хочу, чтобы у него был доступ к другому ранее созданному объекту. Как я могу это сделать? Я имею в виду, может ли он иметь доступ к нескольким ранее созданным объектам? Если да, то как?

Изменить: Раймонд Чен сказал: «Передайте указатель на структуру как lpCreateParams. Вы можете поместить в структуру все, что захотите». Как я могу это сделать? Кто-нибудь может дать мне пример?

3
Mickael Bergeron Néron 15 Мар 2013 в 05:35
Передайте указатель на структуру как lpCreateParams. Вы можете поместить в структуру все, что захотите.
 – 
Raymond Chen
15 Мар 2013 в 05:38
Я не понимаю. Как я могу это сделать?
 – 
Mickael Bergeron Néron
15 Мар 2013 в 05:39
@ MickaelBergeronNéron: Вы уже ДЕЛАЕТЕ это, передавая указатель на структуру D2DResources. Вместо этого создайте структуру, содержащую D2DResources и любые другие данные, которые вам нужны, и передайте ее адрес.
 – 
Ben Voigt
15 Мар 2013 в 05:58
Спасибо. Я надеялся, что есть другой способ, поскольку мне не хотелось так сильно менять свой код.
 – 
Mickael Bergeron Néron
15 Мар 2013 в 06:00
2
 – 
Raymond Chen
15 Мар 2013 в 06:21

1 ответ

Лучший ответ

Создайте свою собственную структуру и передайте ее окну при ее создании. Вы можете поместить туда все, что захотите, включая указатели на другие вещи.

Например

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

    ...
}
2
Jonathan Potter 15 Мар 2013 в 06:00