Last Update : 2006/10/xx
button命令とchkbox命令。見た目はぜんぜん違いますが、どちらも「ボタンコントロール」に分類されてます。ボタンの見た目を変えただけなのがチェックボックスであり、他にもラジオボタンやグループボックスがこのグループに含まれてます。
このオブジェクトに関する基礎的な情報は、button命令の解説やchkbox命令の解説のページを参照してください。
Win32 API関数を利用して、button命令で設置できるボタンオブジェクトの見た目(=ウィンドウスタイル)を変更してみるサンプルです。通常は、ボタンの中央にある文字列の表示位置を変更したり、文字列を複数行で表示することが可能です。(ウィンドウスタイルについては、ちょくとさんのページを参照)
現在のボタンのウィンドウスタイルをGetWindowLong関数で取得し、それにプラスした新たなウィンドウスタイルを SetWindowLong関数で指定してやります。ボタンのウィンドウハンドルを取得するのにobjinfo関数を利用します。
#uselib "user32" #cfunc GetWindowLong "GetWindowLongA" int, int #func SetWindowLong "SetWindowLongA" int, int, int objsize 200, 40 button "枠強調ボタン", *a hButton = objinfo(stat, 2) ; ウィンドウスタイルの変更 ; 太枠の強調ボタン($1) SetWindowLong hButton, -16, GetWindowLong (hButton, -16) | $1 *a
さて、厳密にやると上のようになりますが、HSPに登場するボタンのウィンドウスタイルは、あらかじめ「WS_CHILD + WS_VISIBLE = $50000000」と分かっているので、GetWindowLong関数の部分は省略しても問題ないでしょう。
; ボタンのウィンドウスタイル変更サンプル (by Kpan) #uselib "user32" #func SetWindowLong "SetWindowLongA" int, int, int objsize 200, 40 ; これは標準のボタン button "ふつーのボタン", *jump ; 太枠強調ボタン (BS_DEFPUSHBUTTON) button "枠強調ボタン (SetWindowLong)", *jump SetWindowLong objinfo(stat, 2), -16, $50000000 | $1 ; 太枠強調はsendmsg命令だけで実現可 button "枠強調ボタン (sendmsg)", *jump sendmsg objinfo(stat, 2), $F4 , $1 ; テキスト表示位置の変更 (BS_LEFT/BS_RIGHT/BS_TOP/BS_BOTTOM) ; $100=左寄り、$200=右寄り、$400=上寄り、$800=下寄り ; 複数個組み合わせれば「左下」に表示 button "テキスト位置変更ボタン", *jump SetWindowLong objinfo(stat, 2), -16, $50000000 | $100 | $800 ; 複数行テキスト・縦書き表示風にも (BS_MULTILINE) ; ボタンに収まるよう文字列を自動改行 (「\n」で手動改行) button "複数行\nボタン", *jump SetWindowLong objinfo(stat, 2), -16, $50000000 | $2000 ; フラットスタイルのボタン (BS_FLAT) ; Windows XP以降のビジュアルスタイル時は変化なし button "フラットボタン", *jump SetWindowLong objinfo(stat, 2), -16, $50000000 | $8000 stop *jump
このサンプルを元にしたボタンのウィンドウスタイルを変更するモジュールは、このページの最下部よりダウンロードできます。モジュールにしなければならないほど複雑なスクリプトではありませんが・・・ (^^;
Win32 API関数を利用して、chkbox命令で設置できるチェックボックスのウィンドウスタイルを変更してみるサンプルです。ボタンのウィンドウスタイル変更処理と同じです。
上のボタンのウィンドウスタイル変更にもあるように、現在のチェックボックスのウィンドウスタイルを取得し、それにプラスした新たなウィンドウスタイルを適用してやるわけですが、HSPに登場するチェックボックスのウィンドウスタイルは、「WS_CHILD + WS_VISIBLE + BS_AUTOCHECKBOX = $50000003」となっているので、GetWindowLong関数は省略します。
; チェックボックスのウィンドウスタイル変更サンプル (by Kpan) #uselib "user32" #func SetWindowLong "SetWindowLongA" int, int, int objsize 150, 40 chkbox "ふつー", x chkbox "右側にチェック項目", x SetWindowLong objinfo(stat, 2), -16, $50000003 | $20 ; $100=左寄り、$200=右寄り、$400=上寄り、$800=下寄り。 ; 複数個組み合わせて「右上」に。 chkbox "位置変更", x SetWindowLong objinfo(stat, 2), -16, $50000003 | $200 | $400 ; チェックボックスに収まるよう文字列を自動改行 (「\n」で手動改行) chkbox "複数行\nですー", x SetWindowLong objinfo(stat, 2), -16, $50000003 | $2000 ; フラットスタイル (Windows XP以降のビジュアルスタイル適用時は変化なし) chkbox "フラット", x SetWindowLong objinfo(stat, 2), -16, $50000003 | $8000
このサンプルを元にしたチェックボックスのウィンドウスタイルを変更するモジュールは、このページの最下部よりダウンロードできます。モジュールにしなければならないほど複雑なスクリプトではありませんが・・・ (^^;
チェックボックスというのは、内部的にはボタンオブジェクトです。HSPのbutton命令は、押した時にラベルにジャンプする機能を持っています。これをうまく利用して、チェックボックスのチェックの有無をリアルタイムで監視してみることにしましょう。
下のサンプルは、チェックボックスにチェックが入っていると、他のオブジェクトが使用可能な状態(有効)になり、入っていないと、グレー表示の使用不可な状態(無効)になる、というスイッチ処理が行われます。
オブジェクトの有効/無効の切り替えは、Win32 API関数のEnableWindow関数を使います。HSP2のllmod.asモジュール(obj.as)に「objgray命令」が用意されてましたが、この関数を呼び出していただけです。HSP3でも common\obj.as モジュール内に同じ命令が用意されています。
; チェックボックス監視サンプル (by Kpan) #uselib "user32" #func EnableWindow "EnableWindow" int, int ; 普通にボタンを作成 button "チェック", *check hButton.0 = objinfo(stat, 2) ; ボタンのウィンドウスタイルを変更してチェックボックス化 sendmsg hButton.0, $F4, $3 ; チェックボックスにチェックを入れる (BM_SETCHECK) ; 第3パラに 0=チェックあり、1=チェックなし ; 標準のobjprm命令は利用できません sendmsg hButton.0, $F1, 1 pos , 50 input x combox y, , "HSP\n講座\nプログラミング\nサンプル" stop *check ; チェックボックスの状態を取得 (BM_GETCHECK) ; statに 0=チェックなし、1=チェックあり が返ります sendmsg hButton.0, $F0 title ""+stat ; オブジェクトの使用可/使用不可の切り替え if stat { ; 第2パラが1だとオブジェクトが有効に EnableWindow objinfo(1, 2), 1 EnableWindow objinfo(2, 2), 1 } else { ; 第2パラが0だとオブジェクトが無効に EnableWindow objinfo(1, 2) EnableWindow objinfo(2, 2) }
ちなみに、入力ボックスとメッセージボックスについては、EnableWindow関数を使わず、sendmsg命令だけで有効無効の切り替えが可能です。(→入力ボックスの編集無効 を参照)
chkbox命令には、「チェックあり」と「チェックなし」の2つの状態が存在しますが、ここにもう1つ「不確定」の状態を加えた3つの状態を持つチェックボックスの作成です。sendmsg命令でウィンドウスタイルを変更してやります。
3つ目の状態は、チェックありのグレー表示(Windows XP以降のビジュアルスタイル適用時は四角いチェックマーク)で表現されます。注意点として、チェックボックスのデフォルト状態を指定するのに、通常ではあらかじめchkbox命令の状態保持変数に1を指定しておきますが、グレー表示の状態は指定できないのでsendmsg命令を使います。
; 3ステートチェックボックス作成サンプルソース (by Kpan) ; a = 1 ; OK チェックあり、になります ; a = 2 ; × グレー表示チェックありにならず chkbox "3ステート", a ; 3ステートチェックボックス化 sendmsg objinfo(stat, 2), $F4, $6 ; objprm 0, 1 ; OK ; objprm 0, 2 ; × ; なので、グレー表示に変更したい場合 (BM_SETCHECK) // sendmsg objinfo(0, 2), $F1, 2 // a = 2 ; これも必要 button "チェック!", *check stop *check ; 0=チェックなし、1=チェックあり、2=グレー表示チェックあり が返る mes a
button命令で作成したボタンは、マウスをクリックするとへこんで、離すと元の状態に戻る、という動きをします。ここでは、押した直後にへこんだまま、それを押すと元の状態に戻る、という2段階の動きをするトグルボタンを作成してみます。
で、実際使うのはボタンではなく、チェックボックスを利用します。チェックボックスに「チェックが入っている=ボタンがへこんでいる」、「チェックが入っていない=ボタンが膨らんでいる」、という考え方です。
Win32 API関数のSetWindowLong関数を利用して、チェックボックスのウィンドウスタイルを変更(BS_PUSHLIKE)してやります。
; トグルボタン作成サンプルソース1 (by Kpan) #uselib "user32" #func SetWindowLong "SetWindowLongA" int, int, int ; チェックボックスの状態保持変数に1を入れるとチェックが入る、つまり ; へこみボタンになります。設置後のオン/オフ制御は、普通にobjprm命令を利用。 c2 = 1 chkbox "第壱番", c1 SetWindowLong objinfo(stat, 2), -16, $50000003 | $1000 chkbox "第弐番", c2 SetWindowLong objinfo(stat, 2), -16, $50000003 | $1000 pos , 100 button "御確認", *check stop ; 状態の確認。普通にチェックボックスの状態保持変数を確認しませう。 ; 0=チェックなし(膨らんでいる)、1=チェックあり(へこんでいる) *check title ""+c1+" / "+c2
このサンプルを元にしたトグルボタンの作成モジュールは、このページの最下部よりダウンロードできます。モジュールにしなければならないほど複雑な処理は必要ありませんが。(^ー^;
; トグルボタン作成サンプルソース2 (by Kpan)
; button命令を利用した手法 (リアルタイムで動きを確認したい場合)
#uselib "user32"
#func SetWindowLong "SetWindowLongA" int, int, int
button "OFF", *jump
SetWindowLong objinfo(stat, 2), -16, $50000003 | $1000
stop
*jump
if check {
data = "OFF"
} else {
data = "ON"
}
objprm 0, data
check ^ 1
title ""+check
ボタンにビットマップを貼り付ける画像ボタン(イメージボタン)の作成です。HSP2では、llmod.asモジュールを利用してビットマップを貼り付けるbtnimg命令を利用する、あるいはマウスの動きを監視して、擬似的なボタン風処理を自分で作ってしまう方法があります。(→参照、llmod3 や HSP開発wiki)
ここではボタンに貼り付けるビットマップファイルを実行ファイル内にリソースとして埋め込むという、HSP的には特殊な手法で行います(めんどくさい!&イレギュラー!)。リソースエディタ「Resource Hacker」を別途用意してください。
これで下準備が完了。1つのボタン用に1つのビットマップファイルを用意することになります。HSPのPACKFILE機能は利用しません。下が埋め込んだ画像を利用するためのコードです。モジュール+サンプルの形式になっています。
; ボタンにビットマップを貼り付けるモジュール (by Kpan) #module #uselib "user32" #cfunc LoadImage "LoadImageA" int, int, int, int, int, int #func SetWindowLong "SetWindowLongA" int, int, int #uselib "gdi32" #func DeleteObject "DeleteObject" int ; SetBitmap p1, p2 ; p1=ボタンのオブジェクトID ; p2=[リソース名]で指定した任意の数値 #deffunc SetBitmap int p1, int p2 hButton = objinfo (p1, 2) SetWindowLong hButton, -16, $50000000 | $80 hBitmap.i = LoadImage (hinstance, p2, , , , ) if hBitmap.i = 0 : return sendmsg hButton, $F7, , hBitmap.i i++ return ; ビットマップの開放 ; (※自動的に行われるので呼び出し不要) #deffunc DelBitmap onexit repeat i DeleteObject hBitmap.cnt loop return #global ; 以下、サンプル ; 画像を埋め込んだランタイムファイルをパックオプションで指定 #packopt runtime "hogehoge.hrt" objsize 200, 100 ; 表示文字列は指定しても意味ないので無指定 button "", *dummy ; 貼り付け。ボタンのオブジェクトID、「リソース名」の数値を指定。 SetBitmap stat, 1 stop *dummy
で、これをスクリプトエディタ上でコンパイル実行しても、ボタンに何の変化も現れません。これは実行ファイルにならないと効果を確認できない代物です。また、ビットマップの貼り付けに失敗しても別にエラーはでません。[実行ファイル自動作成]で実行ファイルを出力して、動作確認してください。
※注意: ビットマップを貼り付けたボタンは、Windows XP環境のXPスタイル適用下でも必ずクラシックスタイルで表示される仕様になっています。
ラジオボタン(別名、オプションボタン/ラジオボックス)の作成です。ラジオボタンというのは、複数用意されている丸い形状の項目から1つだけ選択できるものです。HSPの標準命令には存在しないオブジェクトですが、内部的にはボタンコントロールの見た目を変えたにすぎません。
ここでは、HSPでのラジオボタン作成法としてよく紹介されていたbutton命令を使わず、chkbox命令のウィンドウスタイルを変更する新手法を紹介します。
; 状態保持変数に1を入れたチェックボックス(ラジオボタン)に ; 黒丸チェックが入ります。ここでは2番目。 s2 = 1 chkbox "あ", s1 sendmsg objinfo(stat, 2), $F4, $9 chkbox "い", s2 sendmsg objinfo(stat, 2), $F4, $9 chkbox "う", s3 sendmsg objinfo(stat, 2), $F4, $9
さて、上のようにサクっと表示できたスクリプトですが、これはウィンドウ上にラジオボタンのグループが1つしか存在しない時だけ有効で、このまま同じ処理を繰り返しても、ただ単に選択肢がどんどん増えていくだけです。
もし、ラジオボタンのグループが複数ある場合は、1つの方法として「グループ化」という処理を利用します。グループの1番最初のチェックボックスは、ラジオボタン化($50000000+$9)するついでに、グループ化宣言($20000)を行う必要があるので、SetWindowLong関数を呼びます。それ以降は、普通にsendmsg命令でラジオボタン化($9)します。
グループ化を宣言したオブジェクトから、次にグループ化を宣言するオブジェクトの直前までを1つのグループと判断してくれます。
; ラジオボタン表示サンプルスクリプト (by Kpan) #uselib "user32" #func SetWindowLong "SetWindowLongA" int, int, int ; 1番目のグループ x1 = 1 chkbox "あ", x1 SetWindowLong objinfo(stat, 2), -16, $50000009 | $20000 chkbox "い", x2 sendmsg objinfo(stat, 2), $F4, $9 chkbox "う", x3 sendmsg objinfo(stat, 2), $F4, $9 ; 2番目のグループ ; これにより、上とは別動作になるのであーる pos , 80 y3 = 1 chkbox "I", y1 SetWindowLong objinfo(stat, 2), -16, $50000009 | $20000 chkbox "II", y2 sendmsg objinfo(stat, 2), $F4, $9 chkbox "III", y3 sendmsg objinfo(stat, 2), $F4, $9 ; 3番目のグループ ; トグルボタン型($1000)ラジオボタン(チェックあり=へこみボタン) pos , 160 z2 = 1 chkbox "A", z1 SetWindowLong objinfo(stat, 2), -16, $50000009 | $1000 | $20000 chkbox "B", z2 SetWindowLong objinfo(stat, 2), -16, $50000009 | $1000 chkbox "C", z3 SetWindowLong objinfo(stat, 2), -16, $50000009 | $1000 pos , 250 button "チェック!", *check stop ; チェックのあるラジオボタンを取得 (もっとスマートな確認手段は・・・) ; 1つ1つのオブジェクトのチェックの有無を確認。 ; statに1が返ると「チェックあり」ということで、そのオブジェクトIDを表示。 *check ; グループ1用 repeat 3, 0 sendmsg objinfo(cnt, 2), $F0 if stat : mes cnt loop ; グループ2用 repeat 3, 3 sendmsg objinfo(cnt, 2), $F0 if stat : mes cnt loop ; グループ3用 (トグルボタン型) repeat 3, 6 sendmsg objinfo(cnt, 2), $F0 if stat : mes cnt loop
このサンプルを元にしたHSP3向けラジオボタンの作成モジュールを、このページの一番下にて公開中。
グループボックス(四角い枠)の作成です。HSPの標準命令にはありませんが、グループボックスというのはボタンの見た目を変えただけです。以下のサンプルは、あくまでグループボックス自体が表示されるだけです。HSPにはグループボックスのサンプルコード (sample\basic\groupbox.hsp) が一応用意されていますが、オブジェクト内の表示が化けるバグ(?)があります。
※注意!!!
以下のサンプルは、OSやら環境やらで表示の挙動が異なり、オブジェクトが置くとおかしくなるためダメダメ。HSP2時代からグループボックスはどーもこーもいかない・・・?
(*_*;
; まったく使えーんよ。。。失敗例 #uselib "user32" #cfunc GetWindowLong "GetWindowLongA" int, int #func SetWindowLong "SetWindowLongA" int, int, int ;ポイント!? 表示化けの原因であるウィンドウの 「WS_CLIPCHILDREN」;スタイル を取り除く処理を Windows API 使って行います。SetWindowLong hwnd, -16, GetWindowLong (hwnd, -16) ^ $2000000; 普通にグループボックスの位置と大きさ pos 10, 10 objsize 200, 100 ; ボタンではなくチェックボックスを使う。(xはダミー変数) chkbox "グループボックスでっせ!", x ; グループボックスに変更。objinfo関数 の第1パラにオブジェクトID。 sendmsg objinfo(stat, 2), $F4, $7 ; [おまけ] グループボックスの表示文字列の位置を変更したものを作成 ; したい場合は、sendmsg命令 は使えません。$200=右端、$300=中央。 chkbox "ここの位置ね", x SetWindowLong objinfo(stat, 2), -16, $50000007 | $200
というわけで、オブジェクトではないですが、グループボックス「風」の枠を描画するモジュールをこのページ最下部からダウンロードできます。(素直にline命令で、線を1本1本描画してもいいところを、わざわざWin32 API関数で・・・ ^ー^;
このページで紹介しているいくつかのサンプルスクリプトに基づいたモジュールです。ボタンとチェックボックスのウィンドウスタイル変更、トグルボタン作成、ラジオボタン作成、グループボックス「風」の枠表示、の4ファイルを含んでいます。(HSP 3.x用)
<< オブジェクト編 9 | HSP3 オブジェクト | オブジェクト編 2 >>
Copyright © 2005-2008 Kpan. All rights reserved.