在控制台中隐藏滚动条而不闪烁
本文关键字:闪烁 滚动条 隐藏 控制台 | 更新日期: 2023-09-27 18:36:40
我每秒在控制台窗口中写入多次。
我想出了如何删除滚动条:
Console.BufferWidth = Console.WindowWidth = 35;
Console.BufferHeight = Console.WindowHeight;
但是当我想写到一行的最后一列时,它会添加一个新行。这是合乎逻辑的,但如何避免这种情况?
我尝试调整控制台的大小:
Console.BufferWidth++;
Console.BufferHeight++;
// Write to the last column of a line
Console.BufferWidth--;
Console.BufferHeight--;
但这会闪烁,因为这些行每秒会执行多次。
有什么想法吗?
尝试使用 Console.SetBufferSize(width, height);我认为这会有所帮助。
我使用本机方法绘制了它。
[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);
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 不会移动光标。因此,即使在最后一行的最后一列中绘制时,光标也不会跳转到下一行(超出窗口大小)并破坏视图。
问题不在于光标直接转到下一行。它真正做的是,它向右移动一个字符,并且由于缓冲区结束,它转到下一行。
所以我尝试做一些类似 Console.WriteLine("C''r")的东西;将光标设置回,但仍闪烁
比我想使用一些偷偷摸摸的技巧并使用阿拉伯语从右到左标记,但没有奏效。
因此,我能想到的最好的方法是使用 Console.MoveBufferArea 方法将字符移动到右下角,因为这不会将光标设置为下一个右侧位置并避免使用新行。
如果您想完全隐藏控制台应用程序的垂直滚动条,我有一个工作代码。
来吧。。
这适用于任何分辨率。
由我测试。
class Program
{
private const int MF_BYCOMMAND = 0x00000000;
public const int SC_CLOSE = 0xF060;
public const int SC_MINIMIZE = 0xF020;
public const int SC_MAXIMIZE = 0xF030;
public const int SC_SIZE = 0xF000;
[DllImport("user32.dll")]
public static extern int DeleteMenu(IntPtr hMenu, int nPosition,intwFlags);
[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
static void Main(string[] args)
{
var largestWindowX = Console.WindowWidth;
var largestWindowY = Console.WindowHeight;
Console.BufferWidth = Console.WindowWidth = largestWindowX;
Console.BufferHeight = Console.WindowHeight = largestWindowY;
IntPtr handle = GetConsoleWindow();
IntPtr sysMenu = GetSystemMenu(handle, false);
if (handle != IntPtr.Zero)
{
DeleteMenu(sysMenu, SC_CLOSE, MF_BYCOMMAND);
DeleteMenu(sysMenu, SC_MINIMIZE, MF_BYCOMMAND);
DeleteMenu(sysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
DeleteMenu(sysMenu, SC_SIZE, MF_BYCOMMAND);
}
}
}