【问题标题】:Is it normal for an hwnd to have its high bit set?hwnd 设置其高位是否正常?
【发布时间】:2017-03-25 04:16:27
【问题描述】:

我将我的 HWND 传递给一个子流程,以便它可以向我发送有关其进度的消息。有时我从未收到来自子流程的任何消息。 在调查时,我发现我传递给子进程的 GetSafeHwnd() 似乎返回了我不期望的值。

例如: 0xffffffffa5400382

基于此,我可能会推断出我没有正确地将该值与 int64/string 正确转换。我可以解决这个问题。但我觉得奇怪的是,这个 hwnd 看起来不正确?

是否存在 HWND 可以设置其高位的情况?这是一个普通的窗口,还是 hwnd 有什么特别之处?

我在 C++ 中,这是一个基于 CDialog 的应用程序窗口。

【问题讨论】:

  • 进程是32位还是64位?句柄可以设置任何位,高位没什么特别的。
  • 两个进程都是 64 位的。

标签: c++ mfc hwnd cdialog


【解决方案1】:

您看到的结果来自sign extension 的句柄值到一个 64 位整数。实际的句柄值是0xa5400382,因为handle values are always in the 32-bit range,即使进程是64位的!

因此,您应该将 HWND 转换为 std::uint32_t 并将其转换为字符串(或相反)。

将 HWND 转换为 wstring:

HWND hwnd = GetSafeHwnd();
std::uint32_t handleValue = reinterpret_cast<std::uint32_t>( hwnd );
std::wstring handleValueStr = std::to_wstring( handleValue );

将 wstring 转换为 HWND:

try
{
    std::uint32_t handleValue = std::stoul( someString );
    HWND handle = reinterpret_cast<HWND>( handleValue );
}
catch( std::exception& e )
{
    // Handle string conversion error
}

try/catch 块是必需的,因为如果转换失败,std::stoul() 可能会抛出异常。

【讨论】:

  • 有趣的@zett42。我无法在我的机器上重现这个,所以我求助于日志记录。记录 HWND 的代码是这样的:我没有看到句柄值总是 32 位的,并且在这方面它们可以安全地截断。我将关注下一个实例,我们的代码处理一个看起来相当大的窗口句柄。
  • 感谢您的 cmets @zett42。一旦我了解我看到的更好的问题,我会将其标记为答案。不幸的是,我无法在这些 cmets (Stupid Edge) 中输入回车。我正在记录的代码是这样的 uint64 nOwnderHwnd = (uint64)GetSafeHwnd(); Log("%I64x", nOwnerHwnd);我希望那条线不会进行 32 位签名进位?但我看到的记录是这样的:“ffffffffe22400c8”。如果我将其更改为“%I64u”,我会得到这个“18446744073208594632”。
  • @Leo 这很有趣,因为 printf() 正确地将 uint64_t 输出为 e22400c8 并带有“%I64x”或“%llx”。你的 log 函数输出的十进制值好像完全无法解释,那么 log 函数可能有 bug?
  • @Leo 有趣的是,我可以使用以下代码重现它:uint64_t x = 0xe22400c8; printf("%llx\n", x); void* p = (void*) x; x = (uint64_t) p; printf("%llx\n", x);。第一个 printf 输出e22400c8,第二个输出ffffffffe22400c8。所以看起来问题出在语言上。指针在转换为 64 位整数时始终进行符号扩展,即使该整数是无符号的。
  • @Leo 我为此创建了一个new question,因为它与句柄无关(句柄只是指针的类型定义)。从到目前为止的 cmets 可以得出结论,这是编译器的正常(特定于实现)行为。
猜你喜欢
  • 1970-01-01
  • 2021-03-31
  • 2010-12-16
  • 2015-04-17
  • 2021-10-28
  • 2023-03-21
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多