TStringGridでスクロールバーの「つまみ」の幅を調整するには?


moon  2003-06-16 10:00:28  No: 3762

Excelやなんかで見る、アレのようなカンジで、
垂直、水平、両方のスクロールバーのつまみの幅を
(見えてる量)/(全体の量)
で調整したいのです。

SetScrollInfo()
などのAPI関数を使えばイケると思うのですが、
NET上に転がってるサンプルはほとんど垂直スクロールバーのみで、
水平までは扱ってくれません。

んで、垂直の方も、VisibleRowCountを利用しているものが
ほとんどで、行の高さというのはあまり変えないので
それでも構わないのですが、列の幅は静的に、動的に、
変わることが多いので、困っています。

水平・垂直両方のスクロールバーのつまみの幅を変える方法、
もしくは、そんな動作を実現しているコンポーネントなど、
ご存知ないでしょうか?

よろしくご教授お願いします。


にしの  2003-06-17 07:25:07  No: 3763

縦でも横でも同じ方法だからないのだと思います。
SetScrollInfoのAPIをよく見れば、わかりますよ。

第2引数に、SB_HORZを入れれば水平スクロールバー、SB_VERTを入れれば垂直スクロールバーです。

http://halbow.cool.ne.jp/Chap14.html
このあたりも参考になるかと。


moon  2003-06-18 03:43:58  No: 3764

レスありがとうございます。

> 第2引数に、SB_HORZを入れれば水平スクロールバー、
> SB_VERTを入れれば垂直スクロールバーです。

…ハイ。一応そのへんもいじってはいるんですが…。

var
  si_v,si_h: TScrollInfo;
const
  max = 127;
begin
///vertical
  SendMessage(S_grid.Handle,WM_VSCROLL,MAKEWPARAM(SB_TOP,0),0);
  si_v.cbSize := SizeOf(TScrollInfo);
  si_v.fMask := SIF_RANGE or SIF_PAGE;
  si_v.nPage := (max*S_grid.VisibleRowCount) div (S_grid.RowCount-S_grid.VisibleRowCount);
  si_v.nMin := 0;
  si_v.nMax := max + si_v.nPage-1;
  SetScrollInfo(S_grid.Handle,SB_VERT,si_v,True);

///horizontal
  SendMessage(S_grid.Handle,WM_HSCROLL,MAKEWPARAM(SB_TOP,0),0);
  si_h.cbSize := SizeOf(TScrollInfo);
  si_h.fMask := SIF_RANGE or SIF_PAGE;
  si_h.nPage := (max*S_grid.VisibleColCount) div (S_grid.ColCount-S_grid.VisibleColCount);
  si_h.nMin  := 0;
  si_h.nMax  := max + si_h.nPage-1;
  SetScrollInfo(S_grid.Handle,SB_HORZ,si_h,True);

end;

…というようなメソッドを作ったことがあり、
実行直後にコレを呼び出せばうまくいくんです。
が、フォームをリサイズするとスクロールバーが消えるんですよね。
フォームのリサイズイベントを拾って、
これを実行しても、現象はかわらず。

このコードも正しいのかどうか良く分かってません。
まさにhalbowさんという方がdelphiMLで投稿してらした
ヤツを水平用に少し書き足しただけなので。


にしの  2003-06-18 20:09:14  No: 3765

このソースだと、スクロールバーが消えたときにエラーになりますよ。0除算しますから。
それ以外に問題点は見つかりませんでした。
# うちの環境ではうまく動きました

ソースを見る限り、わかっておられると思いますが、DelphiではスクロールのuMaxは127固定です。
これにあうように、ページサイズを指定すればOKのはずです。
127固定と言うことは、128以上のColCount,RowCountを指定したときに、スクロールバーを1つ移動させても、つまみ部分は移動しません。
これを変更するには、TCustomGridのUpdateScrollRangeあたりをオーバーライドしてやる必要がありそうです。
やってみようかとも思いましたが、ちょっと複雑なことをしていて、TDrawGridを1つ作り直すのと同じ手間がかかりそうなのでやめました。

やり方は合っていると思います。
nMaxは127固定として考え、その中でnPageの大きさを決定するようにしてみてください。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加