1

I'm coding an application, and want to print underlined text. What I'm doing wrong?

I'm using a "translated" code from C#, normally it works great in C# but does not in C++. After I fixed the errors, the code simply does not work. It shows some characters that normaly won't. This is what it prints instead (https://i.stack.imgur.com/qAPPQ.png)

Here's the code I used

auto DllHandler = GetStdHandle(-11);
unsigned int Mode;
GetConsoleMode(DllHandler,PDWORD(Mode));
Mode |= 4;
SetConsoleMode(DllHandler,DWORD(Mode));
cout << "\x1b[5mUnderlined \x1b[0mtext" << endl;

And here's the original (C#) code:

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GetStdHandle(int nStdHandle);
    [DllImport("kernel32.dll")]
    public static extern IntPtr GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
    [DllImport("kernel32.dll")]
    public static extern IntPtr SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
        var DllHandler = Kernel32.GetStdHandle(-11);
        uint Mode;
        GetConsoleMode(DllHandler,out Mode);
        Mode |= 4;
        SetConsoleMode(DllHandler, Mode);
        Console.Write("\x1b[5mUnderlined \x1b[0mText");

Thanks in advance.

Galik
  • 47,303
  • 4
  • 80
  • 117
HolyRandom
  • 79
  • 1
  • 11
  • That mostly depends on your terminal font settings and how you can control these. – πάντα ῥεῖ May 26 '19 at 11:38
  • 4
    Does Windows console really support ANSI escape sequences? It seems strange that it works in C#. The `Console` object might interpret these to do actual API calls to change console mode, I suppose. – Ruslan May 26 '19 at 11:40
  • 1
    use `\x1b[4m` instead `\x1b[5m`. https://stackoverflow.com/questions/5237666/adding-text-decorations-to-console-output/43078669#43078669 – RbMm May 26 '19 at 11:55
  • @Ruslan - yes, really support. dont check from which version, but support with [*ENABLE_VIRTUAL_TERMINAL_PROCESSING*](https://learn.microsoft.com/en-us/windows/console/setconsolemode) - look for [*Console Virtual Terminal Sequences*](https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) – RbMm May 26 '19 at 11:59
  • for text formating used *ESC [ m* code and *4 Underline Adds underline* - so need use `\x1b[4m` – RbMm May 26 '19 at 12:02
  • anyway this work only for win 10 and you not *Checking whether SetConsoleMode returns 0 and GetLastError returns STATUS_INVALID_PARAMETER is the current mechanism to determine when running on a down-level system. An application receiving STATUS_INVALID_PARAMETER with one of the newer console mode flags in the bit field* – RbMm May 26 '19 at 12:14
  • RbMm Oops that was my mistake, but 4m still won't fix it... I assume the problem is with PDWORD/DWORD, in .NET languages I use unsigned 16 bit integer and works just fine. – HolyRandom May 26 '19 at 12:33
  • your problem that you not check results of functions call. not check error code. what is your windows version also ? – RbMm May 26 '19 at 12:52
  • `GetConsoleMode(DllHandler,PDWORD(Mode));` of course also error. must be `GetConsoleMode(DllHandler, &Mode);` and `ULONG Mode` – RbMm May 26 '19 at 12:53

1 Answers1

1

Just like @RbMm said, use ULONG type can compile successfully and achieve the desired results.

But the real cause of the error is the error of pointer transmission. If you want to use unsigned int, the first step is to apply for pointers and allocate memory for pointers, and then force type conversion in GetConsoleMode.

    auto DllHandler = GetStdHandle(-11);
    unsigned int *Mode = new unsigned int;
    GetConsoleMode(DllHandler, PDWORD(Mode));
    *Mode = *Mode | 4;
    SetConsoleMode(DllHandler, DWORD(*Mode));
    cout << "\x1b[4mUnderlined \x1b[4mtext" << endl;

    delete Mode;
Strive Sun
  • 5,988
  • 1
  • 9
  • 26