GetClassName not returning expected output

1
2
3
4
5
	TCHAR _classbuf[255];
	HWND hwnd = FindWindowA(NULL, "Untitled - Notepad");
	cout << hwnd << endl;
	GetClassName(hwnd, _classbuf, 255);
	cout << *_classbuf;


I am playing around with the Windows APIs and am trying to extract the class name, in this example, of Windows Notepad. According to spyxx.exe, this string should be "Notepad".

However the output of _classbuf is only the number 78. What am I doing wrong?

EDIT: I feel dumb.. not sure if this is the "proper" way of doing it, but I discovered A solution

1
2
3
4
5
6
7
8
9
	TCHAR _classbuf[255];
	int p;
	string temp;
	HWND hwnd = FindWindowA(NULL, "Untitled - Notepad");
	p = GetClassName(hwnd, _classbuf, 255);
	for(int i=0; i<p; i++) {
		temp+=*(_classbuf+i);
	}
	cout << temp;
Last edited on
There are two issues here:

#1 This line (line 5 in your first code snippet)

cout << *_classbuf;

is saying o/p the first char in the buffer.

It should be

cout << _classbuf;

#2 The other part of the issue is that it looks like you're compiling for Unicode so that TCHAR evaluates to wchar_t, which cout sees as a short. This causes cout (for normal chars) to output the ASCII code for 'N', which is 78.

Either force everything to use the ANSI (a form of extended ASCII) entrypoints, or use the TCHAR mechanisms consistently all the way through, including using wcout for the Unicode build rather than cout.

It you had compiled for ANSI, the o/p of your line 5 would have been 'N'

This line

temp+=*(_classbuf+i);

"works" as a) string has an overload of operator+ which takes a char on the RHS, and b) the values of the Unicode chars corresponding to the ASCII char set all have the same numeric value as the ASCII char, but stored in two bytes rather than just the one; the extra byte being zero. So when operator+= chops the wchar_t in half to add a char to the end of the string, all that is lost is the zero byte. (Actually, it also relies on Windows using the right endian form of 16-bit Unicode.)

Note that I get a warning for this particular line; if you do not, you should crank up your compiler warning level.

warning C4244: 'argument' : conversion from 'TCHAR' to 'char', possible loss of data


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// With TCHAR
#include <windows.h>
#include <tchar.h>
#include <iostream>
using namespace std;

int main()
{
	TCHAR _classbuf[255] = _T("");
	HWND hwnd = FindWindow(NULL, _T("Untitled - Notepad"));
	GetClassName(hwnd, _classbuf, 255);
#ifdef _UNICODE
	wcout << hwnd << endl;
	wcout << _classbuf << endl;
#else
	cout << hwnd << endl;
	cout << _classbuf << endl;
#endif
	return 0;
}


(If you using cout/wcout a lot, it's prob better to use

#ifdef _UNICODE
#define TCOUT wcout
#else
#define TCOUT cout
#endif

and then use TCOUT in the code, rather than have loads of #ifdef-ing.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Using ANSI
#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
	char _classbuf[255] = "";
	HWND hwnd = FindWindowA(NULL, "Untitled - Notepad");
	GetClassNameA(hwnd, _classbuf, 255);
	cout << hwnd << endl;
	cout << _classbuf << << endl;
	return 0;
}


Or you could make everything Unicode instead (wchar_t _classbuf[255] = L"";, FindWindowW, etc)

Andy
Last edited on
Awesome!! Thank you so much for the clarification :)

I still have a lot of learning to do.
Topic archived. No new replies allowed.