Какова альтернатива GWL_USERDATA для хранения указателя на объект?
Вопрос
В приложениях Windows, над которыми я работаю, у нас есть пользовательский фреймворк, который находится непосредственно над Win32 (не спрашивайте).Когда мы создаем окно, наша обычная практика заключается в том, чтобы поместить this
в области пользовательских данных окна через SetWindowLong(hwnd, GWL_USERDATA, this)
, что позволяет нам иметь обратный вызов, подобный MFC, или тесно интегрированный WndProc
, в зависимости от обстоятельств.Проблема в том, что это не будет работать на Win64, поскольку LONG имеет ширину всего 32 бита.Какое лучшее решение этой проблемы работает как на 32-, так и на 64-разрядных системах?
Решение
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;
Другие советы
Другой альтернативой является SetProp / removeProp (когда вы создаете подкласс для окна, которое уже использует GWLP_USERDATA)
Другой хорошей альтернативой является использование WNDPROC в стиле ATL, для получения дополнительной информации об этом см.