「AB開発日記」というタイトルに変更したものの、肝心の開発ネタが疎かになっていました。ということで、本日はエディタのネタを語ります。

ABに付属するProjectEditorは独自のエディタエンジンを搭載しており、通常のエディットコントロールと比べると下記のような相違点があります。

・部分的に色が変えられる

・アンドゥ・リドゥでかなり前の状態に戻せる

・Shift-JIS、EUC-JP、UTF-8などの文字コードに対応する

・CRLF、LF、CRなどの改行コードに対応する

このほか、コード補完機能がついていたり、複数のファイルを統合するツールがついていたりするのですが、ProjectEditorエディタエンジンの特徴というとこんなもんです。

しかし、最大のデメリットもあります。

それは重いということ。

数十キロバイトであれば問題ないのですが、数百キロバイト、数メガバイトになってくると、スクロール機能がカチコチになってしまいます。

これではマズイッ、ということで、本日はエディタエンジンの最適化を行います。

独自のエディタエンジンというくらいなので、自前で描画モジュールを抱えておりまして、当然、その中からTextOut関数なんかが呼び出されているワケです。コードエディタという位置づけから、色が変わる恐れがあるので、一文字単位での処理になるのですが、文字数の分だけTextOut関数を呼び出すのはあまり効率が良くありません(現状はこの状態f(–;;;)。

そこで、基本事項ではありますが、下記のような改良を行ったんです。

  • 文字色が同一のものは、まとめてTextOut関数に送る(TextOut関数の呼び出し回数を最小限に留める)
  • いきなりオリジナルのウィンドウDCに描画を行うと、古い情報を消さなければならない(ヘタすると、チラツクし…)。そこで、再描画テクニックの基本事項であるメモリデバイスコンテキストを採用する。

メモリデバイスコンテキストを利用した再描画は、下記のような手順で行えます。

※hdcはウィンドウDC

※memdcはメモリDC

  1. CreateCompatibleDC関数でhdcをコピーし、memdcに格納
  2. CreateCompatibleBitmap関数でhdcと互換性のあるビットマップを生成
  3. memdcに今生成されたビットマップをSelectObject関数で適用する
  4. memdcに向かって、TextOut
  5. BitBlt関数を使って、hdcにmemdcの内容を描画
  6. memdc、ビットマップを破棄

なんか、べた書きになってしまいましたが、まぁ、無難なテクニックです。今まで、ProjectEditorの再描画部分がこの手法じゃなかったのがコワいです…(おっと、因みにRADツールなんかはココらへん、きちんとしております)。