Winapi: SetWindowLong и GetWindowLong возвращают неправильное значение

88
05 февраля 2022, 12:10

Кусочек инициализации окна в конструкторе собственного класса:

В качестве lparam посылаю this, чтобы в последствии получить его в функции обработки сообщений.

 WNDCLASS wc;
  wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = sizeof(win *);
  wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
  wc.hCursor = LoadCursor(nullptr, (CHAR *)IDC_ARROW);
  wc.hIcon = LoadIcon(nullptr, (CHAR *)IDI_ASTERISK);
  wc.lpszMenuName = nullptr;
  wc.hInstance = hInstance;
  wc.lpfnWndProc = WindowFunc;
  wc.lpszClassName = WindowClassName;
  if (!RegisterClass(&wc))
  {
    MessageBox(NULL, "Error register window class", "ERROR", MB_OK);
    return;
  }
  /* Create window */
  hWnd =
    CreateWindow(WindowClassName,
      "Ray-tracing",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, CW_USEDEFAULT,
      CW_USEDEFAULT, CW_USEDEFAULT,
      nullptr, nullptr, hInstance, reinterpret_cast<VOID *>(this));

Собственно, получаю свой указатель, чтобы дальше работать:

case WM_CREATE:
    /* Attach 'this' - window class pointer - to window */
    SetWindowLong(hWnd, 0, (DWORD)((CREATESTRUCT *)lParam)->lpCreateParams);
    //break;
  default:
      Win = (win *)((DWORD)((CREATESTRUCT *)lParam)->lpCreateParams);///*reinterpret_cast<*/(win *)/*>*/(GetWindowLong(hWnd, 0));
    if (Win != nullptr)
      switch (Msg)
      {
      case WM_CREATE:
        Win->hWnd = hWnd;

Итак, в чем же заключается подвох?

При некотором выполнении кода по шагам this равен 0х0000001088aff190

Когда я использую SetWindowLong и потом сразу же GetWindowLong, у меня в том самом поле lpCreateParams, если преобразовать в указатель, лежит.... 0хffffffff88aff190

Видно, что указатель был получен правильный, но почему-то записался крюкнутый. Подскажите, в чем проблема? Меня особенно смущает то, что мой код работает исправно на другом компьютере...

Answer 1

SetindowLong и GetWindowLong возвращают неправильные значения потому что они сохраняют только четыре байта и не могут быть использованы для хранения указателей на 64-битной платформе. Вместо них следует использовать SetindowLongPtr и GetWindowLongPtr.

Кроме того, следует использовать wchar_t варианты функций, т.е. не CreateWindow, а CreateWindowW и т.п.

READ ALSO
Вывод слова если в нем есть цифра

Вывод слова если в нем есть цифра

Как вывести из строки слова в которых есть цифра?

91
Работа с массивами C++

Работа с массивами C++

Подскажите пожалуйста как сформировать массив положительных из уже существующего массива ,как именно работать с размерностью нового массива,если...

91
С++ оптимизировать вложенный цикл

С++ оптимизировать вложенный цикл

Суть задания: есть список покупок по днямСписок является вектором векторов

102
c++,list и структура

c++,list и структура

Мне надо пробежаться по list,который хранит имеет тип структурыКаким образом можно в цикле перебрать каждый элемент и распечатать? Допустим...

110