C# 控制台禁用快速编辑模式、在指定行更新文本、注册Ctrl+C事件处理器

在第三行更新文本

 

代码如下

using Microsoft.Win32.SafeHandles;
using System;
using System.Runtime.InteropServices;
using System.Threading;

class Program
{
    [DllImport("kernel32.dll")]
    static extern SafeFileHandle GetStdHandle(int nStdHandle);

    [DllImport("kernel32.dll")]
    static extern bool GetConsoleMode(SafeFileHandle hConsoleHandle, out uint lpMode);

    [DllImport("kernel32.dll")]
    static extern bool SetConsoleMode(SafeFileHandle hConsoleHandle, uint dwMode);

    const int STD_INPUT_HANDLE = -10; // 标准输入设备(键盘)

    // 常量定义
    const uint ENABLE_QUICK_EDIT_MODE = 0x0040; // 快速编辑模式标识位

    static void DisableQuickEditMode()
    {
        var stdin = GetStdHandle(STD_INPUT_HANDLE);
        uint consoleMode;
        if (!GetConsoleMode(stdin, out consoleMode))
        {
            throw new System.IO.IOException("Failed to get console mode.");
        }

        // 清除快速编辑模式标志
        consoleMode &= ~ENABLE_QUICK_EDIT_MODE;

        // 设置新的控制台模式
        if (!SetConsoleMode(stdin, consoleMode))
        {
            throw new System.IO.IOException("Failed to set console mode.");
        }
    }

    static bool IsEnd = false;
    static void Main()
    {
        // 安装Ctrl+C事件处理器
        Console.CancelKeyPress += Console_CancelKeyPress;

        DisableQuickEditMode();//快速编辑模式已禁用,点击鼠标将不会暂停程序

        string[] progressStatuses = { "加载中...", "正在处理数据...", "即将完成..." };

        int index = 0;

        int targetLine = 2; // 假设我们想在第三行(索引从0开始)更新文本

        while (true)
        {
            // 获取当前窗口宽度以覆盖整行
            int windowWidth = Console.WindowWidth;

            // 移动光标到目标行行首
            Console.SetCursorPosition(0, targetLine);

            // 写入足够的空格来清除当前行内容
            Console.Write(new string(' ', windowWidth-1));

            // 移动光标到当前行首
            Console.SetCursorPosition(0, Console.CursorTop);

            // 覆盖现有内容,显示新的状态信息
            Console.Write(progressStatuses[index]);

            // 更改状态(模拟进度)
            index = (index + 1) % progressStatuses.Length;

            // 暂停一段时间以观察效果
            Thread.Sleep(1000);

            if (IsEnd)
                break;
        }
        Console.WriteLine("\n终止程序");
        Console.WriteLine("请按任意键结束");
        Console.ReadKey();

    }

    private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
    {
        IsEnd = true;

        // 如果你希望阻止程序退出,取消默认行为
        e.Cancel = true; // 设置为true则阻止程序终止

        //// 最后可以选择手动退出程序
        //Environment.Exit(0);
    }
}
View Code

 

在指定行列位置上打印文本(代码片段)

        /// <summary>
        /// 在指定行列位置上打印文本
        /// </summary>
        /// <param name="text">要打印的文本</param>
        /// <param name="targetLine">指定行</param>
        /// <param name="targetColumn">指定列</param>
        public static void WriteTextAtPosition(string text, int targetLine, int targetColumn)
        {
            lock (_syncLock)// 使用互斥锁,只有获取到锁的线程才能执行
            {
                // 获取当前窗口宽度以确保文本不会超出边界
                int windowWidth = Console.WindowWidth;

                // 检查目标列是否在窗口范围内
                if (targetColumn >= 0 && targetColumn < windowWidth)
                {
                    // 移动光标到目标行列位置
                    Console.SetCursorPosition(targetColumn, targetLine);

                    // 计算并清除从目标列到行尾的现有内容
                    int clearLength = windowWidth - targetColumn;
                    if (clearLength > 0)
                    {
                        Console.Write(new string(' ', clearLength));
                    }

                    // 移动光标到目标行列位置
                    Console.SetCursorPosition(targetColumn, targetLine);

                    // 计算剩余可写入的字符宽度,避免越界
                    int availableWidth = windowWidth - targetColumn;
                    string clippedText = text.Length > availableWidth ? text.Substring(0, availableWidth - 1) : text;

                    // 覆盖现有内容,显示新的状态信息
                    Console.Write(clippedText);
                }
                else
                {
                    throw new ArgumentOutOfRangeException("Target column is out of the console window bounds.");
                }
            }
        }
View Code

 

posted @ 2024-03-06 11:33  阿坦  阅读(57)  评论(0编辑  收藏  举报