在 C++ 中将 HWND 转换为十六进制字符串

Convert HWND to Hex String in C++

在 C++ 中将 HWND 转换为十六进制字符串的最佳方法是什么,我的意思是还要使用 "0x" 前缀?

HWND hWnd = FindWindow(L"Notepad", L"Untitled - Notepad");
MessageBox(nullptr, LPCWSTR(hWnd), L"Hello World!", MB_ICONINFORMATION | MB_OK | MB_DEFBUTTON1);

但我希望它输出 0x00000000(假设记事本 windows 未打开),但它总是 returns 一个空字符串。

我也试过 this answer,但我最终返回 0000000000000000

任何人都可以帮助我进行转换?

要获取十六进制数的字符串表示形式,请将 0x 文字后跟句柄插入字符串流:

#include <Windows.h>
#include <sstream>
#include <iostream>

int main(){
    HWND hWnd = FindWindow(L"Notepad", L"Untitled - Notepad");
    std::stringstream ss;
    ss << "0x" << hWnd;
    std::cout << ss.str();
}

如果您需要在 MessageBox 中打印出结果,请使用宽字符串流:

#include <Windows.h>
#include <sstream>

int main(){
    HWND hWnd = FindWindow(L"Notepad", L"Untitled - Notepad");
    std::wstringstream wss;
    wss << "0x" << hWnd;
    MessageBox(NULL, wss.str().c_str(), L"Hello World!", MB_ICONINFORMATION | MB_OK | MB_DEFBUTTON1);
}

你所做的不是转换。您只需将 hWnd 转换为指向字符串的指针。它几乎总是不会指向有效的字符串,当您尝试将其打印为字符串时会产生未定义的行为。

为了正确地做到这一点,您应该将 hWnd 的位作为整数进行特征化,并将其作为十六进制打印到某个缓冲区,然后再显示在消息框中:

#include <sstream>
#include <cstdint>
#include <iomanip>

//.....

std::wstringstream ss;
ss << std::hex << L"0x" << std::setw(16) << std::setfill(L'0') << 
    *reinterpret_cast<uint64_t*>(&hWnd) << std::endl;
MessageBox(nullptr, ss.str().c_str(), L"Hello World!",
    MB_ICONINFORMATION | MB_OK | MB_DEFBUTTON1);

备注:

1) stringstream 是 C++ 风格的 sprintf。它是 str() 方法 returns std::string,因此要获得 C-style 指针,您应该对其调用 c_str

2) 我没有 Windows 检查 HWND 实际上是什么。所以请检查它的大小并使用适当的整数类型而不是 uint64_t。这很重要,因为如果你使用太宽的类型,你会得到垃圾甚至访问冲突。更好的方法是使用像 here.

中讨论的那样的整数类型模板

3) 您可能需要 std::wstringstream,因为您正在使用 wide-char 版本的 MessageBox。

4)装修。 ss << *reinterpret_cast<uint64_t*>(&hWnd) 只是将原始十六进制数字打印到 ss,因此要获得正确的格式,您应该 fine-tune 它,设置适当的填充和填充字符。例如,这将导致所有整数打印为带前导零的 16 位数字:

ss << std::setw(16) << std::setfill(L'0') ...

其中 setwsetfill 函数来自 iomanip header。另外,打印 0x 前缀是你的工作,而不是 stringstream 的。另请查看 std::showbase.