今回は、ツールバーのボタンにのイメージの下に文字列を表示してみます。
ツールバーは内部にボタンイメージのリストを持っていて、表示させるイメージはそのリスト中のものが使われるということは以前に説明しました。ツールバーに表示される文字列もこれとまったく同様で、ツールバーは内部に文字列リストを持っており、このリスト中にある文字列が表示されるようになっています。
ボタンに文字列を表示させるには、まず文字列リストの中に表示させる文字列を追加しなくてはいけません。リストに文字列を追加させるには、ツールバーに TB_ADDSTRING メッセージを送信します。
#define TB_ADDSTRING 0x041C TB_ADDSTRING wParam = hinst; lParam = idString;
ここでは、 hinst パラメータには 0 (NULL) を、 idString パラメータには文字列を入れたバッファのアドレスをそれぞれ指定します。メッセージ送信時の戻り値として、追加された文字列のリスト中でのインデックスが返ります。
このメッセージでは一度に複数の文字列を追加できるようになっていますが、このとき、それぞれの文字列がヌル文字(すなわち1バイトサイズの 0 )で区切られているように指定し、また、最後の文字列の後には2つのヌル文字がなければなりません。例えば、3つの文字列“Str1”、“Str2”、“Str3”を指定する場合、
というように配置されなければなりません。このとき、メモリ内は
53 | 74 | 72 | 31 | 00 | 53 | 74 | 72 | 32 | 00 | 53 | 74 | 72 | 33 | 00 | 00 | (16進数表示) |
'S' | 't' | 'r' | '1' | NUL | 'S' | 't' | 'r' | '2' | NUL | 'S' | 't' | 'r' | '3' | NUL | NUL |
のようになっていることになります。バッファにこのように格納させるには、以下に示すような方法をを使います。
sdim buf, 64 sdim s, 8, 3 s.0 = "Str1" s.1 = "Str2" s.2 = "Str3" idx = 0 repeat 3 poke buf, idx, s.cnt idx += strsize poke buf, idx, 0 ; NULL文字で区切る idx++ loop poke buf, idx, 0 ; 最後の2個目のヌル文字
とすれば、変数 buf には上で示したような形で格納されます。(話はそれますが、 (w)poke 命令を使うときに文字列を指定すると、バッファに書きこまれた文字列のサイズがシステム変数 strsize に格納されます。マニュアルには載っていないようですが。ここではそれを使っています。)
上のように一度に複数の文字列を追加するよりは、1つずつ順番に追加していくほうが簡単だと思います。1つずつ追加する場合も、文字列の後ろに2つのヌル文字が続かなくてはならないので、 sdim である程度余裕を持って確保しておいた変数に入れてそれを指定しましょう。
文字列リストの中に文字列を追加できたら、あとは TB_ADDBUTTONS メッセージや TB_INSERTBUTTON メッセージでボタンを追加する際に、 TBBUTTON 構造体の iString メンバに文字列のリスト中におけるインデックスを指定すれば、文字列が表示されたボタンがツールバーに追加されます。
さて、実際にスクリプトを書いてみます。
今回は以下の画像ファイルを使用します。このビットマップファイルは、それぞれのイメージサイズが 18×18 ピクセル、イメージ数が6個、背景色がパレットコードの 0 になるように作られた256色ビットマップファイルです。
(toolbtn2.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 ;=============================================================== ; テキストをツールバーの文字列リストに加える ; AddToolString p1, p2 ; p1 : ツールバーのハンドル ; p2 : 文字列(複数ある場合は改行("\n")で区切る) ; stat : 文字列インデックスが返る ;=============================================================== #deffunc AddToolString int, str mref hTool, 0 ; ツールバーのハンドル mref setStr, 33 ; リストに加える文字列 mref stt, 64 ; stat strlen ln, setStr sdim szString, ln+1 sdim temp, 64 ; メモリノートパッド命令を使う notesel setStr notemax num index = 0 ; ヌル文字で区切る repeat num noteget temp, cnt poke szString, index, temp : index += strsize poke szString, index, 0 : index++ loop poke szString, index, 0 ; 最後の2個目のヌル文字 ; TB_ADDSTRING メッセージ送信 pm = hTool, 0x041C, 0 getptr pm.3, szString sendmsg pm return ;=============================================================== ; ボタンを1個追加 ; AddToolButton p1, p2, p3, p4, p5 ; p1 : ツールバーのハンドル ; p2 : ボタンのイメージのインデックス ; p3 : コマンドID ; p4 : ボタンの状態(使用可能ボタンは4が必要) ; p5 : ボタンスタイル ; p6 : ボタンのテキストのインデックス ;=============================================================== #deffunc AddToolButton int, int, int, int, int, int mref hTool, 0 ; ツールバーのハンドル mref index, 1 ; ボタンのイメージのインデックス mref idCmd, 2 ; コマンドID mref fsState, 3 ; ボタン状態 mref fsStyle, 4 ; ボタンのスタイル mref idxText, 5 ; ボタンのテキストのインデックス ; TBBUTTON 構造体 tbb.0 = index ; ボタンのイメージのインデックス tbb.1 = idCmd ; コマンドID tbb.2 = fsState | (fsStyle << 8) ; ボタン状態・スタイル tbb.3 = 0 tbb.4 = idxText ; テキストのインデックス ; 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 #global ;############# モジュール終わり ######################## screen 0, 310, 110 ; ツールバーの作成 CreateToolbar 18, 18 ; イメージのサイズ 18×18 hTool = stat ; ツールバーのハンドル ; ボタンイメージ buffer 2,,,1 ; パレットモードで初期化 picload "toolbtn2.bmp" ; パレットインデックス 0 が透過色 AddToolBitmap hTool, 0, 0, 18*6, 18 ; 文字列リストへの追加 AddToolString hTool, "新規\n開く\n保存\n切り取り\nコピー\n貼り付け" ; 6個のボタンを追加 AddToolButton hTool, 0, 1000, 0x04, 0x00, 0 AddToolButton hTool, 1, 1001, 0x04, 0x00, 1 AddToolButton hTool, 2, 1002, 0x04, 0x00, 2 AddToolButton hTool, 0, 0, 0, 0x01, 0 AddToolButton hTool, 3, 1003, 0x04, 0x00, 3 AddToolButton hTool, 4, 1004, 0x04, 0x00, 4 AddToolButton hTool, 5, 1005, 0x04, 0x00, 5 ; ウィンドウのサブクラス化 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パラメータが格納される変数 *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 if (cmdID >= 1000) & (cmdID <= 1005) { if cmdID == 1000 : s = "新規" if cmdID == 1001 : s = "開く" if cmdID == 1002 : s = "保存" if cmdID == 1003 : s = "切り取り" if cmdID == 1004 : s = "コピー" if cmdID == 1005 : s = "貼り付け" dialog "\"" +s+ "\"ボタンが押されました" } return