時乃工房-Windowsとアマグラマーな関係-

アクセスアップにオートリンクネット リンクが自動で増殖オートリンクの登録はこちら 節約内職情報検索局
ページランク向上リンク集
役立つリンク集 Web Links
SEO対策ディレクトリ型検索エンジン Su-Jine
メニュー
トップ
アマグラミング
C++編 目次
第7章
第9章
ソフトウェア開発製品
相互リンク

<勘違いだらけのアマグラミングな日々(C++編)>

第8章 選択肢を与える(2)

2006年9月6日

前章でメニューを追加して、多少なりとも見栄えが良くなった(?)と思うので、調子に乗ってツールバーステータスバーを追加してみることにした。

<何もしないWindowのサンプル>左図が完成イメージになるわけだが、いやはや、思いつくままにボタンを追加していったものだから、これだけでなにか出来そうな錯覚に陥る。

しかして実際は、なんの機能も与えられていないボタンばかりなので、これまた何の役にも立たないWindow枠なのである。
これだけ賢覧豪華に(?)作りこんでやるのに役立たずとは、これまた困ったものだ(??)。

さて、それでは早速(違う)Win32APIを駆使して、ツールバーとステータスバーを付け足してみよう。

ああ、さくっといくと思ったのに・・・のソースは次のとおり。

List.001-010
main_window.h
main_window.cpp
main_callback.h
main_callback.cpp
main_menu.h
main_menu.cpp
main_menu.rc
<ソースのダウンロード>

そもそも、ツールバーとステータスバーを一緒くたに扱おうと思ったのは、このふたつ、よく似た実装方法だから。
とは云え、別々に扱って原稿を水増ししようと企んだところ、進行が遅いとの内外から生じたプレッシャーによってこうなったことも、また事実である。
話を戻そう。
実装の具体的な方法としては、関数CreateTollbarEx()関数CreateStatusWindow()で、ツールバーとステータスバーを生成してやればよいらしい。
因みにこの二つのWin32API標準関数は"Windows.h"には含まれていないとのこと。
別途、"commctrl.h"をインクルードしてやる必要があるのだ。
あと、それぞれ呼び出しには色々と前準備が必要で、なかなかに長いコードとなる為、オリジナルの関数SetToolbar()関数SetStatusWindow()を用意してまとめてみた。

そして、それぞれの関数をWM_CREATEメッセージによって処理することになる。
このメッセージは、アプリケーションのWindowが生成される時にWindowsOSから送られてくるらしい。

さて、ひととおりコーディングが済んだところで早速コンパイル。
出来上がる実行ファイルに思いをはせながら(大袈裟)コンパイラの作業が終わるのを待っていると、ああ、なんということか、リンカがわあわあと騒ぎ立てながら作業を止めてしまう。
未解決の文字がわらわらと湧き出ている。
意気消沈して資料を調べてみると、"comctl32.lib"をリンカに登録せよとある。
はぁ、そうですか、と気を取り直して登録作業を行い、リコンパイル。
今度はうまくコンパイルできたようだ。
しかし、こういう作業は常識なんだろうか?毎度ながら自分の無知に振り回され、どっと疲れてしまう。
忘れないようにコメントに入れておこう。

さて、やっと出来上がった実行ファイル、早速ダブルクリックすると画面には立派な(?)ツールバーとステータスバーが付いたWindow枠が現れた。
なんにも起きないとは知りつつも、折角作ったボタン類をポチポチクリックするのは楽しい。
因みに、ツールバーのボタンはメニューと密接な関係があり、ボタンを押すとWM_COMMANDメッセージがOSから送られてくる。
ステータスバーにしてもサイズ変更グリップを付けたので、こちらもドラッグしてWindow枠のサイズ変更をしてみる。
と、ここでまたまたトラブル。
ああ、前章のメニューのお手軽さはどこへやら、どんなトラブルだったのか文章で書く気にもならないので、こちらの画像を参照していただきたい。

もちろんこんな致命的なバグをほっとくわけにもいかないので、修正を施す必要がある。
その時の右往左往は省略させて頂いて、修正版のソースを次に挙げさせていただく。

List.001-011
main_window.h
main_window.cpp
main_callback.h
main_callback.cpp
main_menu.h
main_menu.cpp
main_menu.rc
<ソースのダウンロード>

今回のトラブルでまざまざと思い知らされたのは、ツールバーもステータスバーも子Windowであると云うこと。
メインとなる親Windowのサイズが変わったところで、こいつらには全く関係の無い出来事なのだ。
Window枠の機能として提供されているメニューとは、根本的に別の要素なのである。

従って、今回のバグ取りとして施さなければならない処置は、ツールバーとステータスバーがそれぞれ独立したWindowであることを尊重し(?)大きさと位置を適切に変更してやることである。
適切な大きさと位置を指示する為には、まず親Windowの大きさ、特に今回はクライアントエリアと呼ばれる真中の白い領域(今回のサンプルの場合)のサイズを知る必要がある。
これは、Win32API標準関数である関数GetClientRect()によって調べることができ、RECT構造体にポインタ渡しされた結果かから判るわけだ。
次に、これを元にして関数MoveWindow()を使ってそれぞれのサイズと位置を変更してやる。

では、いつ変更してやる必要があるかだが、これは当然親Windowのサイズが変更された時である。
ここで登場するのがWM_SIZEメッセージ
Windowのサイズが変更されると、親切なOSがこのメッセージを送ってくれるので、このメッセージに対応した処理として上記サイズ変更の処理を行ってやろう。
更におせっかいな(?)WindowsOS君はlParamに変更後の横幅を入れて戻してくれるので、これを利用させていただくことにする。
以上の修正を施せば、晴れてツールバーとステータスバーが正常に実装されたWindow枠が出来上がるわけだ。

こうしてWindow枠への化粧を少し覚えた。
特にツールバーとステータスバーはコモンコントロールと呼ばれる要素で、他にも幾種類か仲間が存在する。
しかし、この調子でひとつひとつ実験していたのでは、私の身(忍耐)がもちそうに無い。
そこで、次回からはアプリケーションとしての中身を実装していこうと思う。
少しは面白い内容になることを祈って・・・

<前章> <目次>





<時乃工房>
Net Office Nakai
メビウスリング投稿掲示板には小説日記ゲームアニメコミック小学生中学生などの掲示板過去ログがあります。相互リンクも募集中。