English 中文(简体)
• 如何保留一行用于多读孔子的投入?
原标题:How to reserve a row for input in multi-threaded Console?

现在,这个问题困扰着我,我认识到,很难描述我所期待的东西。 我希望能够在C# Console Application中保留一行案文投入,同时允许其他信息在其余各行更新。 更具体地说,我只想进行一场小的泥.游戏,在使用者忙忙投入的情况下,游戏也得到更新。 投入必须阻碍信息流动。

我愿实现用户写作对屏幕上最后可见的一行的投入的效果,而其他案文则照常说,但并没有贬低我的投入线,也不要 over。

如果我以表格来描述这一点,那么我就想象到,具有多线文本箱作为信息的最高部分,在底层有单一线文本箱供投入使用。

问题回答

One option that you could try, is to directly manipulate the console buffer to render your game area and use the Console.SetCursorPosition to position the cursor to the input line where you use Console.ReadLine for example to take the user input.

由于直接操纵缓冲不会影响 cur子的位置,而且独立于康索尔阅读/仪式功能,你可以随时更新哥索尔缓冲,涵盖头24条线,25条线正在等待投入。 如果我有一段时间,我将尝试把我所说的话样本汇集在一起,但与此同时,你可以提及我为一位协调人直接撰写康索尔缓冲文件而提供的其他答复。

我怎么能将快速的彩色产出写给康索尔?

当然,你会想写一些 n天的职能,使这项工作容易进行,我总是想这样做,我只想同ole子做足够的工作,以便我实际上能够做些事。

<>Update: 在接受用户投入的同时,添加了一个小实例,说明如何在校对青少年进行更新。 制止这种行为的正当类型。 值得注意的是,科索尔班并不理想,我没有关闭奥索尔,只是一部速成的mo。

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

namespace ConsoleDemo
{
  class Program
  {
    static void Main(string[] args)
    {
      Thread t = new Thread(new ThreadStart(UpdateConsole));
      t.IsBackground=true;
      t.Start();      

      string input;
      do
      {
        Console.SetCursorPosition(0, 23);
        Console.Write("Command: ");
        input = Console.ReadLine();
        ConsoleBuffer.ClearArea(0, 21, 80, 3);
        Console.SetCursorPosition(0, 22);
        Console.Write(input);
      } while (!string.Equals(input, "quit", StringComparison.OrdinalIgnoreCase));
    }

    static void UpdateConsole()
    {
      int i = 0;
      Random rnd = new Random();
      while (true)
      {
        string s = new string((char)(65 + (i % 26)),1);
        for (short x = 0; x < 80; ++x)
        {
          for (short y = 0; y < 20; ++y)
          {
            ConsoleBuffer.WriteAt(x, y, s);
            ConsoleBuffer.SetAttribute(x, y, (short)(rnd.Next(15)+1));
          }          
        }
        Thread.Sleep(500);
        i++;
      }
    }
  }

  public class ConsoleBuffer
  {
    private static SafeFileHandle _hBuffer = null;

    static ConsoleBuffer()
    {
      _hBuffer = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);

      if (_hBuffer.IsInvalid)
      {
        throw new Exception("Failed to open console buffer");
      }      
    }

    public static void WriteAt(short x, short y, string value)
    {
      int n = 0;
      WriteConsoleOutputCharacter(_hBuffer, value, value.Length, new Coord(x, y), ref n);
    }

    public static void SetAttribute(short x, short y, short attr)
    {
      SetAttribute( x, y, new short[] { attr });
    }

    public static void SetAttribute(short x, short y, short[] attrs)
    {
      int n = 0;
      WriteConsoleOutputAttribute(_hBuffer, attrs, attrs.Length, new Coord(x, y), ref n);
    }

    public static void ClearArea(short left, short top, short width, short height, char ch =    )
    {
      ClearArea(left, top, width, height, new CharInfo() { Char = new CharUnion() { UnicodeChar = ch } });
    }

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

    private static void ClearArea(short left, short top, short width, short height, CharInfo charAttr)
    {
      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(_hBuffer, 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);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteConsoleOutputCharacter(
      SafeFileHandle hConsoleOutput,
      string lpCharacter,
      int nLength,
      Coord dwWriteCoord,
      ref int lpumberOfCharsWritten);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteConsoleOutputAttribute(
      SafeFileHandle hConsoleOutput,
      short[] lpAttributes,
      int nLength,
      Coord dwWriteCoord,
      ref int lpumberOfAttrsWritten);

    [StructLayout(LayoutKind.Sequential)]
    struct Coord
    {
      public short X;
      public short Y;

      public Coord(short X, short Y)
      {
        this.X = X;
        this.Y = Y;
      }
    };

    [StructLayout(LayoutKind.Explicit)]
    struct CharUnion
    {
      [FieldOffset(0)]
      public char UnicodeChar;
      [FieldOffset(0)]
      public byte AsciiChar;
    }

    [StructLayout(LayoutKind.Explicit)]
    struct CharInfo
    {
      [FieldOffset(0)]
      public CharUnion Char;
      [FieldOffset(2)]
      public short Attributes;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct SmallRect
    {
      public short Left;
      public short Top;
      public short Right;
      public short Bottom;
    }
  }
}

The dotNet Console supports SetCursorPosition() and you also use the old DOS trick of ending a line with instead of .

但是,多读和适用像好结合一样。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签