CEdit でテキスト10万行を 3秒程度で表示する方法はないでしょうか?
現在、CWnd::SetWindowText で表示すると 1分以上かかる状況です。
秀丸などのエディターだと、10万行表示するのに 2秒程度ですんでいるので、どうにか
その程度の性能を出したいのです。
性能上のことなので、マシンのスペックなどにも左右されますが、それほど遅いマシン
は使っていません。
職場からアクセスできないので、応答は帰宅後になります。
画面に映る部分のみ描画するとよいです。
方法は十人十色なので、まずは自分のやり方でやってみてはどうでしょうか。
CEdit なんか使ったら不可能
自前で作るしかない。
全てをCEditで表示するのは無理。
既出ですが、見える範囲計算して少しのデータだけCEditで見せる。
あるいは、GDI系APIつかって自前で描画し、編集操作を疑似るか。
秀丸は後者の気がします・・・。
今回のケースでは CEdit はダメ。という回答が出ているので↓その最大の理由。
> 現在、CWnd::SetWindowText で表示すると 1分以上かかる状況です。
SetWindowText() 時に文字列の整形処理等も行われる。
この初期化・整形処理に時間が掛かっている。
例えば、水平スクロールを可能にするためには最大水平行幅(10万行中で一番長い行の表
示幅)が必要だし、自動改行を行うためにも10万行の行幅を取得し計算する必要が出る。
プロポーショナルフォント禁止であればまだこれらの処理は簡単だが、CEdit はプロポー
ショナルフォントを考慮しているので激しくコストのかかる処理となってる。
逆に、秀丸(俺は持ってません)がプロポーショナルフォントで 2秒という速度ならば
賛辞を送って良いと思う。
> 秀丸などのエディターだと、10万行表示するのに 2秒程度ですんでいるので、
> どうにかその程度の性能を出したいのです。
たぶんメモリーに溜め込むだけで表示はしていないと思います。
人が見れる画面の行数というのは決まっていますから、そこだけ表示すればいいのでは
ないでしょうか。
逆に最大10万件と数が限られているのなら、先に10万件分のメモリーをヒープ
で確保して、そのメモリーに10万件のデータを溜め込む。
あとは、スクロール等で指定された部分だけ表示する。
ではだめですか?
秀丸も近いようなことをやっていると思います。
>秀丸などのエディターだと、10万行表示するのに 2秒程度ですんでいるので、
>どうにかその程度の性能を出したいのです。
CEdit では難しいと思う。
>CEdit なんか使ったら不可能
>自前で作るしかない。
僕もこの意見に賛成。
>CEdit でテキスト10万行を 3秒程度で表示する方法はないでしょうか?
諦めるべきかな。
簡単なエディットボックスを自前で作った方が早いと思う。
データの溜め込みは単純に行単位で読み込み、
後は GDI 部品で描画すれば良い。
水平スクロール用に最大の桁数を別変数で管理すれば楽だね。
CEdit は汎用的に作られているから高速性を求めると不利になるから。
テスト用では CEdit を使って
自前のエディットボックスは別で開発してみる。
皆様ありがとうございます。
返信遅くなりすみません。
秀丸に10万行ペーストすると、2,3秒で表示され、カーソルはペーストされた箇所の後ろ
に着ますが、その直後からスクロールも行ジャンプも可能で、処理がつんのめるというこ
とも見当たらないので、全て表示しているように少なくとも見かけ上は見えます。
メモ帳というチープなアプリでも同様なのにはびっくりしました。
CEdit::SetWindowText() ではやはりだめ、自前のクラスを作るしかないということですね。
現状、ダイアログベースで作っていますが、CEditView を派生させたクラスの OnPaint
か、OnDraw をオーバーライドする方向で考えてます。
エディットボックスを自作し、それをダイアログにのっける方法はちょっと調べてみて、
解らなければ別スレッドで質問します。
CEditView はだめよ。
CEditが埋め込まれているだけだから、OnDrawなんか飛んでこない。
CView から作って、スクロールやら編集機能やら必要なもの全部作るべし。
> 秀丸に10万行ペーストすると、2,3秒で表示され、カーソルはペーストされた
> 箇所の後ろに着ますが、その直後からスクロールも行ジャンプも可能で、処理が
> つんのめるということも見当たらないので、全て表示しているように少なくとも
> 見かけ上は見えます。
あくまでも見かけ上であって10万行も書き込んでないと思います。
「スクロールも行ジャンプも可能」になるようにメモリーに書き込むときにフラグ等
で状況を記憶しておくのだと思います。
10万行をどうやって速くCEditに書き込むかを考えるより、スクロール等の要求
に対していかに速く1画面分のデータを10万行分のデータから拾い出して表示するか
を考えることだと思います。
秀丸等の有名なエディタはそこのところが優れているのだと思います。
表示が速いわけではないと思います。
>> メモ帳というチープなアプリでも同様なのにはびっくりしました。
メモ帳はチープなアプリじゃないよ!
メモ帳って標準エディットコントロールを利用しているから
CEditとメモ帳の比較は
標準エディットコントロールと標準エディットコントロールの比較していることになり
意味ないだろ。憶測だけど。
俺も標準エディットコントロールの遅さが気になっているが
自分でエディットコントロールを作る実力はない。
作って一般公開してみたい。
他のテキストエディタは高速化のために行単位にメモリ確保するとかしているけど
(動作などからの推測だけど)エディットコントロールは速くするための工夫はやってな
いらしいからな。
> 俺も標準エディットコントロールの遅さが気になっているが
> 自分でエディットコントロールを作る実力はない。
> 作って一般公開してみたい。
codeguruやcodeprojectで既に公開されているかもしれませんね。
う~む。
ダイアログベースで、EditBox を自作するか、SDI で CView から派生するかはともか
く、文字データを行ごとのバッファで持っておいて、スクロールされたときに1画面分表
示するしかないみたいですねぇ。行ジャンプは、Ctrl-HOME と Ctrl-End しか対応する予
定はないので、スクロールとその2つだけやればいいけど。
SetWindowText だと一旦表示してしまうと、描いたものをアプリが忘れてしまっても、そ
の後に正しく動いてくれますが、描いた後も、行毎の文字バッファを捨てられないのだ
なぁ。しかも10万行も(苦笑)。
まぁ、EditBox を自作するにせよ、CView から派生するにせよ、やることは同じでしょう
から頑張ってみます。
回答を持っていない書き込みですいません。
>>EditBox を自作するか
これ、もう先人の方々がフリーソースで公開とかしてるのではないでしょうか。
ここの方なら存在を知ってるのでは?、と思い書き込みました:)