I can't speak for VS2008, but most pre-C++11 follow the C++11 rule of &str[0] + i == str.data() + i
, so &str[0]
works and doesn't require any casts1, which is a much safer route than subverting the type system and the standard. Just be careful because you aren't permitted to overwrite the null terminator after the string, even with another null terminator. If you aren't able to guarantee this for VS2008, then a std::vector<wchar_t>
would be the preferred solution.
However, you have another problem. reserve
doesn't stop it being undefined behaviour to access str
out of bounds. Bounds are based on size()
, not capacity()
. You need to change reserve
to resize
.
Even then, you have another problem. GetWindowTextLength
doesn't include the null terminator. You must use nLn + 1
in the code following that call.
With the changes made, this will work with any conforming C++11 implementation, including some pre-C++11 implementations, and ignoring error checking:
int nLnWithNul = GetWindowTextLength(hWnd);
std::wstring str(nLnWithNul, '\0'); // bit of a shorthand for the resize call
int nCopiedLn = GetWindowText(hWnd, &str[0], nLnWithNul);
str.resize(nCopiedLn);
The last resize
call handles the copied title being shorter than nLnWithNul
. For example, if the title shrinks since GetWindowTextLength
was called. After resizing, the string will contain only the copied text, not including any NUL characters after it.
1: See the answer to my previous question.