web-dev-qa-db-ja.com

Windowsでカスタムのグラフィカルコンソール/ターミナルを作成するにはどうすればよいですか?

Windowsコンソールインターフェイス(cmdウィンドウを考えてください)は、ユーザーにとって非常にシンプルなGUIです。ただし、レンダリング、ユーザー入力、およびスクロールを処理する効率のレベルは非常に高くなっています。このインターフェイスの作成に使用される方法は、間違いなく、従来のデスクトップGUIの方法とはかなり異なります。

Windows用に独自のカスタムコンソール/ターミナルを作成することに興味があります。できればC#および.NETベースのテクノロジ(マネージドGDI +またはWPFなど)を使用します。出発点として、私は単純に標準の単純なWindowsシェルを再作成することに非常に熱心です。その後、物事を拡張し、そこから機能を追加することができました。

このようなコンソールUIを作成する方法に関する一般的なガイダンスを探していますが、具体的なポイントは次のとおりです。

  • どのようなレンダリングモデルを使用する必要がありますか?レンダリングループ?部分的な更新(WPFなど)? WinFormsモデル(これがどのように機能するかわからない)?

  • レンダリングモデルではど​​のような種類のキャッシュが使用されますか?

  • フォントはどのように読み込まれ、どのようにレンダリングされますか?それらは標準のTrueTypeフォント、ビットマップフォント、またはその他のものですか?

  • スクロールはどのように効率的に実行されますか?

  • あなたが関連すると思う他のものは何でも!

実際、組み込みのWindowsコンソールUI(または優れたLinuxターミナルUI)がこれらのことをどのように行うか、そしてどのようにそれらをエミュレートできるかについての説明は理想的です。

編集:明確にするために、私は本当にこれを完全にゼロからやりたいと思っています。 GDI +やWPFなどのグラフィカルフレームワークに基づいていますが、それ以上ではありません。

32
Noldorin

私はかつてテキスト出力ウィンドウを最初から実装しました-VisualStudioの出力ウィンドウのように機能するものが欲しかったのです。思ったより複雑で、入力機能がありませんでした。

残念ながら、コードは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-スクロールのためにマウスホイールに応答します。

テキストバッファに行が追加されたら、スクロールバーの範囲を調整します。垂直スクロールバーの範囲は行の総数になり、水平スクロールバーの範囲は最も広い行の幅になります。

等幅のフォントを1つ持つのが最善です。これにより、計算がはるかに簡単になります。特定のフォント技術はそれほど重要ではありません。キャラクターの位置を追跡できる必要があります。

スクロールはどのように効率的に実行されますか?ウィンドウがスクロールするときにウィンドウの上部と下部の線を追跡し、ペイントメッセージが表示されたら、現在表示されている線のみをペイントします。他のものはまだバッファにありますが、触れられません。ウィンドウがスクロールするときにウィンドウのコンテンツをブリットし、上または下から入ってくる部分だけをペイントすることは可能ですが、今日のプロセッサでは無駄な労力です-ウィンドウは完全な再ペイントを非常に迅速に行うので、気付かないでしょう。

編集:偶然にも、このタスクに欠かせない読み物であるスクロールバーに関するこのMicrosoftガイドに出くわしました。 http://msdn.Microsoft.com/en-us/library/windows/desktop/bb787527.aspx

20
Mark Ransom

美しい.NETベースのコマンドプロンプト置換を作成する場合は、 http://poshconsole.codeplex.com/ を参照することをお勧めします。グラフィック要素にWPFを使用し、PowerShellスクリプトホストを実装します。 PowerShellは、由緒あるコマンドPromptに代わるMicrosoftの製品です。 PowerShellはWindows7にデフォルトでインストールされますが、XPおよびVista用にダウンロードできます。PowerShellは.NETオブジェクトを直接使用するスクリプトを使用しても高度に拡張可能です。また、他のプログラムに埋め込むこともできます。

WPF + PowerShellは、やりたいことの出発点として最適です。必要に応じて、PowerShellを独自のコマンド/スクリプトエンジンに交換できます。本当に野心的な場合は、DLRに独自のスクリプト言語を実装して、コマンドインタープリターとして機能させることができます。

幸運を祈ります。

8
Brad Campbell

コンソール オープンソースプロジェクトをご覧ください。それは多くのことをし、そしてそれを非常にうまくやります。これは、文字ベースのものすべてに統合されたコンソールを提供します。 cmd、bash、python)をそれぞれ独自のタブで実行します。

それはC++であり、それを自分で書く楽しみを提供しません。

4
ixe013

私は出力用のRichTextBoxで大成功を収めました。実際には、色のカスタマイズ、効果的なレンダリングとスクロール、クリップボード操作など、必要なすべてのことを実行します。入力は、ウィンドウのKeyPressイベントをインターセプトすることによって編成されました。

3
ogggre

速度が最優先の場合、XNAはテキストを高速で描画するための非常に迅速な方法(最小限のコーディング)です。数百のFPSで数千のスプライトを処理できます。 SpriteBatch :: DrawString()とSpriteFontを使用すると、コーディングの労力をほとんどかけずに高速の「コンソール」を取得できます。標準の「ゲーム」クラスを変更して、画面のサブ領域のみをオンデマンドで再描画できます。警告には、テキストにぼやけた外観を与える不完全なカーニングが含まれます(アンチエイリアシングをオフにし、投影とスプライトの配置に注意することで、これを修正できる場合があります)。これが問題である場合は、おそらくDirect2Dがより良い解決策(またはすでに述べた解決策のいずれか)を提供します。

3
axon

最初の簡単なアプローチとして、複数行モードでTextBoxを使用します。 TextChangedまたはKeyPressedまたはKeyUpイベントを監視し、それに応じて行動します。後で、たとえば単純なPanelコントロールから派生させることにより、独自のコントロールを作成できます。レンダリングは、OnPaintメソッド(WinForms)をオーバーライドすることによって行われます。ループは必要ありません。InvalidateまたはRefreshを呼び出すだけです。

文字列配列またはList<string>またはLinkedList<string>をラインバッファとして使用するか、テキストボックスに保存されているテキストを使用します。

WinFormsを使用して独自のコントロールを作成する場合は、System.Windows.Forms.TextRendererがテキストのレンダリングに適しています。 OnPaintで使用されます。

独自のコントロールを作成する場合、スクロールは注意が必要です。 System.Windows.Controls.Panelにはすでにスクロールのサポートが含まれていますが、テキストが変更されたときにスクロールバーボタンを配置およびサイズ変更する方法をコントロールに指示する必要があります。一方、ユーザーがスクロールバーを移動すると、テキストが移動し、それに応じて表示が更新されます。このような単純な制御では、パフォーマンスは問題になりません。

FastColoredTextBox githubのプロジェクトにはConsoleの例があります。それは:

  • 効率的で高速
  • 有色
  • WPFおよびWinFormで利用可能
  • C#で読みやすい

コードを読むことはあなたに大いに役立つと思います。

1
samad montazeri