Search code examples
c++winapicstringout

Working with WinAPI functions which use C style strings as OUT parameters


Given a WinAPI function which returns it's result via a C style string OUT parameter e.g.:

int WINAPI GetWindowTextW(
   _In_   HWND hWnd,
   _Out_  LPTSTR lpString,
   _In_   int nMaxCount
);

Is there a better way of using the function than what I'm doing below?

HWND handle; // Assume this is initialised to contain a real window handle
std::wstring title;
wchar_t buffer[512];
GetWindowTextW(handle, buffer, sizeof(buffer));
title = buffer;

The above code works, but I have the following issues with it:

  1. The buffer size is completely arbitrary since I have no way to know the length of the string that the function might return. This "feels" wrong to me - I have always tried to avoid magic numbers in my code.

  2. If the function returns a string which is larger than the buffer, it will get truncated - this is bad!

  3. Whenever the function returns a string which is smaller than the buffer, I will be wasting memory. This is not as bad as (2), but I'm not thrilled about the idea of setting aside large chunks of memory (e.g. 1024 bytes in my example above) for something that might only need a few bytes in practice.

Are there any other alternatives?


Solution

  • Call the function multiple times with temporary buffers of different sizes. Begin with a buffer of, say, 8. Double the buffer size and call it again. Repeat until it returns the same count as the last time. Then you can allocate the exact size buffer and copy what you've got there. There are a number of Win32 functions with similar behavior.

    You may use GetWindowTextLength(), but it probably won't help much if there are race conditions (you may end up with a truncated text because of them).