На самом деле ... я думаю, что вы делаете ошибку. Значение в GWLP_USERDATA
и пространство, выделенное в соответствии с cbWndExtra
, представляют собой две разные вещи ...
Значение GWLP_USERDATA
является частью пространства, выделенного Windows для каждого окна. Для классов окон так часто требуется бит размером с указатель, что Windows просто включает его в базовую стоимость окна вместе со всеми другими предопределенными «словами окна». Посмотрите документацию для параметра nIndex
для GetWindowLongPtr()
:
Определяет смещение от нуля до значения, которое необходимо получить. Допустимые значения находятся в диапазоне от нуля до количества байтов дополнительной памяти окна, минус размер целого числа.
Итак, GetWindowLongPtr(hWnd, 0)
извлекает первые sizeof(LONG_PTR)
байтов, выделенных в ответ на cbWndExtra
, GetWindowLongPtr(hWnd, sizeof(LONG_PTR))
дает вам следующие данные размером с указатель и так далее. Как следует из названия, nIndex
действует как индекс в массив байтов (хотя он всегда возвращает значение размером с указатель). Теперь взглянем на значения индекса, назначенные предопределенным константам данных окна: все они отрицательные, включая GWLP_USERDATA
! Фактически, GetWindowLongPtr()
начинает индексирование в середину данных окна, причем данные, общие для всех окон, располагаются «до» индекса 0, а все данные, относящиеся к классу окна, находятся после него.
Диалоговые окна построены поверх базовой поддержки, предусмотренной для обычных окон. Поскольку они требуют больше данных, чем обычные окна, необходимо указать не менее DLGWINDOWEXTRA
байтов в cbWndExtra
. Как и любые другие такие данные, они доступны через положительное значение, переданное GetWindowLongPtr()
.
Поэтому, когда вы просите
GetWindowLongPtr(hWnd, GWLP_USERDATA + DLGWINDOWEXTRA + 0);
... вы на самом деле получаете данные по индексу -21 + 30 + 0 = 9
: значение где-то в собственных данных менеджера диалогов. Не то, что вы хотите!
К настоящему времени вы должны понимать, что при доступе к данным, выделенным через cbWndExtra = DLGWINDOWEXTRA + extra
, вам нужно только сместить ваш запрос на DLGWINDOWEXTRA
. Итак:
GetWindowLongPtr(hWnd, DLGWINDOWEXTRA + 0);
... даст вам первый элемент дополнительных данных. GWLP_USERDATA
следует использовать только , если вы хотите получить или установить один указатель всегда выделенных пользовательских данных, связанных с каждым окном.