Подтвердить что ты не робот

Какая альтернатива GWL_USERDATA для хранения указателя объекта?

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

4b9b3361

Ответ 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, для получения дополнительной информации об этом, см.