« スクロールバーあれこれ | トップページ | 時間のかかる処理のタイムアウト »

2007年1月12日 (金)

スクロールバーあれこれの続き

前回、ScrollBar関係のAPIを使って制御する時、毎回、頭を痛めると書いたが、表現が適切じゃなかった。ただ自分が使い方を誤解していたのである。で、初めて使う人にやりがちな決め方(自分だけかも知れない)を書いてみる。というか、非常にかったるい話です。

テキストをM行表示する場合を考えてみよう。この時、ウィンドウのクライアント領域の高さの制限からN(N<=M)行しか表示できないとする。まず、範囲(nMinとnMax)を決めると思うので範囲を決めてみる。(M-N)行表示されていない部分があるので、(M-N)+1通りの状態を表せればよいので、例えば、nMin=0、nMax=M-Nとする。で、これで位置についてはよさそうなので、次はページを決めてみる。この場合、全体M行のうちN行つまりページサイズが全体のN/Mになればよいので、nPage=全体*N/M=(M-N + 1)*N/Mでいいかなと・・

つまり、この場合、

  • nMin=0
  • nMax=M-N
  • nPage=(M-N + 1)*N/M

になる。で、具体的に、10行(M=10)表示するとしてクライアント領域に5行(N=5)しか表示できないとして、代入してみると、

  • nMin = 0
  • nMax = 5
  • nPage =3

となり、ちょうど、ページサイズが3と全体6(=5-0+1)の半分になっていて、これでいいのかななんて考える。で、今度はM=10、N=6としてみると、うぉ。nPageの型が整数なんだけど、整数にならない。切り捨て・切り上げても問題ないのかなぁ・・・と。こうやって、ドツボにはまったのである。

そもそも使い方が間違っていて、範囲の決め方が問題なのである。様々なサイトを見ると、nMinとnMaxにスクロール範囲を指定すればよいなどと書かれているが、語弊があるかもしれないが、表示したい内容全体の量を*範囲*で指定するのである。この場合、M行表示したいので、nMin=0とすれば、nMax=M-1(nMin=1とすれば、nMax=10、nMin=5とすれば、nMax=14・・・どの場合も、nMax - nMin + 1=M=一定)でいいのである。でページサイズには、実際に表示できる量つまりこの場合N行なので、nPage=Nになる。つまり、

  • nMin=0
  • nMax=M - 1
  • nPage=N

でいいのである。で、先ほどど同じように、M=10、N=5としてみると

  • nMin=0
  • nMax=9
  • nPage=5

になる。でポイントはここからだ。この場合実際表示されていない行は5行なのに、nMin=0、nMax=9だから、サムの位置が0から9と変化できて問題あるんじゃ?と思うだろう。だが、実際、SetScrollInfoやSetScrollPosでサムの位置だけを変えてあげると、0から5までしか移動できないのである。つまり、サムが取れる位置はページサイズの影響をうけるのだ。サムの位置の最大値=nMaxではなく

サムの位置の最大値=(nMax - nMin + 1) - nPageになる。

これを理解して初めて、SCROLLINFO構造体のnMin、nMax、nPosそしてnPageに何を設定すればいいか理解できた。ちなみに、今回の例では行単位で考えたが、ピクセル単位で考えても同じことが言える。疲れた。

« スクロールバーあれこれ | トップページ | 時間のかかる処理のタイムアウト »

Windows」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1497665/39651888

この記事へのトラックバック一覧です: スクロールバーあれこれの続き:

« スクロールバーあれこれ | トップページ | 時間のかかる処理のタイムアウト »

自作ソフトウェア

無料ブログはココログ

メモ