Какая альтернатива GWL_USERDATA для хранения указателя объекта? - PullRequest
27 голосов
/ 22 августа 2008

В приложениях для Windows, над которыми я работаю, у нас есть пользовательский каркас, который находится прямо над Win32 (не спрашивайте). Когда мы создаем окно, наша обычная практика - помещать this в область пользовательских данных окна через SetWindowLong(hwnd, GWL_USERDATA, this), что позволяет нам иметь MFC-подобный обратный вызов или тесно интегрированный WndProc, в зависимости. Проблема в том, что это не будет работать на Win64, так как LONG имеет ширину всего 32 бита. Как лучше решить эту проблему, которая работает как в 32-, так и в 64-битных системах?

Ответы [ 2 ]

36 голосов
/ 22 августа 2008

SetWindowLongPtr был создан для замены SetWindowLong в этих случаях. Параметр LONG_PTR позволяет хранить указатель для 32-битных или 64-битных компиляций.

LONG_PTR SetWindowLongPtr(      
    HWND hWnd,
    int nIndex,
    LONG_PTR dwNewLong
);

Помните, что константы тоже изменились, поэтому использование теперь выглядит так:

SetWindowLongPtr(hWnd, GWLP_USERDATA, this);

Также не забывайте, что теперь, чтобы получить указатель, вы должны использовать GetWindowLongPtr :

LONG_PTR GetWindowLongPtr(      
    HWND hWnd,
    int nIndex
);

И использование будет выглядеть (опять же, с измененными константами):

LONG_PTR lpUserData = GetWindowLongPtr(hWnd, GWLP_USERDATA);
MyObject* pMyObject = (MyObject*)lpUserData;
9 голосов
/ 29 августа 2008

Другой альтернативой является SetProp / RemoveProp (когда вы создаете подкласс для окна, которое уже использует GWLP_USERDATA)

Еще одна хорошая альтернатива - это WNDPROC в стиле ATL, для получения дополнительной информации см.

...