GetConsoleOriginalTitle() - Returning Blank Chars

I want to get the window handle of a game console application by name.
I have tried researching and found on MSDN if I want to get the title of the console application I can use the GetConsoleOriginalTitle function but when I store the return value into a char array and try to print it out it only shows blank characters.

Can anyone tell me what I’m doing wrong? How can I print out the console application title name?

1
2
3
4
5
6
7
8
9
10
11
12
HWND hWnd;
char title [100];

GetConsoleOriginalTitle(title, sizeof(title));

for(int i=0; i<20; i++)
{
cout << title[i];
}

hWindow = FindWindow(NULL, title);
Do you get any warnings when you compile it?

The windows interface has this ASCII/UNICODE duality. If you choose the wrong type for your buffer, trying to print the result will result in nothing.

The way you deal with this is by using TSTR in place of char whenever you need a character buffer of some sort.

TSTR title [100];
@Salem C

No there is no errors. My project is set to multibyte character set.

I cannot use a string for the title array as the GetConsoleOriginalTitle function parameters take a LPSTR?


not sure how to quote you on here
Last edited on
To get the handle of the window used by the console, use GetConsoleWindow()
https://docs.microsoft.com/en-us/windows/console/getconsolewindow

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <windows.h>

static_assert( _WIN32_WINNT >= 0x0500 ) ; // requires windows 2000 or later

int main()
{
	// https://docs.microsoft.com/en-us/windows/console/getconsolewindow
	const auto hwnd_console = ::GetConsoleWindow() ;

	std::cout << "window of the console of this process: " << hwnd_console << '\n' ;
}
But wondering is there a way from doing it with my code? I have two issues.

- I cannot get the char array called title to print. It just prints blank.

- The other issue is with GetConsoleOriginalTitle not getting the game console application name instead it is getting the Visual Studio console which is not the one I want.
Last edited on
> I cannot get the char array called title to print. It just prints blank.

Try this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <windows.h>
#include <cassert>

static_assert( _WIN32_WINNT >= 0x0500 ) ; // requires windows 2000 or later

int main()
{
	char original_title[1024] {} ;
	assert(::GetConsoleOriginalTitleA(original_title, sizeof(original_title) ) > 0 ) ;
	std::cout << "original_title: " << original_title << '\n' ;

	wchar_t woriginal_title[1024] {} ;
	assert( ::GetConsoleOriginalTitleW(woriginal_title, sizeof(woriginal_title) / sizeof(wchar_t) ) > 0 )  ;
	std::wcout << L"woriginal_title: " << woriginal_title << L'\n' ;

	std::cout << "\npress enter to exit... " && std::cin.get() ;
}



> instead it is getting the Visual Studio console which is not the one I want.

Run the program from outside the Visual Studio IDE.
Here is my full code below maybe it will help better understand what issues I am experiencing. I want to know why it is not doing what I want:

- Can’t seem to get char array consoleTitle to output the characters that the function GetConsoleOriginalTitle stored.

- Also can’t print char array buffer1 that got stored from GetWindowText function.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream> 
#include <Windows.h>
using namespace std;


int main()
{

   HWND hWindow;
   char consoleTitle[100] = {};

   GetConsoleOriginalTitle(consoleTitle, sizeof(consoleTitle));

   for(int i=0; i<20; i++)
        {
            cout << consoleTitle[i];
        }

   hWindow = FindWindow(NULL, consoleTitle);

   if (hWindow == NULL)
       {
            cout << “Couldn’t Find Window Handle” << endl;
       }
 
   else
       {
            char buffer1[100];
            GetWindowText(hWindow, buffer1, sizeof(buffer1));
            cout << buffer1 << endl;
            cout << “Found Window Handle” << endl;
       }
  
 system(“pause”);

}
Last edited on
Try running this (from outside the Visual Studio IDE)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream> 
#include <Windows.h>

int main()
{
    char consoleTitle[1024] = {};

    GetConsoleOriginalTitleA( consoleTitle, sizeof(consoleTitle) ); // *** GetConsoleOriginalTitleA

    std::cout << "consoleTitle == " << consoleTitle << '\n' ;

    const HWND hWindow = FindWindowA( nullptr, consoleTitle ); // *** FindWindowA

    if( hWindow == nullptr )
    {
        std::cout << "could not find window handle\n" ;
    }

    else
    {
        char buffer1[1024] {} ;
        GetWindowTextA( hWindow, buffer1, sizeof(buffer1) ); // *** GetWindowTextA
        std::cout << "Found Window Handle " << hWindow << '\n'
                  << "Window text == " << buffer1 << '\n' ;
    }

    std::cin.get() ;
}
The secret life of GetWindowText - The Old New Thing
https://devblogs.microsoft.com/oldnewthing/20030821-00/?p=42833
@copypasta, depending on your compiler you may be creating a Unicode version of your program. A lot of the WinAPI functions have three(!) different versions available. For example GetConsoleOriginalTitle() is actually a macro, an alias, that can call either GetConsoleOriginalTitleA() (ANSI, retrieves a char array) or GetConsoleOriginalTitleW(unicode(), retrieves a wchar_t array). Which version is actually used depends on the definition of the UNICODE preprocessor constant. The Visual Studio IDE usually sets this, modern versions of VS have it defaulted to the Unicode character set.

Not all WinAPI functions have different ANSI/Unicode versions.

I don't know what your compiler is, if it is Visual Studio that defaults to Unicode. ANSI is Win9X.

If there is ANSI and Unicode versions, prefer explicitly calling whatever version is appropriate for the character set you want to support.

