Version 10.15
ステータスバーを作ってみよう!
『 SDK で MFC と同じことをしてみよう企画、次は?』
「次はステータスバーです」
『これは初めっからあった機能だよね』
「そう、 Version 9.13 ( No.174 ) でやったね。ただ、ステータスバーと
ツールバーは MFC とかなり違うから、 MFC の時のはあまり参考にならない
かも」
『参考になるほどちゃんと教わってないし』
「確かに……じゃ、まずはステータスバーを表示させます」
『まずはそっからね』
「まずはコードの修正から。 MFC の時って、ツールバーはいつ作ってた?」
『あのときは CMainFrame::OnCreate() の中だったね』
「というわけで、今回も同じようにします」
『同じように、ねぇ……』
「 CMainFrame::OnCreate() っていつ呼ばれる?」
『えっと、確かウィンドウが作られるとき……あ! そっか、メッセージが
送られてきてそれで呼ばれるから』
「そう、ウィンドウが作られるときには WM_CREATE ってメッセージが送ら
れてきて、 MFC の時は CMainFrame::OnCreate() を呼び出してました」
『ってことは、 SDK の時はウィンドウプロシージャで受け取って、また似
たような関数を作って呼ぶようにすればいい、ってことね』
「そういうこと。実際にやってみると、まずウィンドウプロシージャはこう
いう感じになります」
// ウィンドウプロシージャ。
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();
}
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 );
}
「 WM_CREATE を受け取ったら OnCreate() を呼ぶって処理を追加しまし
た」
『ってことは OnCreate() を作るんだ』
「そういうこと。 OnRButtonUp() をコピペして、こんな感じに」
// ウィンドウが作られます。
LRESULT OnCreate
( HWND p_hWnd
, WPARAM p_wParam
, LPARAM p_lParam
)
{
return 0;
}
『戻り値とか引数とか同じね。あ、これが Version 10.13 ( No.191 ) で
言ってた〈コピペが楽〉ってゆーのね』
「そういうこと。まぁ微妙な部分もあるんだけど」
『あの時もそんなこと言ってたね』
「 WM_CREATE のリファレンスを見てみて」
lpcs = (LPCREATESTRUCT) lParam; // structure with creation data
「これは、 LPARAM には CREATESTRUCT っていう構造体のポインタが入って
るって意味」
『この構造体ってなんに使うの?』
「ウィンドウがどこに作られるとか、ウィンドウ名とか、そういう情報が全
部入ってます」
『それ便利!』
「それを使う場合にはこうなります」
// ウィンドウが作られます。
LRESULT OnCreate
( HWND p_hWnd
, WPARAM p_wParam
, LPARAM p_lParam
)
{
LPCREATESTRUCT pstCreateStruct
= (LPCREATESTRUCT)p_lParam;
// とりあえずウィンドウ名を出力。
OutputDebugString( pstCreateStruct->lpszName );
return 0;
}
『キャストしてるんだね』
「そのキャストをウィンドウプロシージャでするっていう方法もあるわけ」
『どんなふうに?』
「たとえば、ウィンドウプロシージャで OnCreate() を呼ぶところは」
LPCREATESTRUCT pstCreateStruct
= (LPCREATESTRUCT)p_lParam;
return OnCreate( p_hWnd, pstCreateStruct );
「ってして、 OnCreate() の方は」
LRESULT OnCreate
( HWND p_hWnd
, LPCREATESTRUCT p_pstCreateStruct
)
{
OutputDebugString( p_pstCreateStruct->lpszName );
return 0;
}
「って感じ」
『ウィンドウプロシージャの方でキャストしちゃってから渡すわけねー』
「でも、今回はそうしない方で説明するね」
『え、なんで?』
「 CREATESTRUCT はすぐには使わないから。使わないものがあると混乱の元
だし」
『そういうもん?』
「そういうもの。さて、話と、あとウィンドウプロシージャも元に戻しても
らって、ステータスバーは次のような感じに作ります」
LRESULT OnCreate
( HWND p_hWnd
, WPARAM p_wParam
, LPARAM p_lParam
)
{
CreateStatusWindow
( WS_CHILD | WS_VISIBLE
, "テスト"
, p_hWnd
, 100
);
return 0;
}
「 CreateStatusWindow() っていう関数で作るのね」
『そう。で、この関数の説明は次回にするとして、ビルドしてみて』
『ほい。あ、エラー出た』
Main.cpp(16) : error C2065: 'CreateStatusWindow'
: 定義されていない識別子です。
「これは、必要なファイルをインクルードしてないから。コモンコントロー
ルって憶えてる?」
『しっかりは教わってないような……』
「一応 Version 3.10 ( No.035 ) で触れたし、それにしっかり教えるよう
なことじゃないっていうか」
『どういうこと?』
「普段使ってるエディットボックスやツールバー、そういうの全部コモンコ
ントロールだから」
『ってことは、コモンコントロールかどうかとかあんまり気にしなくてい
いってことね』
「そういうこと。でも、 SDK の場合にはちょっと気にする必要があって」
『それが、このインクルードしなきゃいけないのってことね』
「 Version 8.16 ( No.158 ) でも触れてるけど、 Commctrl.h ってファイ
ルをインクルードする必要があります。だから」
#include <stdio.h>
#include <Windows.h>
#include <Commctrl.h> // この行を追加。
「って感じになります」
『ファイルの最初の所ね。んじゃビルドして実行〜ってあれ?? また
エラーが出た』
Main.obj : error LNK2001:
外部シンボル "__imp__CreateStatusWindowA@16" は未解決です
『こ、今度のはなに???』
「これはちょっと難しい部分だから詳しくは次の次の章に書くけど、これは
CreateStatusWindow() の関数本体が見つかりません、みたいなエラー」
『ど、どういうこと?』
「インクルードファイルって、実は関数の呼び出し方が書かれてるだけ。だ
からその関数本体があるって保証はどこにもないんです」
『で、インクルードだけしたから、その本体がないって言われてるってこ
と?』
「そういう感じ。で、これを解決するために、【プロジェクトの設定】ダイ
アログで【リンク】−【一般】ページの【オブジェクト/ライブラリ
モジュール】って部分を見て」
『あ、同じ拡張子が .lib のファイルがいっぱいある。』
「ここにあるもののなかに、ウィンドウズでアプリを動かすための機能が
びっしり入ってるんです」
『こーゆーのを見てるから、ちゃんとできてるってこと?』
「そういうこと。 MFC だとこういうのは隠れたところでしちゃうんだけど
ね」
『え? そういうのできるの?』
「うん。 MFC のプロジェクトで同じ欄を見てみると分かるけど、空欄に
なってるから」
『それってなんか怪しい感じ……』
「まぁその辺はもう少し先ってことで、この一覧の最後にスペースを入れて
から」
comctl32.lib
「を追加して」
『ほい追加。んで OK 押して閉じてビルドして実行! お、今度はちゃんと
できた! ステータスバーもある!』
「というわけで表示はここまで。次はステータスバーを操作します」
/*
Preview Next Story!
*/
『インクルードとかライブラリとか、そっちの方が難しいね』
「うん、この辺は2章後くらいにちゃんと教えるから」
『それって遅くない』
「確かに、最初の方で必要な知識ではあるんだけど、でも」
『でも?』
「こういう部分を本当に理解してることが重要かなと」
『とりあえず解決できるっていうのも重要じゃない?』
「というわけで次回」
< Version 10.16 ステータスバーを使ってみる・ SDK 編 >
『につづく!』
「このステータスバーのとかはそういう方針だけどね」
『なんか偏ってる〜』