【问题标题】:Deleting previously written lines in Console在控制台中删除以前写的行
【发布时间】:2011-03-11 13:35:33
【问题描述】:

是否可以使用与 Console.SetCursorPosition() 一起使用的 (Left,Top) 坐标删除控制台窗口的某些部分?

你可以为它定制一个方法吗?

【问题讨论】:

  • 是的,是的……(说真的,您可以在要“删除”的区域上写空格)。

标签: c# console


【解决方案1】:

Silky 的评论是正确答案:

  • 设置适当的背景颜色
  • 为您希望清除的每一行循环:
    • 将光标位置设置在左侧
    • 写出一串宽度合适的空格

例如:

public static void ClearArea(int top, int left, int height, int width) 
{
    ConsoleColor colorBefore = Console.BackgroundColor;
    try
    {
        Console.BackgroundColor = ConsoleColor.Black;
        string spaces = new string(' ', width);
        for (int i = 0; i < height; i++)
        {
            Console.SetCursorPosition(left, top + i);
            Console.Write(spaces);
        }
    }
    finally
    {
        Console.BackgroundColor = colorBefore;
    }
}

请注意,这将恢复背景颜色,但不会恢复之前的光标位置。

【讨论】:

  • 这会删除整行吗?因为我的程序是一个老式的 astroids 游戏,我试图让船移动,所以我必须删除它的最后一个位置。
  • @shorty876:不,它只会覆盖您指定的宽度。
  • 好吧,我的想法行不通。我尝试了其他方法,但该继续前进了。你会得到清晰易懂的代码的接受答案
【解决方案2】:

如果性能是一个问题,您可以直接操作控制台缓冲区。不幸的是,这将需要一些互操作,这是我改编自我给出的previous answer 的示例。这将很快清除控制台缓冲区的一个区域。由于互操作,它有点冗长,但如果你将它很好地包装到控制台帮助器类中,你可以扩展它以执行各种高性能控制台输出。

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

namespace ConsoleApplication1
{
  class Program
  {
    [STAThread]
    static void Main(string[] args)
    {
      Console.SetCursorPosition(0, 0);
      for (int x = 0; x < 80 * 25; ++x)
      {
        Console.Write("A");
      }
      Console.SetCursorPosition(0, 0);

      Console.ReadKey(true);

      ClearArea(1, 1, 78, 23);

      Console.ReadKey();
    }

    static void ClearArea(short left, short top, short width, short height)
    {
      ClearArea(left, top, width, height, new CharInfo() { Char = new CharUnion() { AsciiChar = 32 } });
    }

    static void ClearArea(short left, short top, short width, short height, CharInfo charAttr)
    {
      using (SafeFileHandle h = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero))
      {
        if (!h.IsInvalid)
        {
          CharInfo[] buf = new CharInfo[width * height];
          for (int i = 0; i < buf.Length; ++i)
          {
            buf[i] = charAttr;
          }

          SmallRect rect = new SmallRect() { Left = left, Top = top, Right = (short)(left + width), Bottom = (short)(top + height) };
          WriteConsoleOutput(h, buf,
            new Coord() { X = width, Y = height },
            new Coord() { X = 0, Y = 0 },
            ref rect);
        }
      }
    }

    [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);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CloseHandle(IntPtr hObject);

    [DllImport("kernel32.dll", SetLastError = true)]
    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)
      {
        this.X = X;
        this.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(0)]
      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;
    }   
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 2021-10-15
    • 2012-02-17
    • 1970-01-01
    • 2021-10-25
    相关资源
    最近更新 更多