我应该如何在Windows上创build自定义graphics控制台/terminal?

Windows控制台界面(认为cmd窗口)是给用户一个非常简单的GUI。 然而,处理渲染,用户input和滚动的效率水平非常高。 用于创build此接口的方法无疑与传统桌面GUI的方法完全不同。

我有兴趣为Windows创build自己的定制控制台/terminal,最好使用基于C#和.NET的技术(例如托pipe的GDI +或WPF)。 作为一个起点,我会非常热衷于重新创build标准的简单Windowsshell程序。 然后,我可以扩展的东西,并从那里添加function。

我正在寻找关于如何创build这样一个控制台UI的一般指导,但是一些特定的要点包括:

  • 我应该使用什么样的渲染模型? 渲染循环? 部分更新(如WPF)? WinForms模型(不知道这是如何工作的)?

  • 渲染模型中使用了什么样的caching?

  • 字体是如何加载的,它们是如何渲染的? 他们是标准的TrueType字体,位图字体还是其他?

  • 滚动如何有效地执行?

  • 任何你认为可能是相关的!

事实上,对于内置的Windows控制台UI(甚至是优秀的LinuxterminalUI)如何执行这些操作(以及如何模拟它们)的任何解释都是理想的。

编辑:要清楚,我真的想完全从头开始。 基于像GDI +或WPF的graphics框架,但没有更多。

我曾经从头开始实现一个文本输出窗口 – 我想要一个像Visual Studio中的输出窗口一样的工作。 结果比我想象的要复杂得多,没有任何输入能力。

不幸的是,代码是用C ++编写的,属于前雇主,所以我不能和你分享。 但我可以给你一个想法。

您需要一种方法来存储可以快速编制索引的输出行。 如果您要限制显示的行数,还需要轻松擦除顶部的行。 在C ++中, deque<string>是完美的,我不知道C#中的等价物是什么(如果有的话)。

您将需要处理以下Windows消息的处理程序,顺序不特定。

  • WM_LBUTTONDOWN – 开始选择。 当按钮关闭时使用SetCapture来跟踪鼠标。
  • WM_LBUTTONUP – 结束选择。
  • WM_RBUTTONUP – 翻译成WM_CONTEXTMENU。
  • WM_CONTEXTMENU – 显示复制/剪切/粘贴菜单,以及其他你想要的。
  • WM_KEYDOWN – 响应4个光标键,Home / End,PageUp / PageDown。 CTRL-A / CTRL-C / CTRL-X / CTRL-V / CTRL-d。
  • WM_PAINT – 绘制窗口的内容。
  • WM_SIZE – 在窗口大小更改时更新滚动条。
  • WM_VSCROLL – 在垂直滚动期间更新窗口的可见部分。
  • WM_HSCROLL – 在水平滚动期间更新窗口的可见部分。
  • WM_CREATE – 在创建窗口时进行初始化。
  • WM_SETFOCUS – 创建系统插入符号以显示窗口中的当前位置。
  • WM_KILLFOCUS – 杀死脱字符,因为只有当前焦点窗口应该显示脱字符。
  • WM_MOUSEMOVE – 在鼠标左键关闭的情况下跟踪对选择的更改。
  • WM_CAPTURECHANGED – 结束选择。
  • WM_TIMER – 在选择期间光标离开窗口时自动滚动。
  • WM_GETDLGCODE – 添加DLGC_WANTARROWS,使箭头键将通过。
  • WM_MOUSEWHEEL – 响应鼠标滚轮滚动。

当行被添加到文本缓冲区时,调整滚动条的范围。 垂直滚动条的范围将是行的总数,水平滚动条的范围将是最宽的行的宽度。

最好是有一个单一的字体 – 这使得计算更容易。 特定的字体技术并不重要。 你只需要能够跟踪角色的位置。

滚动如何有效地执行? 跟踪窗口顶部和底部的滚动条,当有消息提示时,只绘制当前可见的行。 其他人仍然在缓冲区,但他们不感动。 当窗口内容滚动时,只能画出从顶部或底部进入的部分,但是使用今天的处理器却浪费了精力 – 窗口会很快完成重新绘制,所以您不会注意到。

编辑:巧合的是,我碰到这个微软指南滚动酒吧应该是这项任务的重要阅读。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb787527.aspx

如果你想创建一个美丽的基于.NET的命令提示符替换,那么我建议看看http://poshconsole.codeplex.com/它使用WPF的图形元素,它实现了一个PowerShell脚本主机&#x3002; PowerShell是微软取代历史悠久的命令提示符。 Windows 7默认安装PowerShell,但可以下载XP和Vista。 尽管脚本直接使用.NET对象,PowerShell具有高度可扩展性。 它也可以嵌入到其他程序中。

WPF + PowerShell将是你想要做的一个很好的起点。 如果你想要的话,你可以换掉你自己的命令/脚本引擎的PowerShell。 如果你真的有野心,你可以在DLR上实现你自己的脚本语言,作为你的命令解释器。

祝你好运。

看一看控制台的开源项目。 它做了很多,并做得很好。 它提供了一个统一的控制台,无论是基于字符的。 我在自己的选项卡中运行cmd,bash和python。

虽然它是用C ++编写的,但它不会提供自己编写的乐趣。

我用RichTextBox获得了巨大的成功。 实际上,它可以做所有你想做的事情:颜色自定义,有效的渲染和滚动,剪贴板操作等。输入是通过拦截窗口的KeyPress事件来组织的。

如果速度是最重要的,那么XNA是一个非常快速的方式(最小的编码)来高速绘制文本。 它可以处理数以百计的FPS精灵。 使用SpriteBatch :: DrawString()和SpriteFont,你可以用很少的编码工作就可以得到一个高速的“控制台”。 标准的“游戏”类可以修改,只重新绘制按需屏幕的子区域。 注意事项包括不完美的字距,会使文字变得模糊(您可以通过关闭消除锯齿和小心投影和精灵位置来解决此问题)。 如果这是一个问题,那么也许Direct2D提供了一个更好的解决方案(或任何已经提到的解决方案)。

作为第一个简单的方法,我将在多行模式下使用TextBox 。 注意TextChangedKeyPressedKeyUp事件,并相应地采取行动。 之后,您可以通过从简单的Panel控件派生一个控件来创建自己的控件。 渲染通过覆盖OnPaint方法(WinForms)来进行。 不需要循环,只需调用InvalidateRefresh

使用字符串数组或List<string>LinkedList<string>作为行缓冲区,或者只使用存储在文本框中的文本。

如果您使用WinForms创建自己的控件,则System.Windows.Forms.TextRenderer是渲染文本的不错选择。 它将在OnPaint

如果您创建自己的控件,滚动是一件棘手的事情。 System.Windows.Controls.Panel已经包含了滚动支持,但是当文本改变时,你仍然需要告诉控件如何放置和调整滚动条按钮的大小。 另一方面,当用户移动滚动条并相应地更新显示时,您已经移动了文本。 性能不应该是这样一个简单的控制问题。