std::cout supports char arrays, so call the A version. That is what JLBorges did, he explicitly called the A version of WinAPI functions.
Last edited on
@ JLBorges (13405)

I have tried running the binary instead of inside visual studio and the text shows up in console. But why when running it inside visual studio I get blank text? I have been trying to figure this out and don’t know how to make the text not blank.

@ George P (4508)

My project character set is multibyte.
> why when running it inside visual studio I get blank text?

When running from inside Visual Studio, the original title of the console window would be ...VsDebugConsole.exe; the title is changed to the actual title once the program starts running and FindWindow won't find the window with the original title.


> I have been trying to figure this out and don’t know how to make the text not blank.

To run from inside Visual Studio, instead of retrieving the original title of the console window,
retrieve its current title.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream> 
#include <Windows.h>

int main()
{
    char consoleTitle[1024] = {};

    // GetConsoleOriginalTitleA( consoleTitle, sizeof(consoleTitle) ); // *** GetConsoleOriginalTitleA
    GetConsoleTitleA( consoleTitle, sizeof( consoleTitle ) ); // *** GetConsoleTitleA

    std::cout << "consoleTitle == " << consoleTitle << '\n' ;

    const HWND hWindow = FindWindowA( nullptr, consoleTitle ); // *** FindWindowA

    if( hWindow == nullptr )
    {
        std::cout << "could not find window handle\n" ;
    }

    else
    {
        char buffer1[1024] {} ;
        GetWindowTextA( hWindow, buffer1, sizeof(buffer1) ); // *** GetWindowTextA
        std::cout << "Found Window Handle " << hWindow << '\n'
                  << "Window text == " << buffer1 << '\n' ;
    }

    std::cin.get() ;
}
@ JLBorges

Hmmm why does GetConsoleTitleA works and can get the HWND from FindWindow.
But when using GetConsoleOriginalTitleA and calling FindWindow the HWND returns null?


Thank you for helping appreciate it
Last edited on
> why does GetConsoleTitleA works and can get the HWND from FindWindow.
> But when using GetConsoleOriginalTitleA and calling FindWindow the HWND returns null?

FindWindow looks for a top level window with the specified title. So it requires the current window title (from GetConsoleTitleA), not an old title (from GetConsoleOriginalTitleA) which may have been replaced.
copypasta wrote:
My project character set is multibyte.

Why? Multi-byte is essentially ANSI characters. Explicitly using the ANSI/Multi-byte WinAPI function does work regardless of what the character option is set in the project's properties, the code JLBorges showed compiles and runs fine with the default Unicode character set.

I always use the default Unicode character set and never have a problem because I explicitly use the A or W version of WinAPI functions when dealing with text in my WinAPI code.

The programs could call the W versions of the WinAPI function, use wchar_t C strings and output to std::wcout.

wchar_t has a Windows data type alias handy, WCHAR.

Unicode is 2 bytes in size and uses UTF-16, multi-byte can be one or two bytes depending on the character and the locale.

Multi-byte is not recommended for new projects, MBCS was an MS invention of extending ANSI that attempted to provide support for non-European characters before the Unicode standard was adopted.

Always explicitly call the A/W version of any WinAPI function when available. Not every WinAPI function deals with text so no need to have two different versions.
When using Windows functions, always but always check the return for success/failure.

GetConsoleOriginalTitle() returns:

If the function succeeds, the return value is the length of the string copied to the buffer, in characters.

If the buffer is not large enough to store the title, the return value is zero and GetLastError returns ERROR_SUCCESS.

If the function fails, the return value is zero and GetLastError returns the error code.


If the return value is 0 then the function has failed. You then need to call GetLastError() to obtain the error code relating to the failure and then display it.

In VS, if you then use Tools/Error Lookup you can get a description for the error code.

If the return value is > 0, then this in the number of characters copied to the buffer.
One thing to note if using wchar_t/WCHAR, WinAPI functions that fill a C string buffer have a potential buffer overrun issue. ANSI/MB is 1 byte in size, Unicode is 2. You need to divide the size of the C string by the number of bytes in the character set.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream> 
#include <Windows.h>

int main()
{
   // I dislike MAGIC numbers
   const int SIZE { 1024 };

   WCHAR consoleTitle[SIZE] {};

   GetConsoleTitleW(consoleTitle, sizeof(consoleTitle)/sizeof(WCHAR));

   std::wcout << "consoleTitle == " << consoleTitle << '\n';

   const HWND hWindow = FindWindowW(nullptr, consoleTitle);

   if (hWindow == nullptr)
   {
      std::wcout << "could not find window handle\n";
   }

   else
   {
      WCHAR buffer[SIZE] {};
      GetWindowTextW(hWindow, buffer, sizeof(buffer)/sizeof(WCHAR));
      std::wcout << "Found Window Handle " << hWindow << '\n'
                 << "Window text == " << buffer << '\n';
   }
}
From https://www.programmerall.com/article/1575496459/ ("Multibyte and Unicode")

(5) Unicode and multi-byte choice

1. Unicode program environment has strong adaptability, and there will be no garbled problems

2. Unicode programs run faster than multi-byte programs. Reason: Windows uses Unicode encoding internally, and multi-byte functions will transcode the parameters and pass them to the Unicode function

3. Multi-byte control background can be used, GUI program is best to use Unicode

Stick with the Visual Studio default of Unicode character set, and explicitly use either the narrow character (A) or wide character (W) version for your text processing.
Topic archived. No new replies allowed.