WINAPI C ++ GetDlgItem не возвращает допустимый дескриптор - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь получить дескриптор дочернего окна по его идентификатору, но для этого мне нужно дважды привести идентификатор, иначе это не сработает. Есть ли другой способ? Чего мне не хватает?

WINAPI x64 C ++

Код:

#define BASE_ID 100
UINT8 i = 1;
CreateWindow(... (HMENU)BASE_ID + i, ...)

//later in code

HWND hWnd = GetDlgItem(hParent, BASE_ID + i); // This won't work (Returns null handle)
HWND hWnd = GetDlgItem(hParent, (int)((HMENU)BASE_ID + i)); //Works but I get compiler warning

1 Ответ

0 голосов
/ 08 ноября 2018

Первый способ прекрасно работает в нормальных условиях, и это то, что вы должны использовать:

GetDlgItem(hParent, BASE_ID + i)

Причина, по которой он не работает в вашем коде, заключается в том, что BASE_ID + i (он же 101) НЕ тот же идентификатор, который вы передаете CreateWindow().

При вызове CreateWindow() вы сначала преобразуете константу BASE_ID BY САМ, а затем добавляете i к этому указателю, вызывая, таким образом, арифметику указателя, которая в результате выдает другой идентификатор (104 на 32-битной, 108 на 64-битной) ) чем вы ожидаете (101).

Таким образом, GetDlgItem(hParent, BASE_ID + i) не удается найти соответствующий идентификатор, тогда как GetDlgItem(hParent, (int)((HMENU)BASE_ID + i)) успешно, так как он использует ту же логику приведения, которую вы использовали при вызове CreateWindow(), таким образом находя соответствующий идентификатор.

Приведение имеет более высокий приоритет, чем сложение , поэтому (HMENU)BASE_ID + i интерпретируется компилятором как ((HMENU)BASE_ID) + i. Вам нужно исправить круглые скобки, чтобы выполнить сложение FIRST, затем произнесите результат:

CreateWindow(... (HMENU)(BASE_ID + i), ...)

Тогда GetDlgItem(hParent, BASE_ID + i) будет работать как положено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...