WINAPI C ++ GetDlgItem不返回有效的句柄

时间:2018-11-08 01:22:35

标签: c++ winapi 64-bit

我正在尝试通过其ID获取子Window的句柄,但要执行此操作,我必须对ID进行两次强制转换,否则它将无法正常工作。还有其他方法吗?我想念什么?

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 :(得分:5)

第一种方法在正常情况下可以正常工作,这是您应该使用的方法:

GetDlgItem(hParent, BASE_ID + i)

代码失败的原因是因为BASE_ID + i(又名101)与您传递给CreateWindow()的ID不同。

在调用CreateWindow()时,您首先要按自身类型转换BASE_ID常量,然后将i添加到该指针,从而调用指针算术,最终产生另一个ID(104)在32位上,在64位上为108),超出了您的预期(101)。

这样,GetDlgItem(hParent, BASE_ID + i)无法找到匹配的ID,而GetDlgItem(hParent, (int)((HMENU)BASE_ID + i))成功了,因为它使用了与调用CreateWindow()时使用的相同的转换逻辑,从而找到了匹配的ID。 / p>

Casting has a higher precedence than addition,因此(HMENU)BASE_ID + i被编译器解释为((HMENU)BASE_ID) + i。您需要修正括号,以便首先执行加法运算,然后强制转换结果:

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

然后GetDlgItem(hParent, BASE_ID + i)将按预期工作。