スクロールバー モジュール

HSPでスクロールバーを使用するためのモジュールです。
スクロールバーは、主に領域外に情報があることを示しスライド操作することでその情報を領域内に移動し表示する目的で使用されます。

モジュールの概要

モジュールの使い方

下記のモジュールをスクリプトにコピペするだけで使用できます。
DLLやモジュールを別途用意する必要はありませんが、WindowsAPI(Win32API)を使用しますので環境に依存しています。
命令・関数名パラメータパラメータの説明
ScrollBar_Create int, int, int, int, int, int, int, int, int
スクロールバーを配置する
カレント位置にスクロールバーオブジェクトを配置します。
ウィンドウメッセージWM_HSCROLL($0114),WM_VSCROLL($0115)はモジュール内で処理します。
int
n [pixel] (オブジェクトの横幅)
int
n [pixel] (オブジェクトの縦幅)
int
0 (横方向スクロールバー)
1 (縦方向スクロールバー)
int
n (最低値、スクロールしていないときの値)
int
n (最大値、最後までスクロールしたときの値)
int
n (つまみの大きさ)
int
n (つまみの初期位置)
int
n (移動量、矢印部分の操作)
int
n (移動量、空白部分の操作)
(stat)
n (HSPオブジェクトID)
ScrollBar_SetRange int, int, int, int
スクロールバーオブジェクトの範囲を変更する
int
n (対象のオブジェクトID)
int
n (最低値、スクロールしていないときの値)
int
n (最大値、最後までスクロールしたときの値)
int
n (つまみの大きさ)
ScrollBar_SetStep int, int, int
操作時の移動量を変更する
int
n (対象のオブジェクトID)
int
n (移動量、矢印部分の操作)
int
n (移動量、空白部分の操作)
val = ScrollBar_GetPos( int )
スクロールバーの示す現在位置を取得する関数
int
n (対象のオブジェクトID)
stat
n (現在位置)
ScrollBar_SetPos int, int
スクロールバーの示す現在位置を変更する
int
n (対象のオブジェクトID)
int
n (新しい位置)
ScrollBar_SetSubLabel label
スクロールバー操作時の割り込み指定
ユーザーがスクロールバーを操作したときに割り込みを発生させます。
割り込みはサブルーチンジャンプですので必ずreturnしてください。
割り込みルーチン中はScrollBar_GetInfo関数を使用できます。
割り込みを行わない場合でもスクロールバーは動作します。
label
*label (ジャンプ先のラベル名)
(省略やラベル型以外は割り込み解除)
val = ScrollBar_GetInfo( int )
割り込み処理中の各種情報を取得する関数
ScrollBar_SetSubLabelで呼び出されたルーチン中のみ有効です。
int
0 (スクロールバーを持つウィンドウのIDを取得する)
1 (スクロールバーの形状を取得する)
3 (操作要因を取得する)
4 (オブジェクトハンドルを取得する)
stat
n (各値)
val = ScrollBar_GetSystemSize( )
システム設定のスクロールバーのサイズを取得する関数
普段Windowsで使用されるバーの厚さを取得します。
※厚さ:横スクロールバーなら高さ(Yサイズ)のこと。
stat
n [pixel]
パラメータの型は、int:数値、label:ラベル、stat:関数の返す値、(stat):実行後のシステム変数。

モジュール

/*====================================================================
          スクロールバーモジュール(ControlObjectModule2.1号)
HSP3.3β3       2011. 7.25  プロトタイプ作成
HSP3.3RC1             8. 1  モジュール化
HSP3.3          2012. 3.10  作成:ScrollBar_GetSystemSize
----------------------------------------------------------------------
スクロールバーを配置する
    ScrollBar_Create 横幅, 縦幅, flag, 最小値, 最大値, サイズ, 位置, 移動量A, 移動量B
        横幅・縦幅      コントロールの大きさ
        flag            0(横スク) or 1(たてスク)
        最少値・最大値  スクロールバーの値の範囲
        サイズ          バー(つまみ部分)の大きさ
        位置            バーの現在位置
        移動量A         矢印部分をクリックしたときのバーの移動量
        移動量B         空白部分(バーの前後)をクリックしたときのバーの移動量
        stat            HSPオブジェクトID(以降の操作で必要になる)

スクロールバーの範囲を指定する
    ScrollBar_SetRange オブジェクトID, 最小値, 最大値, サイズ

スクロールバーを操作したときの移動量を指定する
    ScrollBar_SetStep オブジェクトID, 矢印の移動量, ブランクの移動量

スクロールバーの現在の位置を取得する関数
    ScrollBar_GetPos( オブジェクトID )

スクロールバーの位置を指定する
    ScrollBar_SetPos オブジェクトID, 新しい位置

スクロール時割り込み実行指定(#defineで定義)
    ScrollBar_SetSubLabel ジャンプ先ラベル(*xxx)
        ユーザーがスクロールバーを操作した時にサブルーチンジャンプを実行する(return必須)
        ラベル省略で割り込み無効

スクロール割り込み時に情報を取得する関数
    ScrollBar_GetInfo( 種類 )
        種類    0(ウィンドウID) or 1(メッセージID) or 2(操作要因) or 3(temp) or 4(ObjHandle)
                メッセージID    $114(276)横スクロール or $115(277)縦スクロール
                操作要因        5のときtempに位置が入る

スクロールバーの大きさ(システム設定値)を取得する関数
    ScrollBar_GetSystemSize()

====================================================================*/
#ifndef ScrollBarModuleIncluded
#define ScrollBarModuleIncluded
#module ScrollBarModule
#uselib "user32.dll"    ;スクロールバー
#func SetScrollInfo     "SetScrollInfo" int, int, var, int
#func GetScrollInfo     "GetScrollInfo" int, int, var
#define WS_CHILD            $40000000
#define WS_VISIBLE          $10000000
#define SBS_HORZ            0
#define SBS_VERT            1
#define WM_HSCROLL          $0114
#define WM_VSCROLL          $0115

