WriteConsoleOutput 间距错误
WriteConsoleOutput wrong spacing
为什么字符写在1个单元格中? Windows控制台API,但是现在我运行陷入了一个脑洞大开的问题..本来应该显示一条线,却显示点
我的代码:
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
public COORD dwSize;
public COORD dwCursorPosition;
public short wAttributes;
public SmallRect srWindow;
public COORD dwMaximumWindowSize;
}
[StructLayout(LayoutKind.Explicit)]
public struct CharInfo
{
[FieldOffset(0)]
internal char UnicodeChar;
[FieldOffset(0)]
internal short AsciiChar;
[FieldOffset(2)]
internal COLOR Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct SmallRect
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
public COORD(short X, short Y)
{
this.X = X;
this.Y = Y;
}
}
public class Engine
{
public short Width { get; protected set; }
public short Height { get; protected set; }
public CharInfo[] buffer;
protected SmallRect rect;
protected const int STDIN = -10;
protected const int STDOUT = -11;
protected const int STDERR = -12;
public Engine(short width = 80, short height = 25)
{
Width = width;
Height = height;
buffer = new CharInfo[width * height];
rect = new SmallRect() { Left = 0, Top = 0, Right = width, Bottom = height };
SetConsoleCP(437); SetConsoleOutputCP(437);
Console.SetBufferSize(width, height);
Console.SetWindowSize(width, height);
}
public void SetPixel(short x, short y, Character symbol, COLOR color)
{
SetPixel(x, y, new CharInfo() {Attributes = color, UnicodeChar = (char)symbol });
}
protected void SetPixel(short x, short y, CharInfo @char)
{
if (x >= 0 && y >= 0 && x < Width && y < Height)
{
buffer[y * Width + x] = @char;
}
WriteConsoleOutput(GetStdHandle(STDOUT), buffer, new COORD(80, 25), new COORD(0, 0), ref rect);
}
[DllImport("kernel32.dll",SetLastError =true)]
static extern bool SetConsoleOutputCP(uint CodePageId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleCP(uint CodePageId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteConsoleOutput(IntPtr hConsoleOutput, CharInfo[] buffer, COORD bufferSize, COORD bufferCoord, ref SmallRect region);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int handle);
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO buffer);
}
class Program
{
[STAThread]
static void Main(string[] args)
{
Engine e = new Engine();
for (short i = 0; i < 10; i++)
{
e.SetPixel(i, 1, Character.Full, COLOR.FG_RED);
}
Console.ReadLine();
}
}
结果输出:
虽然你没有表现出来,但我相信你对颜色的定义是错误的。 COLOR 可能是枚举类型。确保它的基类型为 short,而不是 int。
enum COLOR : short
{
FW_RED = 0x0004,
}
如果省略“:short”,编译器将生成大小为 6 字节而不是 4 字节的 CharInfo 结构。
有了正确的定义,我得到了完整的一行:
为什么字符写在1个单元格中? Windows控制台API,但是现在我运行陷入了一个脑洞大开的问题..本来应该显示一条线,却显示点
我的代码:
[StructLayout(LayoutKind.Sequential)]
public struct CONSOLE_SCREEN_BUFFER_INFO
{
public COORD dwSize;
public COORD dwCursorPosition;
public short wAttributes;
public SmallRect srWindow;
public COORD dwMaximumWindowSize;
}
[StructLayout(LayoutKind.Explicit)]
public struct CharInfo
{
[FieldOffset(0)]
internal char UnicodeChar;
[FieldOffset(0)]
internal short AsciiChar;
[FieldOffset(2)]
internal COLOR Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct SmallRect
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
public COORD(short X, short Y)
{
this.X = X;
this.Y = Y;
}
}
public class Engine
{
public short Width { get; protected set; }
public short Height { get; protected set; }
public CharInfo[] buffer;
protected SmallRect rect;
protected const int STDIN = -10;
protected const int STDOUT = -11;
protected const int STDERR = -12;
public Engine(short width = 80, short height = 25)
{
Width = width;
Height = height;
buffer = new CharInfo[width * height];
rect = new SmallRect() { Left = 0, Top = 0, Right = width, Bottom = height };
SetConsoleCP(437); SetConsoleOutputCP(437);
Console.SetBufferSize(width, height);
Console.SetWindowSize(width, height);
}
public void SetPixel(short x, short y, Character symbol, COLOR color)
{
SetPixel(x, y, new CharInfo() {Attributes = color, UnicodeChar = (char)symbol });
}
protected void SetPixel(short x, short y, CharInfo @char)
{
if (x >= 0 && y >= 0 && x < Width && y < Height)
{
buffer[y * Width + x] = @char;
}
WriteConsoleOutput(GetStdHandle(STDOUT), buffer, new COORD(80, 25), new COORD(0, 0), ref rect);
}
[DllImport("kernel32.dll",SetLastError =true)]
static extern bool SetConsoleOutputCP(uint CodePageId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleCP(uint CodePageId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteConsoleOutput(IntPtr hConsoleOutput, CharInfo[] buffer, COORD bufferSize, COORD bufferCoord, ref SmallRect region);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int handle);
[DllImport("kernel32.dll")]
static extern uint GetLastError();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO buffer);
}
class Program
{
[STAThread]
static void Main(string[] args)
{
Engine e = new Engine();
for (short i = 0; i < 10; i++)
{
e.SetPixel(i, 1, Character.Full, COLOR.FG_RED);
}
Console.ReadLine();
}
}
结果输出:
虽然你没有表现出来,但我相信你对颜色的定义是错误的。 COLOR 可能是枚举类型。确保它的基类型为 short,而不是 int。
enum COLOR : short
{
FW_RED = 0x0004,
}
如果省略“:short”,编译器将生成大小为 6 字节而不是 4 字节的 CharInfo 结构。
有了正确的定义,我得到了完整的一行: