Version 10.19
ツールバーを作ってみよう
「さて、今回は SDK でツールバーを作ってみます」
『ステータスバーと同じくって感じね』
「ただ、今回はさらに MFC のものとはかけ離れてるから」
『そうなんだ』
「とういうより、 MFC の方がややこしいことしてるっぽい……。ま、とり
あえず作ってみようか。まずはリソースにツールバーを挿入します」
『そっか、 MFC の時って最初からあったもんね』
「まずワークスペースでリソースを表示して【SimpleWindow リソース】を
右クリックして【挿入】 を選んで」
『ダイアログ出た。【Toolbar】を選べばいいんだよね』
「うん、そうするとツールバーができると思うから」
『 ID とかはどうするの?』
「まず、ボタンをふたつにして、左側は赤で、右側は青で塗り潰して」
『ほい。この辺は Version 9.11 ( No.172 ) を参照にしてと。 ID は?』
「これは別の場所で指定するからここでは指定しなくていいよ。次に、
ツールバーそのものの ID を IDR_TOOLBAR_MAIN にして」
『ほい。って、ツールバーそのものの ID ってどう変えるの?』
「ワークスペースの IDR_TOOLBAR1 の上で右クリックでプロパティ」
『あ、ホントだ。って前になんかで聞いたねそれ……』
「この辺はどのリソースも同じだからね。で、ここでまず確認して欲しいの
は、このプロパティの右側」
『赤と青だね』
「これって、ボタンとは違うでしょ」
『あ、ホントだ。ボタンの形してないし、赤と青の間が詰まってるし』
「左側に【ファイル名】ってあるでしょ」
『 toolbar1.bmp ってある。ビットマップファイル?』
「そう、このビットマップにこの赤と青の絵が描かれてるってことです」
『ほほう。これが後で重要になるの?』
「重要になるんです。じゃあこれを閉じて、今度は赤でも青でもいいからボ
タンをダブルクリックして」
『ほい、ボタンのプロパティが出たよ』
「さっき言ったように ID はここでは指定しないから。で、ここで重要なの
は幅と高さ」
『 16 と 15 だね』
「このボタンのマス目が、横が 16 ドット、縦が 15 ドットってこと。って
ことは、さっきのビットマップのサイズは?」
『あ、えーっと、間が詰まってたから、横は 32 ドット、縦は 15 ドット
ってことだね』
「そういうこと。これがあとで重要になるから。さて、次はプログラムの
方。まず OnMenuTest() を修正して」
// ID_MENU_TEST が選択されました。
LRESULT OnMenuTest
( HWND p_hWnd
, WPARAM p_wParam
, LPARAM p_lParam
)
{
TRACE( "OnMenuTest()\n" );
return 0;
}
『あら、シンプルに』
「ステータスバーのテストの時は色々してたけど、今回はこのコマンドが実
行されたことだけ分かればいいから。同じく、ウィンドウプロシージャから
はステータスバーの通知メッセージの部分を取り除きます」
// ウィンドウプロシージャ。
LRESULT CALLBACK WndProc
( HWND p_hWnd
, UINT p_uiMessage
, WPARAM p_wParam
, LPARAM p_lParam
)
{
if( p_uiMessage == WM_CREATE )
{
return OnCreate( p_hWnd, p_wParam, p_lParam );
}
else if( p_uiMessage == WM_DESTROY )
{
return OnDestroy();
}
else if( p_uiMessage == WM_RBUTTONUP )
{
return OnRButtonUp( p_hWnd, p_wParam, p_lParam );
}
else if( p_uiMessage == WM_COMMAND )
{
if( LOWORD( p_wParam ) == ID_MENU_TEST )
{
return OnMenuTest( p_hWnd, p_wParam, p_lParam );
}
}
// 標準的な処理をします。
return DefWindowProc( p_hWnd, p_uiMessage, p_wParam, p_lParam );
}
『最後の方の if がなくなっただけだね』
「最後に本命。 OnCreate() の部分をこう書き変えてください」
// ウィンドウが作られます。
LRESULT OnCreate
( HWND p_hWnd
, WPARAM p_wParam
, LPARAM p_lParam
)
{
const int TOOLBAR_BUTTON_NUM = 2;
TBBUTTON pstTbButton[TOOLBAR_BUTTON_NUM];
// ひとつめのボタンのデータをセット。
pstTbButton[0].iBitmap = 0;
pstTbButton[0].idCommand = ID_MENU_TEST;
pstTbButton[0].fsState = TBSTATE_ENABLED;
pstTbButton[0].fsStyle = TBSTYLE_BUTTON;
pstTbButton[0].dwData = 0;
pstTbButton[0].iString = 0;
// ふたつめのボタンのデータをセット。
pstTbButton[1].iBitmap = 1;
pstTbButton[1].idCommand = 0;
pstTbButton[1].fsState = TBSTATE_ENABLED;
pstTbButton[1].fsStyle = TBSTYLE_BUTTON;
pstTbButton[1].dwData = 0;
pstTbButton[1].iString = 0;
// ツールバーを作ります。
HWND hToolBarWnd = CreateToolbarEx
( p_hWnd
, WS_CHILD | WS_VISIBLE
, 100
, TOOLBAR_BUTTON_NUM
, GetModuleHandle( NULL )
, IDR_TOOLBAR_MAIN
, pstTbButton, TOOLBAR_BUTTON_NUM
, 0, 0
, 16, 15
, sizeof( TBBUTTON )
);
if( hToolBarWnd == NULL )
{
// ツールバーが作られませんでした。
return -1;
}
return 0;
}
『長いような長くないような』
「たぶん見た目よりは長くないと思うよ。まず、ツールバーのボタンの情報
は TBBUTTON という構造体の配列に入れます。それがこれ」
const int TOOLBAR_BUTTON_NUM = 2;
TBBUTTON pstTbButton[TOOLBAR_BUTTON_NUM];
「 2 なのはボタンの数が2個だから。で、この配列のひとつひとつに値を
入れます」
pstTbButton[0].iBitmap = 0;
pstTbButton[0].idCommand = ID_MENU_TEST;
pstTbButton[0].fsState = TBSTATE_ENABLED;
pstTbButton[0].fsStyle = TBSTYLE_BUTTON;
pstTbButton[0].dwData = 0;
pstTbButton[0].iString = 0;
「 TBBUTTON::iBitmap はボタンの何番目のボタンか。
TBBUTTON::idCommand はボタンが押されたときに送られる ID 」
『あ、ここで指定してるからさっきのは要らないんだね』
「そういうこと。あとのはパス」
『パスぅ?』
「こっちはどのボタンでも同じで大丈夫だから」
『そういえば、ふたつめのボタンも同じだね』
「ボタン毎に変えるのは TBBUTTON::iBitmap と TBBUTTON::idCommand って
ことだね。で、そのあとツールバーを作ります。その中でも重要なものを
ピックアップします。まず第3引数」
, 100
「これはツールバーそのものの ID 」
『あれ? これって IDR_TOOLBAR_MAIN じゃないの?』
「そう、違うんです。これは CreateStatusWindow() の第4引数と同じよう
な感じ」
『ツールバーの操作をするときに使う……のは分かるんだけど、なんで
IDR_TOOLBAR_MAIN じゃないの?』
「 IDR_TOOLBAR_MAIN はツールバーじゃなくて、ビットマップの ID なんで
す。アイコンの ID に近いかも」
『アイコン、ねぇ……』
「それが重要なのが、これ」
, 16, 15
『 16 と 15 ……あ、ボタンのサイズ』
「実は、 CreateStatusWindow() は IDR_TOOLBAR_MAIN ビットマップから
16 ドットずつ切り抜いてボタンに貼り付けてるんです」
『切り抜く??』
「つまり、こういうこと」
・ボタンそれぞれの情報( ID とか) : pstTbButton
・ボタンに貼り付ける絵柄 : IDR_TOOLBAR_MAIN
「というふうに役割が分けられてるんです」
『……なんか、ツールバーリソースの意味ってあるの?』
「あんまりないかも。それこそ MFC との一番の違いかも」
/*
Preview Next Story!
*/
『ツールバーはかなり MFC と違うよね』
「ツールバーの場合、 MFC との比較はあまり勉強にならないかも」
『なんで?』
「本当に作りが違うから」
『……なら、 MFC の方の仕組みもわかってないといけないんじゃない?』
「それはさすがにかなり先かも」
『まだ道のりは遠いのね……』
「というわけで次回」
< Version 10.20 SDK だけで作るテキストエディタもどき >
『につづく!』
「このテキストエディタもどきの解説で SDK 編は最後です」
『長かったねー』
「でも Version 11 はさらに長いんだけどね」
『え”』