
今回は、ツールバーのボタンにのイメージの下に文字列を表示してみます。
ツールバーは内部にボタンイメージのリストを持っていて、表示させるイメージはそのリスト中のものが使われるということは以前に説明しました。ツールバーに表示される文字列もこれとまったく同様で、ツールバーは内部に文字列リストを持っており、このリスト中にある文字列が表示されるようになっています。
ボタンに文字列を表示させるには、まず文字列リストの中に表示させる文字列を追加しなくてはいけません。リストに文字列を追加させるには、ツールバーに 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