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消息的处理程序,顺序不特定。
当行被添加到文本缓冲区时,调整滚动条的范围。 垂直滚动条的范围将是行的总数,水平滚动条的范围将是最宽的行的宽度。
最好是有一个单一的字体 – 这使得计算更容易。 特定的字体技术并不重要。 你只需要能够跟踪角色的位置。
滚动如何有效地执行? 跟踪窗口顶部和底部的滚动条,当有消息提示时,只绘制当前可见的行。 其他人仍然在缓冲区,但他们不感动。 当窗口内容滚动时,只能画出从顶部或底部进入的部分,但是使用今天的处理器却浪费了精力 – 窗口会很快完成重新绘制,所以您不会注意到。
编辑:巧合的是,我碰到这个微软指南滚动酒吧应该是这项任务的重要阅读。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb787527.aspx
如果你想创建一个美丽的基于.NET的命令提示符替换,那么我建议看看http://poshconsole.codeplex.com/它使用WPF的图形元素,它实现了一个PowerShell脚本主机。 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
。 注意TextChanged
或KeyPressed
或KeyUp
事件,并相应地采取行动。 之后,您可以通过从简单的Panel
控件派生一个控件来创建自己的控件。 渲染通过覆盖OnPaint
方法(WinForms)来进行。 不需要循环,只需调用Invalidate
或Refresh
。
使用字符串数组或List<string>
或LinkedList<string>
作为行缓冲区,或者只使用存储在文本框中的文本。
如果您使用WinForms创建自己的控件,则System.Windows.Forms.TextRenderer
是渲染文本的不错选择。 它将在OnPaint
。
如果您创建自己的控件,滚动是一件棘手的事情。 System.Windows.Controls.Panel
已经包含了滚动支持,但是当文本改变时,你仍然需要告诉控件如何放置和调整滚动条按钮的大小。 另一方面,当用户移动滚动条并相应地更新显示时,您已经移动了文本。 性能不应该是这样一个简单的控制问题。