今回は、ツールバーのボタンの状態を取得したり設定したりしてみましょう。これらの作業はすべてツールバーにメッセージを送ることによって行なうことができます。
ツールバーのボタンの状態を取得するには、ツールバーに TB_GETSTATE メッセージを送信します。
#define TB_GETSTATE 0x0412 TB_GETSTATE wParam = idButton; lParam = 0;
idButton パラメータには、状態を取得するツールボタンのコマンドIDを指定します。このメッセージを送ると、戻り値として指定されたボタンの現在の状態が取得されます。ボタンの状態には例として以下のようなものがあり、状態はこれらの値の組み合わせで取得されます。
値 | 意味 |
---|---|
0x01 (TBSTATE_CHECKED) | ボタンが TBSTYLE_CHECK スタイルを持っていて、押されている状態。 |
0x02 (TBSTATE_PRESSED) | ボタンが押されている状態。 |
0x04 (TBSTATE_ENABLED) | ボタンが使用可能な状態。この状態が指定されていない場合はボタンは灰色表示になり、使用不可になります。 |
0x08 (TBSTATE_HIDDEN) | ボタンが見えない状態。ユーザーからの入力を受け付けません。 |
0x10 (TBSTATE_INDETERMINATE) | ボタンが灰色表示の状態。 |
0x20 (TBSTATE_WRAP) | ボタンを次の行に表示。TBSTATE_ENABLED が同時に指定されている必要があります。 |
ボタンの状態を設定するには、ツールバーに TB_SETSTATE メッセージを送ります。
#define TB_SETSTATE 0x0411 TB_GETSTATE wParam = idButton; lParam = fState;
idButton パラメータには、状態を取得するツールボタンのコマンドIDを、 fState パラメータには設定する状態を指定します。状態は上の表で示した値の組み合わせで指定します。
状態の設定は、それぞれの属性に対してのみ行なうこともできます。例えば、ボタンの表示・非表示を設定したり、有効・無効を設定したりすることができます。
ボタンの表示・非表示を設定するには、ツールバーに TB_HIDEBUTTON メッセージを送ります。
#define TB_HIDEBUTTON 0x0404 TB_HIDEBUTTON wParam = idButton; lParam = fHide;
idButton パラメータには、表示・非表示の状態を設定するツールボタンのコマンドIDを、 fHide パラメータには、ボタンを表示する場合は 0 (FALSE) を、非表示にする場合は 1 (TRUE) をそれぞれ指定します。
ボタンを押せないように無効にしたり、逆に有効にしたりするには、ツールバーに TB_ENABLEBUTTON メッセージを送ります。
#define TB_ENABLEBUTTON 0x0401 TB_ENABLEBUTTON wParam = idButton; lParam = fEnable;
idButton パラメータには、有効・無効の状態を設定するツールボタンのコマンドIDを、 fEnable パラメータには、ボタンを有効にする場合は 1 (TRUE) を、無効にする場合は 0 (FALSE) をそれぞれ指定します。無効にすると、ボタンが灰色表示になってユーザーはボタンを押すことができなくなります。
ボタン追加時にボタンのスタイルに 0x0002 (TBSTYLE_CHECK スタイル) を指定してある場合、ボタンが押されている状態と押されていない状態とを切りかえることができます。この設定をするには、ツールバーに TB_CHECKBUTTON メッセージを送ります。
#define TB_CHECKBUTTON 0x0402 TB_CHECKBUTTON wParam = idButton; lParam = fCheck;
idButton パラメータには、状態を設定するツールボタンのコマンドIDを、 fCheck パラメータには、ボタンを押された状態にする場合は 1 (TRUE) を、押されていない状態にする場合は 0 (FALSE) をそれぞれ指定します。
さて、実際にスクリプトを書いてみます。今回のサンプルはちょっとパズルゲーム感覚のものにしてみました。
スクリプト中では、ボタンの状態を取得・変更するのに TB_GETSTATE メッセージと TB_ENABLEBUTTON メッセージを使用しています。
今回使用する画像ファイルは、前に使用したのと同じものを使います。このビットマップファイルは、それぞれのイメージサイズが 16×15 ピクセル、イメージ数が9個、背景色の白色がパレットコードの 0 になるように作られた256色ビットマップファイルです。
(toolbtn.bmp)
今回は、ビットマップオブジェクトの作成と、ツールバーの操作の部分をモジュール命令として定義してあります。
#include "llmod.as" #include "hsgetmsg.as" #module ;####### ビットマップオブジェクト作成モジュール ######### ;=============================================================== ; 描画中ウィンドウのイメージからビットマップオブジェクト作成 ; CreateBitmap p1, p2, p3, p4 ; p1 : HSPウィンドウx座標 ; p2 : HSPウィンドウy座標 ; p3 : 幅 ; p4 : 高さ ; stat : ビットマップのハンドルが返る ;=============================================================== #deffunc CreateBitmap int, int, int, int mref px, 0 ; HSPウィンドウx座標 mref py, 1 ; HSPウィンドウy座標 mref sx, 2 ; xサイズ mref sy, 3 ; yサイズ mref stt, 64 ; stat mref bmscr, 67 ; 描画中ウィンドウのBMSCR構造体 ; ディスプレイのデバイスコンテキストのハンドル取得 devname = "DISPLAY" pm = 0,0,0,0 getptr pm, devname ; "DISPLAY"のアドレス dllproc "CreateDCA", pm, 4, D_GDI@ hdcScreen = stat ; ディスプレイのデバイスコンテキスト ; ディスプレイ互換ビットマップオブジェクト作成 pm = hdcScreen, sx, sy dllproc "CreateCompatibleBitmap", pm, 3, D_GDI@ hbitmap = stat ; ビットマップオブジェクトのハンドル ; ディスプレイ互換デバイスコンテキスト作成 pm = hdcScreen dllproc "CreateCompatibleDC", pm, 1, D_GDI@ hdcMemory = stat ; メモリデバイスコンテキストのハンドル ; ビットマップをデバイスコンテキストに選択 pm = hdcMemory, hbitmap dllproc "SelectObject", pm, 2, D_GDI@ ; HSPウィンドウからビットマップにイメージをコピー pm = hdcMemory, 0, 0, sx, sy, bmscr.4, px, py, $CC0020 dllproc "BitBlt", pm, 9, D_GDI@ ; デバイスコンテキストを削除 dllproc "DeleteDC", hdcMemory, 1, D_GDI@ dllproc "DeleteDC", hdcScreen, 1, D_GDI@ stt = hbitmap ; ビットマップオブジェクトのハンドル return #global ;############# モジュール終わり ######################## #module ;########### ツールバー操作モジュール ################## ;=============================================================== ; ツールバー作成 ; CreateToolbar p1, p2 ; p1 : ボタンイメージの幅 (0のとき16ピクセル) ; p2 : ボタンイメージの高さ (0のとき15ピクセル) ; stat : ツールバーのハンドルが返る ;=============================================================== #deffunc CreateToolBar int, int mref sx, 0 ; ビットマップの数 mref sy, 1 ; ビットマップオブジェクトのハンドル mref stt, 64 ; stat ; コモンコントロールライブラリ初期化 dllproc "InitCommonControls", pm, 0, D_COMCTL@ ; ツールバー作成 pm = 0, 0, 0, 0 ; 座標・サイズは 0 でよい pm.4 = 0x50000001 ; WS_CHILD | WS_VISIBLE | CCS_NORESIZE pm.5 = 0, 0 _makewnd pm, "ToolbarWindow32" hTool = pm ; ツールバーのハンドル ; TB_BUTTONSTRUCTSIZE メッセージ送信 pm = hTool, 0x041E, 20, 0 sendmsg pm ; ビットマップのサイズを設定 if sx == 0 : sx = 16 if sy == 0 : sy = 15 ; TB_SETBITMAPSIZE メッセージ送信 pm = hTool, 0x420, 0, sx | (sy << 16) sendmsg pm stt = hTool ; stat にツールバーのハンドルを格納 return ;=============================================================== ; 描画中ウィンドウのイメージをツールバーに加える ; (パレットモードであること・パレットインデックス 0 は透過色) ; (イメージが複数のときは横に並べられていること) ; AddToolBitmap p1, p2 ; p1 : ツールバーのハンドル ; p1 : HSPウィンドウx座標 ; p2 : HSPウィンドウy座標 ; p3 : 幅 ; p4 : 高さ ; stat : 最初のイメージのインデックスが返る ;=============================================================== #deffunc AddToolBitmap int, int, int, int, int mref hTool, 0 ; ツールバーのハンドル mref px, 0 ; HSPウィンドウx座標 mref py, 1 ; HSPウィンドウy座標 mref sx, 2 ; 高さ mref sy, 3 ; 幅 mref stt, 64 ; stat ; パレット 0 をシステムカラーのボタン表面色に変更 pm = 15 ; COLOR_BTNFACE dllproc "GetSysColor", pm, 1, D_USER@ palette 0, stat&$FF, (stat>>8)&$FF, (stat>>16)&$FF palfade ; ビットマップオブジェクト作成 CreateBitmap 0, 0, winx, winy hbitmap = stat ; ビットマップのハンドル ; ビットマップをボタンイメージのリストに追加 ; TBADDBITMAP 構造体 tbadd.0 = 0 tbadd.1 = hbitmap ; ビットマップハンドル ;TB_ADDBITMAPメッセージを送信 pm = hTool, 0x0413 pm.2 = 9 ; ビットマップ中のボタンイメージの数 getptr pm.3, tbadd ; TBADDBITMAP 構造体のアドレス sendmsg pm index = stat ; ビットマップオブジェクトを削除 dllproc "DeleteObject", hbitmap, 1, D_GDI@ stt = index return ;=============================================================== ; ボタンを1個追加 ; AddToolButton p1, p2, p3, p4, p5 ; p1 : ツールバーのハンドル ; p2 : ボタンのイメージのインデックス ; p3 : コマンドID ; p4 : ボタンの状態(使用可能ボタンは4が必要) ; p5 : ボタンスタイル ;=============================================================== #deffunc AddToolButton int, int, int, int, int mref hTool, 0 ; ツールバーのハンドル mref index, 1 ; ボタンのイメージのインデックス mref idCmd, 2 ; コマンドID mref fsState, 3 ; ボタン状態 mref fsStyle, 4 ; ボタン ; TBBUTTON 構造体 tbb.0 = index ; ボタンのイメージのインデックス tbb.1 = idCmd ; コマンドID tbb.2 = fsState | (fsStyle << 8) ; ボタン状態・スタイル tbb.3 = 0 tbb.4 = 0 ; TB_ADDBUTTONS メッセージを送信 pm = hTool, 0x0414 pm.2 = 1 ; 追加するボタンの数(1個) getptr pm.3, tbb ; TBBUTTON 構造体のアドレス sendmsg pm ; TB_AUTOSIZE メッセージ送信 pm = hTool, 0x0421, 0, 0 sendmsg pm return ;=============================================================== ; ボタンのスタイル取得 ; GetToolState p1, p2 ; p1 : ツールバーのハンドル ; p2 : コマンドID ; stat : 取得したスタイルが返る ;=============================================================== #deffunc GetToolState int, int mref hTool, 0 ; ツールバーのハンドル mref cmdID, 1 ; ボタンのコマンドID ; TB_GETSTATE メッセージを送信 pm = hTool, 0x0412, cmdID, 0 sendmsg pm return ;=============================================================== ; ボタンの有効・無効を設定 ; EnableToolButton p1, p2, p3 ; p1 : ツールバーのハンドル ; p2 : コマンドID ; p3 : 1:有効 0:無効 ;=============================================================== #deffunc EnableToolButton int, int, int mref hTool, 0 mref cmdID, 1 mref fEnable, 2 ; TB_TB_ENABLEBUTTON メッセージを送信 pm = hTool, 0x0401, cmdID, fEnable sendmsg pm return ;=============================================================== ; ツールバーの高さを取得 ; GetToolHeight p1 ; p1 : ツールバーのハンドル ; stat : ツールバーの高さが返る ;=============================================================== #deffunc GetToolHeight int mref hTool, 0 ; ツールバーのハンドル mref stt, 64 ; stat pm.0 = hTool ; ツールバーのハンドル getptr pm.1, rect ; RECT 構造体のアドレス dllproc "GetWindowRect", pm, 2, D_USER@ stt = rect.3 - rect.1 ; 高さを求める return #global ;############# モジュール終わり ######################## screen 0, 250, 130 ; ツールバーの作成 CreateToolbar 16, 15 ; イメージのサイズ 16×15 hTool = stat ; ツールバーのハンドル ; ボタンイメージ buffer 2,,,1 ; パレットモードで初期化 picload "toolbtn.bmp" ; パレットインデックス 0 が透過色 AddToolBitmap hTool, 0, 0, 16*5, 15 ; 5個のボタンを追加(コマンドID = 1000〜1004) repeat 5 AddToolButton hTool, cnt, 1000+cnt, 4 loop ; ウィンドウのサブクラス化 gsel 0 set_subclass ; サブクラス化 hwnd = stat ; メインウィンドウのハンドル set_message 0x0111 ; WM_COMMAND を取得するように設定 ; メッセージパラメータ用変数 dup msg, msgval.1 ; メッセージが格納される変数 dup wprm, msgval.2 ; wParamパラメータが格納される変数 dup lprm, msgval.3 ; lParamパラメータが格納される変数 GetToolHeight hTool ; ツールバーの高さ取得 pos 0, stat mes {" すべてのボタンを選択不可の状態 にしてみよう。 ボタンを押すと押されたボタンと その両側のボタンの選択可・不可 の状態が切り替わります。 "} cPush = 0 ; ボタンを押した回数 *mainloop get_message msgval if msgval == hwnd { if msg == 0x0111 : gosub *onCommand } else { wait 10 } goto *mainloop *onCommand ; WM_COMMANDが送られたとき ; ツールバー以外から送られた場合は何もしない if lprm != hTool : return cmdID = wprm & 0xFFFF ; 押されたボタンのコマンドID ; ボタン3つの状態(有効・無効)を変化させる repeat 3 cmdID2 = cmdID + cnt - 1 if cmdID2 < 1000 : cmdID2 += 5 if cmdID2 > 1004 : cmdID2 -= 5 GetToolState hTool, cmdID2 if stat & 0x04 { ; ボタンが有効の時は無効にする EnableToolButton hTool, cmdID2, 0 } else { ; ボタンが無効の時は有効にする EnableToolButton hTool, cmdID2, 1 } loop cPush++ ; すべて無効になったかどうかの確認 flag = 0 repeat 5 GetToolState hTool, 1000+cnt if stat & 0x04 : flag = 1 : break loop if flag == 0 { dialog "おめでとー!!\nボタンを押した回数 : "+cPush end } return
5つのボタンが最初はすべて有効な状態になっていて、ボタンを押すと、そのボタンとその両側にあるボタン(端のボタンが押された場合は反対側の端のボタンも)の有効・無効の状態が入れ替わるようになっています。すべてのボタンを無効の状態にすることができれば終了です。
最短で7回でできるはずです。