エディタエンジンの最適化
abdev 4月 29th, 2006「AB開発日記」というタイトルに変更したものの、肝心の開発ネタが疎かになっていました。ということで、本日はエディタのネタを語ります。
ABに付属するProjectEditorは独自のエディタエンジンを搭載しており、通常のエディットコントロールと比べると下記のような相違点があります。
・部分的に色が変えられる
・アンドゥ・リドゥでかなり前の状態に戻せる
・Shift-JIS、EUC-JP、UTF-8などの文字コードに対応する
・CRLF、LF、CRなどの改行コードに対応する
このほか、コード補完機能がついていたり、複数のファイルを統合するツールがついていたりするのですが、ProjectEditorエディタエンジンの特徴というとこんなもんです。
しかし、最大のデメリットもあります。
それは重いということ。
数十キロバイトであれば問題ないのですが、数百キロバイト、数メガバイトになってくると、スクロール機能がカチコチになってしまいます。
これではマズイッ、ということで、本日はエディタエンジンの最適化を行います。
独自のエディタエンジンというくらいなので、自前で描画モジュールを抱えておりまして、当然、その中からTextOut関数なんかが呼び出されているワケです。コードエディタという位置づけから、色が変わる恐れがあるので、一文字単位での処理になるのですが、文字数の分だけTextOut関数を呼び出すのはあまり効率が良くありません(現状はこの状態f(–;;;)。
そこで、基本事項ではありますが、下記のような改良を行ったんです。
- 文字色が同一のものは、まとめてTextOut関数に送る(TextOut関数の呼び出し回数を最小限に留める)
- いきなりオリジナルのウィンドウDCに描画を行うと、古い情報を消さなければならない(ヘタすると、チラツクし…)。そこで、再描画テクニックの基本事項であるメモリデバイスコンテキストを採用する。
メモリデバイスコンテキストを利用した再描画は、下記のような手順で行えます。
※hdcはウィンドウDC
※memdcはメモリDC
- CreateCompatibleDC関数でhdcをコピーし、memdcに格納
- CreateCompatibleBitmap関数でhdcと互換性のあるビットマップを生成
- memdcに今生成されたビットマップをSelectObject関数で適用する
- memdcに向かって、TextOut
- BitBlt関数を使って、hdcにmemdcの内容を描画
- memdc、ビットマップを破棄
なんか、べた書きになってしまいましたが、まぁ、無難なテクニックです。今まで、ProjectEditorの再描画部分がこの手法じゃなかったのがコワいです…(おっと、因みにRADツールなんかはココらへん、きちんとしております)。
4月 30th, 2006 at 13時07分34秒
1文字単位に描画しているのは気付いていましたよ。Win XPでClearTypeを使ったときの表示のされ方は結構悲惨でしたから。
4月 30th, 2006 at 15時30分33秒
遅いのは承知でしたが、ClearTypeを使ったときの乱れは未確認でした。。。試してはみたのですが、特に悲惨な状況ではありませんでした。どんな感じになるのか教えていただけないでしょうか。
5月 1st, 2006 at 20時07分46秒
話がずれますがいろいろな機能があるならテキストエディダにしてみたらどうでしょう。(標準テキストを作る機能とは別にです。)
5月 2nd, 2006 at 13時25分47秒
フォーラムで見ていらしたと思いますが、僕はリッチエディットを使ってつくっちゃいました(爆)ちゃんとアンドゥ機能もストリームを使って実装していますが^^;まぁ、大きなファイルになるとめちゃくちゃ色変更処理が遅くなりますが…。