【问题标题】:Convert HWND to Hex String in C++在 C++ 中将 HWND 转换为十六进制字符串
【发布时间】:2017-12-17 16:20:09
【问题描述】:

在 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(假设记事本窗口未打开),但它总是返回一个空字符串。

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

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

【问题讨论】:

    标签: c++ string hex hwnd


    【解决方案1】:

    要获得十六进制数字的字符串表示,请将 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);
    }
    

    【讨论】:

    • 以上建议在记事本未打开时给我0x0000000000000000,在它打开时给我0x0000000000xxxxxx,但我希望它返回0x000000000x00xxxxxx。 :-)
    【解决方案2】:

    您所做的不是转换。您只需将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() 方法返回std::string,所以要获得一个C 风格的指针,你应该在它上面调用c_str

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

    3) 您可能需要std::wstringstream,因为您使用的是宽字符版本的 MessageBox。

    4) 装饰。 ss &lt;&lt; *reinterpret_cast&lt;uint64_t*&gt;(&amp;hWnd) 只是将原始十六进制数字打印到ss,因此要获得正确的格式,您应该对其进行微调,设置适当的填充和填充字符。例如,这将导致所有整数都打印为带有前导零的 16 位数字:

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

    其中setwsetfill 函数来自iomanip 标头。此外,打印0x 前缀是您的工作,而不是stringstream。也可以看看std::showbase

    【讨论】:

    • 我仍然收到0x0,与 AutoIt3 相比,这在 C++ 中似乎很难转换。在里面,真的很简单,只需要使用String(YourHWND)。由于它也是使用 C++ 开发的,因此应该有一些不同的方法来返回 0x00000000。我不知道它是什么。
    • 我将通过将uint64_t 更改为另一种类型再试一次..... :-},现在我在记事本打开时接近预期结果。它输出一个六号十六进制,但我希望输出一个八号十六进制,如0x00000000
    • @Blueeyes789 我更新了我的答案。还在 Windows 上检查过,它可以工作。
    • 这可能有效,但现在我无法编译它,C++ 给出了两个E0135 错误,告诉namespace "std" has no member "setw"namespace "std" has no member "setfill"。我只包含了您在此处显示的头文件。
    • @Blueeyes789 如果你有问题想用正则表达式解决,那么你有两个问题:) 可以更简单:en.cppreference.com/w/cpp/io/manip/uppercase
    猜你喜欢
    • 2018-01-31
    • 2022-07-22
    • 2016-03-06
    • 2014-06-09
    • 2018-06-06
    • 1970-01-01
    • 2018-01-03
    • 2014-10-27
    • 2021-04-28
    相关资源
    最近更新 更多