3

What is the best way to convert HWND to Hex String in C++, I mean also with a "0x" prefix?

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

But I expect this to output 0x00000000 (assuming Notepad windows is not open) , but it always returns an empty string.

I also tried this answer, but I ended up with returning 0000000000000000.

Anyone can help me on that conversion?

Blueeyes789
  • 543
  • 6
  • 18

3 Answers3

4

This:

HWND hwnd = FindWindowW(NULL, L"Untitled - Notepad");
std::wostringstream ss;
ss << std::hex << hwnd;
std::wstring strTitle = ss.str();
MessageBoxW(NULL, L"Caption message", strTitle.c_str(), MB_OK);
IInspectable
  • 46,945
  • 8
  • 85
  • 181
selbie
  • 100,020
  • 15
  • 103
  • 173
2

To get a string representation of a hexadecimal number insert the 0x literal followed by a handle into a stringstream:

#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();
}

If you need to print out the result in a MessageBox use wide stringstream:

#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);
}
Ron
  • 14,674
  • 4
  • 34
  • 47
  • Above suggestion gives me `0x0000000000000000` when Notepad not open and `0x0000000000xxxxxx` when it's open, But I expect it to return `0x00000000` and `0x00xxxxxx`. :-) – Blueeyes789 Jul 13 '17 at 05:39
1

What you are doing is not conversion. You just cast hWnd to a pointer to string. Almost always it will not point to a valid string, producing an undefined behavior when you try to print it as a string.

To do it properly, you should trait hWnd's bit's as integer and print it to some buffer as hex before showing in the message box:

#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);

Notes:

1) stringstream is a C++-style sprintf. It's str() method returns std::string, so to get a C-style pointer you should call c_str on it.

2) I have no Windows to check what is HWND actually. So please check it's size and use appropriate integer type instead of uint64_t. It's important, as if you use a too wide type, you'll get garbage or even access violation. A better approach is to use an integer type template like one discussed here.

3) Probably, you need std::wstringstream as you are using wide-char version of MessageBox.

4) Decoration. ss << *reinterpret_cast<uint64_t*>(&hWnd) just prints raw hex digits to ss, so to get the right format, you should fine-tune it, setting proper padding and filling character. For example, this will cause all integers to be printed as 16-digit numbers with leading zeros:

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

where setw and setfill functions are from iomanip header. Also, printing 0x prefix is your job, not stringstream's. Also take a look at std::showbase.

Sergey
  • 7,985
  • 4
  • 48
  • 80
  • I still getting `0x0`, This seems conversion very hard in C++ those compared to AutoIt3. in it, it is really simple and only need to do is use `String(YourHWND)`. As it is also developed using C++, there should be something different to do this to return `0x00000000`. I can't find out what's it. – Blueeyes789 Jul 13 '17 at 04:44
  • I will try again by changing `uint64_t` to another type..... :-}, And now I near to expected results when Notepad open. It outputs a six numbered hex, but I expect to output a eight numbered hex like `0x00000000`. – Blueeyes789 Jul 13 '17 at 04:46
  • @Blueeyes789 I updated my answer. Also checked it on Windows, it works. – Sergey Jul 13 '17 at 05:05
  • This may work, but now I can't compile it and C++ gives two `E0135` errors telling `namespace "std" has no member "setw"` and `namespace "std" has no member "setfill"`. I only included header files that you shown here. – Blueeyes789 Jul 13 '17 at 05:14
  • No! Thanks, I forget it, I will include it right now. – Blueeyes789 Jul 13 '17 at 05:17
  • `setw(8)` worked for me. :-) Then what can I do this to only return capital letters? any regular expression is needed to do this? – Blueeyes789 Jul 13 '17 at 05:38
  • 1
    @Blueeyes789 If you have a problem and you want to solve it with regular expressions, then you have two problems :) It can be done much easier: http://en.cppreference.com/w/cpp/io/manip/uppercase – Sergey Jul 13 '17 at 05:48
  • Thanks again for nice help! :-) – Blueeyes789 Jul 13 '17 at 06:31