📜  c# 控制台创建窗口 - C# (1)

📅  最后修改于: 2023-12-03 15:13:51.767000             🧑  作者: Mango

C# 控制台创建窗口

在 C# 中,我们可以使用 Win32 API 函数来创建控制台窗口,从而可以实现控制台窗口的各种定制功能。下面我们会演示如何创建一个带有自定义标题和背景颜色的控制台窗口。

创建控制台窗口

首先,我们需要引入 System.Runtime.InteropServices 名称空间,以使用 Win32 API 函数。

using System.Runtime.InteropServices;

然后,在 Main 函数中调用 CreateConsoleWindow 方法,该方法会创建一个新的控制台窗口。

static void Main(string[] args)
{
    CreateConsoleWindow("Custom Console Window", 80, 30, ConsoleColor.DarkBlue);
    Console.WriteLine("Press any key to exit...");
    Console.ReadKey(true);
}

CreateConsoleWindow 方法的定义如下:

[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowText(IntPtr hWnd, string lpString);

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetConsoleCursorPosition(IntPtr hConsoleOutput, COORD dwCursorPosition);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FillConsoleOutputAttribute(IntPtr hConsoleOutput, ushort wAttribute, uint nLength, COORD dwWriteCoord, out uint lpNumberOfAttrsWritten);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FillConsoleOutputCharacter(IntPtr hConsoleOutput, char cCharacter, uint nLength, COORD dwWriteCoord, out uint lpNumberOfCharsWritten);

struct COORD
{
    public short X;
    public short Y;
}

struct SMALL_RECT
{
    public short Left;
    public short Top;
    public short Right;
    public short Bottom;
}

struct CONSOLE_SCREEN_BUFFER_INFO
{
    public COORD dwSize;
    public COORD dwCursorPosition;
    public short wAttributes;
    public SMALL_RECT srWindow;
    public COORD dwMaximumWindowSize;
}

static void CreateConsoleWindow(string title, int width, int height, ConsoleColor backgroundColor)
{
    int left = (Console.LargestWindowWidth - width) / 2;
    int top = (Console.LargestWindowHeight - height) / 2;
    
    SetConsoleMode(GetStdHandle(-11), 7);
    
    var handle = GetConsoleWindow();
    SetWindowText(handle, title);
    SetWindowPos(handle, IntPtr.Zero, left, top, width * 8, height * 16, 0x0001);
    
    uint mode;
    GetConsoleMode(GetStdHandle(-10), out mode);
    mode |= 0x0004;
    SetConsoleMode(GetStdHandle(-10), mode);
    
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(-11), out csbi);
    FillConsoleOutputAttribute(GetStdHandle(-11), (ushort)(int)backgroundColor, csbi.dwSize.X * csbi.dwSize.Y, new COORD { X = 0, Y = 0 }, out uint _);
    SetConsoleCursorPosition(GetStdHandle(-11), new COORD { X = 0, Y = 0 });
    FillConsoleOutputCharacter(GetStdHandle(-11), ' ', csbi.dwSize.X * csbi.dwSize.Y, new COORD { X = 0, Y = 0 }, out uint _);
}
代码解释
  • CreateConsoleWindow 函数使用了多个 Win32 API 函数来修改控制台窗口的各种属性,具体如下:
    • GetConsoleWindow 函数获取当前进程的控制台窗口句柄。
    • SetWindowText 函数设置控制台窗口的标题。
    • SetWindowPos 函数设置控制台窗口的位置、大小、Z 顺序等属性。
    • SetConsoleMode 函数设置控制台输入/输出的模式。这里我们使用该函数来设置控制台窗口的不可调整大小、不可最大化、不可最小化等属性。
    • GetStdHandle 函数获取标准输入/输出/错误的句柄。这里我们使用该函数获取标准输出的句柄。
    • GetConsoleMode 函数获取控制台输入/输出的模式。
    • GetConsoleScreenBufferInfo 函数获取当前控制台屏幕缓冲区的信息。
    • SetConsoleCursorPosition 函数设置控制台光标位置。
    • FillConsoleOutputAttribute 函数设置控制台屏幕缓冲区一段区域的背景颜色。
    • FillConsoleOutputCharacter 函数设置控制台屏幕缓冲区一段区域的字符。

具体的实现细节请参考注释。

结论

使用 Win32 API 函数,我们可以轻松地创建自定义样式的控制台窗口,从而提高程序交互的友好度和体验。