ScrollBoxのPositionの最大値

解決


ちひろ  2013-02-23 05:22:31  No: 43935

こんばんは。

ScrollBoxのPositionの最大値はどのように決まるのでしょうか?

例えば、ScrollBox(横300縦300)にImage(横600縦600)を貼り付け、
スクロールさせると、縦横ともPositionは321までしか行きません。

これはスクロールバーの幅が21ピクセルなので、そうなるようですが、
この「21」はどこから来ますか?
計算等で求められるのか、それとも固定値なのか知りたいです。
よろしくお願いします。


けど  2013-02-23 06:29:01  No: 43936

GetSystemMetrics(SM_CXHTHUMB)
GetSystemMetrics(SM_CYVTHUMB)とか
GetSystemMetrics(SM_CXVSCROLL);
だとおもうけどこれだと数値は17
昔調べた気がするけど思い出せない
もしかしたら GetSystemMetrics(SM_CXEDGE)*2 を足した分が21かな
詳細は http://msdn.microsoft.com/ja-jp/library/cc429812.aspx で

ちなみに 600-300 だから「321までしか」ではなく「300なのに21余分に動く?」だと思う


Mr.XRAY  2013-02-23 06:50:23  No: 43937

こんにちは.

どういう動作仕様にしたいのか,環境もわかりませんが,
TScrollBox というのは,そこに配置したコントロールが見えるまでの位置まで
スクロールする仕様です.
だって,縦が 600 ドットのコントロールを配置したのに,
永遠にスクロールしてしまうと,ちょっと問題が.

もちろん,逆の考え方もあります.
どこまでもスクロールする仕様なので,スクロールを止める位置は,
プログラマーが制御して下さい.とかですね.

その,えっと,「321までしか行きません」ということですが,
TImage の画像が欠けて表示されてしまうんですか ?


tor  2013-02-23 07:15:41  No: 43938

「どうやって計算するか」という点について言えば
スクロールバー(や枠などの装飾)を除いた領域のサイズはClientWidth, ClientHeightでとれるのでそこから計算できます。


Mr.XRAY  2013-02-23 07:54:10  No: 43939

>TScrollBox というのは,そこに配置したコントロールが見えるまでの位置まで
>スクロールする仕様です.

デフォルトではです.Range プロパティがありますから,いくらでも (上限はありますが)
設定できます.

>スクロールさせると、縦横ともPositionは321までしか行きません。

と書いてあるので,もしかしたら,もう少しスクロールさせたいのかと思ったのですが.

>計算等で求められるのか、それとも固定値なのか知りたいです。

やっぱり,こちらが主題かな ?


ちひろ  2013-02-23 19:13:56  No: 43940

みなさま、ありがとうございます。

すみません。
>縦横ともPositionは321までしか行きません
というのは表現が間違っていました。
私が当初「600までいく」と勘違いしてたので…。
600までいかない理由は理解できましたので、
この部分は無視してください。

それで原点に戻りまして、
最初「21を知る方法を知りたい」と書きましたが、
今のところやりたいのは、スクロールバーがスクロールされた時に、
それが一番フチまで来たことを検知したいのです。

しかし色々と先を考えますと、何らかの方法でバーの幅を知ることが
出来れば一番良いかな、と思っています。

いま、思いついたのは、一旦、ダミーでPositionに600を代入して、
その後にPositionを取得すれば321が得られるかなぁ…、と考えてますが、
スマートでないですね。
何か良い方法があれば・・・。


助監督  2013-02-23 23:46:49  No: 43941

ん?
Positionの最大値はtorさんの言う通り、ClientWidthとClientHeightで計算すれば出るんじゃ?

function HorzPositionMax(ScrWinCtrl: TScrollingWinControl): Integer;
begin
  Result := ScrWinCtrl.HorzScrollBar.Range - ScrWinCtrl.ClientWidth;
end;

function VertPositionMax(ScrWinCtrl: TScrollingWinControl): Integer;
begin
  Result := ScrWinCtrl.VertScrollBar.Range - ScrWinCtrl.ClientHeight;
end;

それより、、、こっちの方が手軽には出来ないような気が。。。。
>スクロールバーがスクロールされた時に

TScrollBar.OnChangeやOnScroll的なものが当然あると思ってたのに、何も無いとは。
困った時のApplication.OnIdleでなんとかするしかなさそう。
ユーザーによってスクロールされた場合は基本的に放置という方針でしょうかね。


ちひろ  2013-02-24 00:30:40  No: 43942

>助監督さん

ClientWidthとClientHeight が使えるのですね。
プロパティの画面で出てこなかったので無いと思っていました。

