我目前正在编写一个小的实用程序库,以帮助提高写入控制台时的性能,而且我还面临一个问题,在这个问题上,它实际上无法输出任何文本。下面是我的代码:
public static class QuickDraw
{
private static short Width => (short)Console.WindowWidth;
private static short Height => (short)Console.WindowHeight;
private static SafeFileHandle Handle =>
Kernel32.CreateFile("$CONOUT", 0x40000000, 2, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
private static Kernel32.Coord Cursor =>
new Kernel32.Coord((short)Console.CursorLeft, (short)Console.CursorTop);
private static Kernel32.SmallRect WriteRegion =>
new Kernel32.SmallRect() { Left = 0, Top = 0, Right = Width, Bottom = Height };
private static Kernel32.Coord BufferSize =>
new Kernel32.Coord(Width, Height);
private static Kernel32.Coord BufferCoord =>
new Kernel32.Coord(0, 0);
public static void Write(char[] text, ConsoleColor fg, ConsoleColor bg)
{
Kernel32.CharInfo[] buffer = new Kernel32.CharInfo[Width * Height];
Kernel32.Coord cursor = Cursor;
for (int i = 0; i < text.Length; i++)
{
if (text[i] == '\n')
{
cursor.X = 0;
cursor.Y++;
}
else
{
int index = (cursor.Y * Width) + cursor.X;
// Set character
buffer[index].Char.AsciiChar = (byte)text[i];
// Set color
// (Crazy heckin bitwise crap, don't touch.)
buffer[index].Attributes = (short)((int)fg | ((int)bg | (2 << 4)));
// Increment cursor
cursor.X++;
}
// Make sure that cursor does not exceed bounds of window
if (cursor.X >= Width)
{
cursor.X = 0;
cursor.Y++;
}
if (cursor.Y >= Height)
{
cursor.Y = 0;
}
}
var writeRegion = WriteRegion;
Kernel32.WriteConsoleOutput(Handle, buffer, BufferSize, BufferCoord, ref writeRegion);
Console.SetCursorPosition(cursor.X, cursor.Y);
}
}
// Taken from https://stackoverflow.com/a/2754674/7937949
internal static class Kernel32
{
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public 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);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool WriteConsoleOutput(
SafeFileHandle hConsoleOutput,
CharInfo[] lpBuffer,
Coord dwBufferSize,
Coord dwBufferCoord,
ref SmallRect lpWriteRegion);
[StructLayout(LayoutKind.Sequential)]
public struct Coord
{
public short X;
public short Y;
public Coord(short x, short y)
{
X = x;
Y = y;
}
}
[StructLayout(LayoutKind.Explicit)]
public struct CharUnion
{
[FieldOffset(0)] public char UnicodeChar;
[FieldOffset(0)] public byte AsciiChar;
}
[StructLayout(LayoutKind.Explicit)]
public struct CharInfo
{
[FieldOffset(2)] public CharUnion Char;
[FieldOffset(2)] public short Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct SmallRect
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
}我主要是从this post获取实现,添加了一个新的类来简化它的使用。我不太清楚我的问题出在哪里,因为我的调试器工作不正常,但我很确定它在我的QuickDraw实现中。
当我尝试使用QuickDraw.Write()时,光标移动到它试图打印的任何字符串的末尾,但实际上什么也没有显示出来。我做错了什么?
发布于 2018-04-17 15:27:44
首先,你没有正确地复制代码。有一些错误。
[FieldOffset(2)] public CharUnion Char;
至
[FieldOffset(0)] public CharUnion Char;$CONOUT更改为此CONOUT$当然,如果您想要正确的前景/背景色表示,那么您必须删除2 << 4。我甚至不知道你为什么把它放在那里。
https://stackoverflow.com/questions/49880854
复制相似问题