#define SB_CTL              2

#define SB_LINEUP           0
#define SB_LINELEFT         0
#define SB_LINEDOWN         1
#define SB_LINERIGHT        1
#define SB_PAGEUP           2
#define SB_PAGELEFT         2
#define SB_PAGEDOWN         3
#define SB_PAGERIGHT        3
#define SB_THUMBTRACK       5

#define SIF_RANGE           $0001
#define SIF_PAGE            $0002
#define SIF_POS             $0004
#define SIF_DISABLENOSCROLL $0008
#define SIF_TRACKPOS        $0010
#define SIF_ALL             (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)

#func GetWindowLong     "GetWindowLongA" int, int
#func SetWindowLong     "SetWindowLongA" int, int, int
#define GWL_USERDATA        -21     ;とりあえずここでいいや

#func GetSystemMetrics  "GetSystemMetrics" int  ;システムのいろいろ取得
#define SM_CXVSCROLL        2

#define global ScrollBar_SetSubLabel(%1=0) SbmLabel@ScrollBarModule=%1

#deffunc ScrollBar_Create int x, int y, int f, int n, int m, int s, int p, int a, int b, local i
    if f & 1  : ib(8) = SBS_VERT  : else  : ib(8) = SBS_HORZ
    winobj "SCROLLBAR", "", 0, WS_CHILD | WS_VISIBLE | ib(8), x, y, 0, 0  : i = stat
    ib = 7 * 4, SIF_ALL | SIF_DISABLENOSCROLL, n, m, s, p, 0
    SetScrollInfo objinfo(i, 2), SB_CTL, ib, 1
    if ib(8) == 0  : oncmd gosub *sbmGetMessageLabel, WM_HSCROLL
    if ib(8) == 1  : oncmd gosub *sbmGetMessageLabel, WM_VSCROLL
    ScrollBar_SetStep i, a, b
    return i

#deffunc ScrollBar_SetRange int i, int n, int m, int s
    ib = 7 * 4, SIF_ALL | SIF_DISABLENOSCROLL, 0, 0, 0, 0, 0
    GetScrollInfo objinfo(i, 2), SB_CTL, ib
    ib(2) = n, m, s
    SetScrollInfo objinfo(i, 2), SB_CTL, ib, 1
    return

#deffunc ScrollBar_SetStep int i, int a, int b
    SetWindowLong objinfo(i, 2), GWL_USERDATA, (a << 16 & $FFFF0000) | (b & $FFFF)
    return

#defcfunc ScrollBar_GetPos int i
    ib = 7 * 4, SIF_POS, 0, 0, 0, 0, 0
    GetScrollInfo objinfo(i, 2), SB_CTL, ib
    return ib(5)

#deffunc ScrollBar_SetPos int i, int p
    ib = 7 * 4, SIF_ALL | SIF_DISABLENOSCROLL, 0, 0, 0, 0, 0
    GetScrollInfo objinfo(i, 2), SB_CTL, ib
    ib(5) = p
    SetScrollInfo objinfo(i, 2), SB_CTL, ib, 1
    return

*sbmGetMessageLabel
    SBMI = ginfo_intid, iparam, wparam >> 16 & $FFFF, wparam & $FFFF, lparam
    if (0 <= SBMI(3) & SBMI(3) <= 3) | (SBMI(3) == 5) {
        ib = 7 * 4, SIF_ALL | SIF_DISABLENOSCROLL, 0, 0, 0, 0, 0, 0
        GetScrollInfo SBMI(4), SB_CTL, ib
        ib(7) = ib(5)       ;動いたチェック
        if SBMI(3) == 5 {
            ib(5) = ib(6)
        } else {
            GetWindowLong SBMI(4), GWL_USERDATA
            if SBMI(3) == 0  : ib(5) -= stat >> 16 & $FFFF
            if SBMI(3) == 1  : ib(5) += stat >> 16 & $FFFF
            if SBMI(3) == 2  : ib(5) -= stat       & $FFFF
            if SBMI(3) == 3  : ib(5) += stat       & $FFFF
        }
        SetScrollInfo SBMI(4), SB_CTL, ib, 1
        GetScrollInfo SBMI(4), SB_CTL, ib
        if vartype(SbmLabel) == 1 & ib(7) != ib(5) : gosub SbmLabel
    }
    return

