スクロールバーの実装は過去にやったことがありますが、パッと見簡単そうな割に
その実けっこう面倒だったと記憶しています。
(スクロールバーに対するアクションそれぞれについて記述しなければならない、
スクロールもバーの位置変更も自分で行わなければならない、等)
ついでにマウスホイールやキーボードでの操作にも対応してみました。
#include "user32.as"
dim scrinfo,7 //SCROLLINFO構造体
win_th=30000 //ウィンドウ全体の高さ
win_vh=800 //ウィンドウのうち表示される高さ
scr_line=100 //行単位スクロールした時のスクロール量
scr_page=600 //ページ単位スクロールした時のスクロール量
GetSystemMetrics 2 //SM_CXVSCROLL=2 縦スクロールバーの横幅を取得
screen 0,300+stat,win_th,,,,300+stat,win_vh //スクロールバーの幅の分だけ横幅を余分に確保
GetWindowLong hwnd,-16
SetWindowLong hwnd,-16,stat|0x00200000 //WS_VSCROLL=0x00200000 縦スクロールバーを追加
//画面描画
repeat 1000
pos 0,cnt*30
mes "aiueo"+cnt
loop
scr_pos=0 //スクロール位置
gosub *set_scr
//↓これをやらないとスクロールバーが表示されない
SetWindowPos hwnd,0,0,0,0,0,0x37 //SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_FRAMECHANGED=0x37
oncmd gosub *scr,0x115 //WM_VSCROLL 縦スクロールバーを操作したときの割り込み
wheel_pos=0 //マウスホイールスクロール量の累積
oncmd gosub *wheel,0x20A //WM_MOUSEWHEEL マウスホイールによるスクロールが不要の場合は削除してください
onkey gosub *key //キー入力 キーボードによるスクロールが不要の場合は削除してください
stop
*set_scr
//scr_posの値に合わせて画面をスクロールさせ、スクロールバーに反映させる
groll 0,scr_pos
scrinfo=28,0x1F,0,win_th,win_vh,scr_pos,0 //SIF_ALL|SIF_DISABLENOSCROLL=0x1F
SetScrollInfo hwnd,1,varptr(scrinfo),1 //SB_VERT=1
return
*scr
//スクロールバーを操作
scr_pos0=scr_pos
hi=(wparam>>16)&0xFFFF : lo=wparam&0xFFFF
switch lo
case 0 //SB_LINEUP(1行上へ)
scr_pos-=scr_line : swbreak
case 1 //SB_LINEDOWN(1行下へ)
scr_pos+=scr_line : swbreak
case 2 //SB_PAGEUP(1ページ上へ)
scr_pos-=scr_page : swbreak
case 3 //SB_PAGEDOWN(1ページ下へ)
scr_pos+=scr_page : swbreak
case 5 //SB_THUMBTRACK(スクロールバーをドラッグ)
scr_pos=hi : swbreak
case 6 //SB_TOP(一番上へ)
scr_pos=0 : swbreak
case 7 //SB_BOTTOM(一番下へ)
scr_pos=win_th-win_vh : swbreak
swend
scr_pos=limit(scr_pos,0,win_th-win_vh)
if scr_pos!=scr_pos0 : gosub *set_scr
return
*wheel //マウスホイールによるスクロールが不要の場合はreturnまで削除してください
scr_pos0=scr_pos
wheel_pos+=wparam>>16 //上位ワードは符号付き16ビット整数なので、そのまま算術シフト
repeat
if wheel_pos>=120 : scr_pos-=scr_line : wheel_pos-=120 : continue //ホイールを上に回した場合
if wheel_pos<=-120 : scr_pos+=scr_line : wheel_pos+=120 : continue //ホイールを下に回した場合
break
loop
scr_pos=limit(scr_pos,0,win_th-win_vh)
if scr_pos!=scr_pos0 : gosub *set_scr
return
*key //キーボードによるスクロールが不要の場合はreturnまで削除してください
scr_pos0=scr_pos
switch wparam
case 33 //PageUp
scr_pos-=scr_page : swbreak
case 34 //PageDown
scr_pos+=scr_page : swbreak
case 35 //End
scr_pos=win_th-win_vh : swbreak
case 36 //Home
scr_pos=0 : swbreak
case 38 //↑
scr_pos-=scr_line : swbreak
case 40 //↓
scr_pos+=scr_line : swbreak
swend
scr_pos=limit(scr_pos,0,win_th-win_vh)
if scr_pos!=scr_pos0 : gosub *set_scr
return