こんばんは。
ScrollBoxのPositionの最大値はどのように決まるのでしょうか?
例えば、ScrollBox(横300縦300)にImage(横600縦600)を貼り付け、
スクロールさせると、縦横ともPositionは321までしか行きません。
これはスクロールバーの幅が21ピクセルなので、そうなるようですが、
この「21」はどこから来ますか?
計算等で求められるのか、それとも固定値なのか知りたいです。
よろしくお願いします。
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余分に動く?」だと思う
こんにちは.
どういう動作仕様にしたいのか,環境もわかりませんが,
TScrollBox というのは,そこに配置したコントロールが見えるまでの位置まで
スクロールする仕様です.
だって,縦が 600 ドットのコントロールを配置したのに,
永遠にスクロールしてしまうと,ちょっと問題が.
もちろん,逆の考え方もあります.
どこまでもスクロールする仕様なので,スクロールを止める位置は,
プログラマーが制御して下さい.とかですね.
その,えっと,「321までしか行きません」ということですが,
TImage の画像が欠けて表示されてしまうんですか ?
「どうやって計算するか」という点について言えば
スクロールバー(や枠などの装飾)を除いた領域のサイズはClientWidth, ClientHeightでとれるのでそこから計算できます。
>TScrollBox というのは,そこに配置したコントロールが見えるまでの位置まで
>スクロールする仕様です.
デフォルトではです.Range プロパティがありますから,いくらでも (上限はありますが)
設定できます.
>スクロールさせると、縦横ともPositionは321までしか行きません。
と書いてあるので,もしかしたら,もう少しスクロールさせたいのかと思ったのですが.
>計算等で求められるのか、それとも固定値なのか知りたいです。
やっぱり,こちらが主題かな ?
みなさま、ありがとうございます。
すみません。
>縦横ともPositionは321までしか行きません
というのは表現が間違っていました。
私が当初「600までいく」と勘違いしてたので…。
600までいかない理由は理解できましたので、
この部分は無視してください。
それで原点に戻りまして、
最初「21を知る方法を知りたい」と書きましたが、
今のところやりたいのは、スクロールバーがスクロールされた時に、
それが一番フチまで来たことを検知したいのです。
しかし色々と先を考えますと、何らかの方法でバーの幅を知ることが
出来れば一番良いかな、と思っています。
いま、思いついたのは、一旦、ダミーでPositionに600を代入して、
その後にPositionを取得すれば321が得られるかなぁ…、と考えてますが、
スマートでないですね。
何か良い方法があれば・・・。
ん?
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でなんとかするしかなさそう。
ユーザーによってスクロールされた場合は基本的に放置という方針でしょうかね。
>助監督さん
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です。
なぜか違いが出てしまいます。
良くわかりません。
>スクロールバーがスクロールされた時に
検索してみたところ出てきたので、こちらは何とかなりそうに思います。
ありがとうございました。
>スマートで無い方法ですと
それだとScrollBox1の構成要素とは関係のないImage1の大きさに結果が左右されちゃうのでは。
Image1のサイズと、ScrollBox1の仮想サイズが同じであることが暗黙の前提になってませんか。
つまり、
Image1.WidthとScrollBox1.HorzScrollBar.Range、または
Image1.HeightとScrollBox1.VertScrollBar.Range が一致してないのではありませんか?
ScrollBox1の中に何を入れようと結局はRangeこそがすべてで、それがPositionに影響するかと。
>助監督さん
そうですね、、、。
なので、スクロールバーの幅を算出するためだけに、
別途、ScrollBoxとimageを配置しました。見えない位置に。
あぁかっこわるい・・・。
問題の解決策とかではないのですが,後学のために.
>ScrollBox1.Width - ScrollBox1.ClientWidth
>としてみたところ、答えは何故か 19 でした。
と書いていますが,以下のようなコードで確認したと思うのですが.
この値となった環境を教えていただけますか ?
procedure TForm1.Button1Click(Sender: TObject);
var
V : Integer;
begin
V := ScrollBox1.Height - ScrollBox1.ClientHeight;
ShowMessage(IntToStr(V));
end;
21ですよねー
ScrollBoxに何も入っていない時の差は4だから↑の幅19を足した分がこの数値ですよね
なんで19になったんでしょう?
>21ですよねー
>ScrollBoxに何も入っていない時の差は4だから↑の幅19を足した分がこの数値ですよね
>なんで19になったんでしょう?
ほぼ予想はついているんですけどね (^^;
本人に確認したいことがあるんです.
また,本人が気付かないことには.
興味があればですが,私のサイトのどこかにヒントの記事がありますです.ハイ.
http://mrxray.on.coocan.jp/index.htm
>Mr.XRAYさん , けどさん
ScrollBox1.Ctrl3D がFalseとTrueで違いがでていました。
元の方がFalse、かっこわるい方がTrue(=Default)でした。
Mr.XRAYさん
とっても助かりました。
ありがとうございました。
あれっ !?
記事を見たということですか ?
実は,あの記事の内容は,全て
[第3章 コントロールのメッセージ処理(その2)]
http://mrxray.on.coocan.jp/Halbow/VCL03.html
に書いてあります.
ところで,他に何か書くことはないのでしょうか ?
私,環境を訊いたんですが.無視されちゃたみたいですね.
いいんですよ,わたしゃ,そうやって,寂しい,悲しい人生を送ってきたのですから.
[解決] ということですが,結局,私には,何をどうしたいのか理解できませんでした.
Mr.XRAYさん、すっ、すみません(>_<)
>>21が19
について再考の機会を頂いて、原因がわかったために、
聞かれたこととや書くべき事とかすっかり忘れていました。
→環境はXE3(Win7-64)でした。
>>スクロールバーがスクロールされた時に
は
>検索してみたところ出てきたので、こちらは何とかなりそうに思います。
と書きましたが、これもきちんと結果を報告すべきでした。
→https://www.petitmonte.com/bbs/answers?question_id=7847
を参考にさせて頂いて、できました。
この度はありがとうございました。
ツイート | ![]() |