Hide scrollbars in Console without flickering

2019-07-21 03:13发布

问题:

I write in a console window multiple times in a second.

I figured out how to remove the scrollbars:

Console.BufferWidth = Console.WindowWidth = 35;
Console.BufferHeight = Console.WindowHeight;

So far it's fine. But when I want to write in the last column of a line, it adds a new line! It's logical, but how to avoid this?

I tried to resize the console:

Console.BufferWidth++;
Console.BufferHeight++;

// Write to the last column of a line

Console.BufferWidth--;
Console.BufferHeight--;

But this flickers because these lines will get executed multiple times in a second!

Any ideas or will I have to live with the scrollbars?

回答1:

Try with Console.SetBufferSize(width, height); I think it will help.



回答2:

I managed it with drawing with a native method.

#region Native methods

[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern SafeFileHandle CreateFile(
    string fileName,
    [MarshalAs(UnmanagedType.U4)] uint fileAccess,
    [MarshalAs(UnmanagedType.U4)] uint fileShare,
    IntPtr securityAttributes,
    [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
    [MarshalAs(UnmanagedType.U4)] int flags,
    IntPtr template);

[StructLayout(LayoutKind.Sequential)]
public struct Coord
{
    public short X;
    public short Y;

    public Coord(short X, short Y)
    {
        this.X = X;
        this.Y = Y;
    }
};

[DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteConsoleOutputCharacter(
    SafeFileHandle hConsoleOutput,
    string lpCharacter,
    int nLength,
    Coord dwWriteCoord,
    ref int lpumberOfCharsWritten);

#endregion


public static void Draw(int x, int y, char renderingChar)
{
    // The handle to the output buffer of the console
    SafeFileHandle consoleHandle = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);

    // Draw with this native method because this method does NOT move the cursor.
    int n = 0;
    WriteConsoleOutputCharacter(consoleHandle, renderingChar.ToString(), 1, new Coord((short)x, (short)y), ref n);
}

WriteConsoleOutputCharacter does not move the cursor. So even while drawing in the last column of the last row, the cursor does not jump into the next line (outside of window size) and break the view.



回答3:

The problem is not that the cursor goes to the next line directly. What it really does is, it goes one character to the right and because the buffer ends it goes to the next line.

So I tried to do something like Console.WriteLine("C\r"); To set the cursor back but it still flickered

Than I thought about using some sneaky trick and using an Arabic Right to Left Marker but didn't worked.

So the best way i could figured out was to move the character to the bottom right with the Console.MoveBufferArea method because this doesn't set the cursor to the next right position and avoids the new line.