たった一つの冴えないスクロールバー
今回はスクロールバーについて考えてみます。
スクロールバーはスクロールバーだって?
いえいえ、ここに取り出したるスクロールバーはだだのスクロールバーではありません。
前回巨大ファイルの読み込みを検証した際に、何が問題になったかといえば、巨大ファイルに普通のスクロールバーでは対応できない! ということです。
どういうことかといえば、スクロールバーというのはWindowsの標準機能で、なにか操作すると「WM_VSCROLL」メッセージとかが飛んできます。
で、スクロールした場合は「WPARAM wParam」にそのスクロールした位置の情報が入ってくるんですが、wParamは32ビット環境では当然ながら32ビットしか無い。
つまり、4Gバイト以上のファイルは、1バイト単位でスクロールできないんです!
な、なんだってー!
たとえこれが行単位だとしても、LFとかだと最低1行1バイトなんで同じこと。
まあ、バッファへの読込み単位は512kバイトなんで、ファイルサイズを512kバイトで割った単位でバッファに読み込めばいいんですが、実際のスクロール位置は行頭までスキップした位置になるので、内部バッファが示す開始位置と、スクロールバーの示す位置が違ってきます。
またスクロールバーを動かすときはともかく、キーボード操作でスクロールしていった場合は、内部バッファの次の領域を読込み、いらない部分を消していかなければなりません。
ずっとためっぱなしだと内部バッファが溢れてしまいますからね。
こんなことをすると、内部バッファの先頭アドレスとスクロールバーの値がどんどんズレていくわけで、そのズレを何らかの方法で補正する必要があります。
なのでスクロールバーには現在ポイントしている値と同値を突っ込みたいけど、残念なことに32ビットしか無いので無理。
え?
素直に64ビット環境でコンパイルしろって?
いや、自分も考えたんですよそれは。
駄菓子菓子、AliceBuilderは元々の設計も実装も古く、もうあちこち32ビットにどっぷり浸かっているわけですよ。
コンパイラのデフォルトがAnisStringからUnicodeStringに変わっとときも死ぬ思いして直したのに、もう嫌でござる。
なんにも機能が変わってないのに手を入れるなんて無駄の極み。
小さなソフト屋さんがイケないのかUNICODEの団体がイケないのか、Windowsの内部コードをUNICODEに変えるもんだから、コンパイラも追従することになりもう大変なことに。
そのうえ64ビット化とかやってられっかーべらぼーめー。
一応なんとか64ビット化しようとは思ったんですよ?
しかし真っ先にasmは使えんぞボケ! おととい来やがれ!!
とか言われて、そっと環境を32ビットに戻しましたw
すっごく苦労してインラインアセンブラ書いたのにそれを捨てろと?
いや、当時とは違って今はCPUも速いから、アセンブラなんて使わなくてもいいってわかるよ?
しかしあのインテルアセンブラのワケワカメさに泣きながら書いたのにw
せめてZ80かモトローラのアセンブル言語並みにわかりやすくできなかったものかね?
アセンブル言語というより元々のCPUの設計が悪かったせいか?
アセンブラで書いてるのグラフィック部分だから、消すと画面表示が一部できなくなるし、作り直すのもめんどくさい。
ということでスクロールバーの方を作り直すことにしました!
どっちが面倒かは評価が分かれるところですが、自作のスクロールバーなら色々仕込めるのでまあいいかなと。
今回巨大ファイルエディタを作るに当たって、どうしてもやりたかったのは縦スクロールバーをRPGのボス体力ゲージのように2本にすることw
2刀流ですねw
なんでかといえば、前にも書いた通り、スクロールバーが1本しか無いと、ちょっと動かしただけで、何千行何万行とかスクロールするわけで、数行単位でスクロールさせるには、このままではキーボードで操作する以外方法がありません。
そこでもう一本のスクロールバーの出番です。
この追加したスクロールバーは、内部バッファのスクロール用として使用します。
というか内部バッファ用のスクロールバーが本来のスクロールバーの本来の役割であって、巨大ファイル用のスクロールバーではありません。
それが、普通のエディタでは共用しているので、細かいスクロールはできなくなってしまうのです。
しかしそれでは「巨大ファイルを快適に編集」と言うことはできません。
ストレスなしにスクロールできる、というのは絶対条件なのです。
巨大ファイルの一部だけを読み込む機能とかあるエディタもありますが、それを常時出している感じでしょうか?
というわけでスクロールバーを自作します。
まあ、1から作ると大変なのですが、こんな事もあろうかと!w、当時System3.x用にAliceBuilderと共にSystemAliceとAliceDesignEditorという、C++BuilderのVCLに似たライブラリ群とデザインエディタを作っていました。
パネルやボタン、チェックボックス、ラベル、トラックバーなどを、デザイナーで貼り付けるだけで、設定データを作ってくれて、プロパティやメソッド、イベント等も設定できる優れもの(自画自賛w)。
今回はその中のトラックバーを利用します。
本来トラックバーはスライダー、つまりボリュームのようなものに使うコントロールです。
とはいえ、スクロールバーもトラックバーも変化量をユーザーが操作するものなので、流用が可能です。
というか外観と機能はほぼスクロールバーと変わらないので、流用したとしても早々違和感はないでしょう、ということで採用です。
まあ、このトラックバーコントロールも、ポジション指定は32ビットなので64ビット変数に変更する必要があるでしょう。
全体を64ビット化するよりは簡単なので、問題はありませんが。
実用上は64ビット変数を使う1本だけを自作に切り替えればいいのですが、見た目が多少違うので、縦スクロールバー2本と横スクロールバーも一緒に変えてしまいます。
やっぱりデザインに統一性がないとね。
また、なにかスクロールバーに機能を追加したい場合も、自作のものなら容易ですからね。
なにせ、初めての試みなので何がストッパーになるかわからない。
変更できない機能をなんとかしようとするより、自作のプログラムをいじったほうがよっぽど早いし。
AliceBuilderを作ったときも標準コントロールに泣かされたからなぁ。
便利だけど融通が利かないっていうか。
まるでお役所仕事w
c++builderにはたくさんの標準機能とは別にコンポーネントがインストールできるんですが、これも新バージョンになったら対応してないとかなった場合、どうにもできなくなるので、便利とは思うのですが、使ってなかったりします。
ソースコードも一緒についていればなんとかなるんですが、こういうコンポーネントの殆どがDelphi!
パスカルはMZ80時代にちょこっと書いたことがあるんですが、馴染めずに結局C言語へ。
ソースコードがついててもメンテナンスできないでござる。
使い捨てで一度作ったら二度と変更するつもりがないのであればそれでもいいのですが、あとから修正したくなることがないとも言えないので、標準以外の機能はなかなか使いづらいですね。
というわけでスクロールバー自作は決定です。