それで、スクロールバーの幅を計算しようと、
ScrollBox1.Width - ScrollBox1.ClientWidth
としてみたところ、答えは何故か 19 でした。

スマートで無い方法ですと、
ScrollBox1.HorzScrollBar.Position := Image1.Width;
ScrollBox1.VertScrollBar.Position := Image1.Height;
iScBarW := ScrollBox1.HorzScrollBar.Position -
                  (Image1.Width - ScrollBox1.Width) ;
iScBarH := ScrollBox1.VertScrollBar.Position -
                  (Image1.Height - ScrollBox1.Height) ;
これで答えは21です。

なぜか違いが出てしまいます。
良くわかりません。

>スクロールバーがスクロールされた時に
検索してみたところ出てきたので、こちらは何とかなりそうに思います。

ありがとうございました。


助監督  2013-02-24 01:47:37  No: 43943

>スマートで無い方法ですと
それだとScrollBox1の構成要素とは関係のないImage1の大きさに結果が左右されちゃうのでは。
Image1のサイズと、ScrollBox1の仮想サイズが同じであることが暗黙の前提になってませんか。

つまり、
Image1.WidthとScrollBox1.HorzScrollBar.Range、または
Image1.HeightとScrollBox1.VertScrollBar.Range が一致してないのではありませんか?

ScrollBox1の中に何を入れようと結局はRangeこそがすべてで、それがPositionに影響するかと。


ちひろ  2013-02-24 05:16:35  No: 43944

>助監督さん
そうですね、、、。
なので、スクロールバーの幅を算出するためだけに、
別途、ScrollBoxとimageを配置しました。見えない位置に。
あぁかっこわるい・・・。


Mr.XRAY  2013-02-24 22:01:43  No: 43945

問題の解決策とかではないのですが,後学のために.

>ScrollBox1.Width - ScrollBox1.ClientWidth
>としてみたところ、答えは何故か 19 でした。

と書いていますが,以下のようなコードで確認したと思うのですが.
この値となった環境を教えていただけますか ?

procedure TForm1.Button1Click(Sender: TObject);
var
  V : Integer;
begin
  V := ScrollBox1.Height - ScrollBox1.ClientHeight;
  ShowMessage(IntToStr(V));
end;


けど  2013-02-25 05:59:43  No: 43946

21ですよねー
ScrollBoxに何も入っていない時の差は4だから↑の幅19を足した分がこの数値ですよね
なんで19になったんでしょう?


Mr.XRAY  2013-02-25 08:05:11  No: 43947

>21ですよねー
>ScrollBoxに何も入っていない時の差は4だから↑の幅19を足した分がこの数値ですよね
>なんで19になったんでしょう?

ほぼ予想はついているんですけどね (^^;
本人に確認したいことがあるんです.
また,本人が気付かないことには.

興味があればですが,私のサイトのどこかにヒントの記事がありますです.ハイ.
http://mrxray.on.coocan.jp/index.htm


ちひろ  2013-02-25 18:42:08  No: 43948

>Mr.XRAYさん  , けどさん

ScrollBox1.Ctrl3D がFalseとTrueで違いがでていました。
元の方がFalse、かっこわるい方がTrue(=Default)でした。

Mr.XRAYさん
とっても助かりました。
ありがとうございました。


Mr.XRAY  2013-02-25 19:52:43  No: 43949

あれっ !?
記事を見たということですか ?
実は,あの記事の内容は,全て

[第3章 コントロールのメッセージ処理(その2)]
http://mrxray.on.coocan.jp/Halbow/VCL03.html

に書いてあります.
ところで,他に何か書くことはないのでしょうか ?  
私,環境を訊いたんですが.無視されちゃたみたいですね.
いいんですよ,わたしゃ,そうやって,寂しい,悲しい人生を送ってきたのですから.

[解決] ということですが,結局,私には,何をどうしたいのか理解できませんでした.


ちひろ  2013-02-25 21:49:23  No: 43950

Mr.XRAYさん、すっ、すみません(>_<)

>>21が19
について再考の機会を頂いて、原因がわかったために、
聞かれたこととや書くべき事とかすっかり忘れていました。

→環境はXE3(Win7-64)でした。

>>スクロールバーがスクロールされた時に

>検索してみたところ出てきたので、こちらは何とかなりそうに思います。
と書きましたが、これもきちんと結果を報告すべきでした。

https://www.petitmonte.com/bbs/answers?question_id=7847
  を参考にさせて頂いて、できました。

この度はありがとうございました。


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

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






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