Search code examples
c++winapiconsoleconsole-application

ReadConsoleOutputAttribute function usage in c++


I need to get background color by known coord in c++. I tried to use ReadConsoleOutputAttribute from windows.h, but i didn't work. Here is my code:

HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD count;
COORD cursor = { this->X, this->Y };
LPWORD *lpAttr = new LPWORD;
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(console, &info);

ReadConsoleOutputAttribute(console, *lpAttr, 1, cursor, &count);

What's wrong here and what's the way to fix it? Do I suppose to get background color from lpAttr or what?


Solution

  • Color attributes are specified by TWO hex digits -- the first corresponds to the background; the second the foreground. Each digit can be any of the following values:

    0 = Black       8 = Gray
    1 = Blue        9 = Light Blue
    2 = Green       A = Light Green
    3 = Aqua        B = Light Aqua
    4 = Red         C = Light Red
    5 = Purple      D = Light Purple
    6 = Yellow      E = Light Yellow
    7 = White       F = Bright White
    

    We only need to extract the first digit of the hexadecimal result to know the background color of the current coordinate.This is my test code. I modified the mouse coordinate points to simplify the test.

    #include <Windows.h>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        //color set test
        system("color F0");
        std::cout << "Hello World!\n" << endl;
    
        HANDLE Console = GetStdHandle(STD_OUTPUT_HANDLE);
        if (!Console)
            return 0;
    
        CONSOLE_SCREEN_BUFFER_INFO buf;
        GetConsoleScreenBufferInfo(Console, &buf);
    
        WORD Attr;
        DWORD Count;
        COORD pos = buf.dwCursorPosition;
        ReadConsoleOutputAttribute(Console, &Attr, 1, pos, &Count);
    
        //hexadecimal out
        cout  << hex << Attr << endl;
        
        if (Attr)
        {   //extract the first digit of the hexadecimal result
            int color = Attr / 16;
            switch (color)
            {
               case 0:cout  << " background color is Black. "     << endl; break;
               case 1:cout  << " background color is Blue. "      << endl;break;
               case 2:cout  << " background color is Green . "    << endl; break;
               case 3:cout  << " background color is Aqua. "      << endl; break;
               case 4:cout  << " background color is Red. "       << endl; break;
               case 5:cout  << " background color is Purple . "   << endl; break;
               case 6:cout  << " background color is Yellow. "    << endl; break;
               case 7:cout  << " background color is White. "     << endl; break;
               case 8:cout  << " background color is Gray . "     << endl; break;
               case 9:cout  << " background color is Light Blue." << endl; break;
               case 10:cout << " background color is Light Green." << endl; break;      //A
               case 11:cout << " background color is Light Aqua ." << endl; break;      //B
               case 12:cout << " background color is Light Red . " << endl; break;      //C
               case 13:cout << " background color is Light Purple . " << endl; break;   //D
               case 14:cout << " background color is Light Yellow . " << endl; break;   //E
               case 15:cout << " background color is Bright White . " << endl; break;   //F
               default:
                   cout << " error color " << endl;
                   break;
            }
        }
    
        return 0;
    }