在C ++中将HWND转换为Hex String

时间:2017-07-13 04:04:52

标签: c++ string hex hwnd

在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

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

你在做什么不是转换。您只需将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 << *reinterpret_cast<uint64_t*>(&hWnd)只是将原始十六进制数字打印到ss,因此要获得正确的格式,您应该对其进行微调,设置正确的填充和填充字符。例如,这将导致所有整数打印为带有前导零的16位数字:

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

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

答案 2 :(得分:0)

一个对整数有效的hackish解决方案是将类型转换为(void *) i.E指向void类型的指针。在当前的Microsoft编译器上,这很好地打印前缀为0x,因为它被解释为“地址”。

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

这个技巧与Microsoft Visual C ++编译器开箱即用。 Gcc和clang可能会发出一个警告,如果真的有必要可以被禁止(可能是-Wint-to-pointer-cast)。