#defcfunc ScrollBar_GetInfo int t
    return SBMI(t)

#defcfunc ScrollBar_GetSystemSize
    GetSystemMetrics SM_CXVSCROLL
    return stat

; http://www.tvg.ne.jp/menyukko/ ; Copyright(C) 2011-2012 衣日和 All rights reserved.
#global
#endif

サンプル

スクロールバーを設置・運用するためのサンプルです。上記モジュールに連結して実行してください。
画像ファイルを読み込み小さなウィンドウでも画像全体を表示できるようにスクロールバーを配置します。 ウィンドウのサイズを変更(サイズ可変ウィンドウです)しながらスクロールバーの動作を確認できます。
    dialog "bmp;*.jpg;*.gif", 16, "画像ファイル"  : if stat == 0  : mes "キャンセル"  : stop
    FileName = refstr

    picload FileName
    PicSizeX = ginfo_sx  : PicSizeY = ginfo_sy      ;画像の大きさを取得
    BarSize = ScrollBar_GetSystemSize()             ;バーの標準的な厚さ

    screen 1, PicSizeX + BarSize, PicSizeY + BarSize, , , , 320, 240    ;リサイズ可能ウィンドウ
    gcopy 0, 0, 0, PicSizeX, PicSizeY
    gosub *Window_PutScrollBar          ;ウィンドウにスクロールバーを配置する
    oncmd gosub *Window_PutScrollBar, 5 ;ウィンドウサイズが変更されると呼び出されるように
    ScrollBar_SetSubLabel *GetScroll    ;スクロールバー操作時にルーチンジャンプするように

    screen 0, 320, 20 * 6
    mes strf("画像サイズ:%4d×%4d", PicSizeX, PicSizeY)
    stop

*Window_PutScrollBar    ;ウィンドウの大きさが変更されたとき
    gsel 1  : clrobj                ;画面上のオブジェクトを破棄する

    ;横スクロールバーを配置する(まとめて設定する例)
    pos 0, ginfo_winy - BarSize     ;クライアント領域の底辺にくっつくように
    ScrollBar_Create ginfo_winx - BarSize, BarSize, 0, 0, PicSizeX - 1, ginfo_winx - BarSize, ginfo_vx, ginfo_winx / 4, ginfo_winx - BarSize
    XBarID = stat                   ;横スクのHSPオブジェクトID

    ;縦スクロールバーを配置する(個別に設定する例)
    pos ginfo_winx - BarSize, 0
    ScrollBar_Create BarSize, ginfo_winy - BarSize, 1
    YBarID = stat                   ;たてスクのHSPオブジェクトID
    ScrollBar_SetRange YBarID, 0, PicSizeY - 1, ginfo_winy - BarSize
    ScrollBar_SetStep  YBarID,  ginfo_winy / 4, ginfo_winy - BarSize
    ScrollBar_SetPos   YBarID,  ginfo_vy

    pos ginfo_winx - BarSize, ginfo_winy - BarSize  : winobj "STATIC", "", 0, $50000000, BarSize, BarSize   ;穴埋め

    ib = ginfo_vx, ginfo_vy, ginfo_winx - BarSize, ginfo_winy - BarSize
    gsel 0
    redraw 0  : color 255, 255, 255  : boxf  : color  : pos 0, 0
    mes strf("画像サイズ:%4d×%4d\n表示サイズ:%4d×%4d\nスクロール:%4d×%4d", PicSizeX, PicSizeY, ib(2), ib(3), ib, ib(1))
    redraw 1
    gsel 1      ;←戻しておかないとうまくいかないorz
    return

*GetScroll              ;スクロールバーが操作されてバーの値が変更されたとき
    gsel 1
    ib = ScrollBar_GetPos(XBarID), ScrollBar_GetPos(YBarID), ginfo_winx - BarSize, ginfo_winy - BarSize
    groll ib, ib(1)
    gsel 0
    redraw 0  : color 255, 255, 255  : boxf  : color  : pos 0, 0
    mes strf("画像サイズ:%4d×%4d\n表示サイズ:%4d×%4d\nスクロール:%4d×%4d", PicSizeX, PicSizeY, ib(2), ib(3), ib, ib(1))
    mes "ウィンドウID:" + ScrollBar_GetInfo(0)
    if ScrollBar_GetInfo(1) == $114  : mes "横スクロールバーを操作したです。"
    if ScrollBar_GetInfo(1) == $115  : mes "縦スクロールバーを操作したです。"
    if ScrollBar_GetInfo(3) == 0     : mes "矢印(減少)をつつきました。"
    if ScrollBar_GetInfo(3) == 1     : mes "矢印(増加)をつつきました。"
    if ScrollBar_GetInfo(3) == 2     : mes "空白(減少)をつつきました。"
    if ScrollBar_GetInfo(3) == 3     : mes "空白(増加)をつつきました。"
    if ScrollBar_GetInfo(3) == 5     : mes "つまみを動かしました。"
    redraw 1
    return
; http://www.tvg.ne.jp/menyukko/ ; Copyright(C) 2011-2012 衣日和 All rights reserved.