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