Reputation: 19
I was having trouble getting a substring using
strstr(a,b);
To check if the "FiveM" name appears in the title bar of the window, because usually in this game the title bar also contains updates and so on
so i was googling and i found the GetWindowText
function.
I have ran this code:
HWND foreground = GetForegroundWindow();
char window_title[7];
if (foreground)
{
GetWindowText(foreground, (LPWSTR)window_title, 7);
}
auto output = strstr(window_title, "FiveM");
printf("%d", output);
and got not output, everything was 0, but when i used the function GetWindowTextA()
everything worked fine, so i googled some more about this getwindow function and i found this link and i saw this
#define GetWindowText GetWindowTextA
in a non-Unicode build, GetWindowText and GetWindowTextA are the same thing. [...]
And my build is unicode so that was the problem i had to add that A at the end by why, also why when i get the window text using GetWindowTextW
aka GetWindowText
one char takes more space, i guess it's because of how i cast it right
char window_title[7];
if (foreground)
{
GetWindowTextW(foreground, (LPWSTR)window_title, 7);
}
i'm also confused about why did the strstr()
function rises an memory violation
when printing the output value to the console while just simply reading it doesnt raises any memoy violation
Upvotes: 0
Views: 1049
Reputation: 2573
GetWindowTextW provides output as a unicode widestring. Note you will potentially overrun the end of the array since the nMaxCount
parameter is number of characters, not number of bytes. That would explain why you see a memory violation, because UTF-16 wide-chars contain at least 2 bytes; you are effectively telling GetWindowTextW that the buffer can house 14 bytes, when it is actually only 7 bytes long.
You need to be passing it a wchar_t
array and then either working entirely in widestring (e.g. wcslen
) or converting from widestring to character-string as indicated here:
C++ Convert string (or char*) to wstring (or wchar_t*)
You could use the MSVC ATL methods A2W
and W2A
although I would recommend using std::string
and std::wstring
whenever possible.
When you use character-string methods on widestrings, they misbehave because widestrings often contain zeroes as the upper byte of the encoding, which the character-string methods interpret as a null terminator (e.g. in a hex memory view you may see something like 48 00 45 00 4C 00 4C 00 4F 00 00 00
- which a character string method would interpret as "H")
If you look at the declaration for GetWindowText
you will find something like this:
#ifdef UNICODE
#define GetWindowText GetWindowTextW
#else
#define GetWindowText GetWindowTextA
#endif
This explains why in a non-unicode build GetWindowText is the same as GetWindowTextA
Another possibilty would be to use GetWindowTextA
and do the whole thing with character strings, but that option may not be open to you.
Upvotes: 0
Reputation: 25408
You are very mixed up in your handling of Unicode (aka wide) and ANSI (aka narrow) strings. You should pick one variant and stick to it. In this case, since you are building for Unicode, wide strings are the natural choice.
So, the code should look a bit like this:
HWND foreground = GetForegroundWindow();
if (foreground)
{
WCHAR window_title[256];
GetWindowText(foreground, window_title, _countof (window_title));
const WCHAR *output = wcsstr (window_title, L"FiveM");
...
}
Some things to note (in no particular order):
The window title is definitely going to be longer than 6 characters, so allow adequate space for it when retrieving it.
To avoid 'magic numbers' in your code, use _countof
when appropriate.
The return type of strstr
(or the wide equivalent, wcsstr
) is a char *
(or WCHAR *
), not an int
, so handle it accordingly.
Upvotes: 0