★☆=====================================================================☆★ 【wxWindowsでGUIプログラミング】 第3号:Hello World を飾ろう 2003.06.01(Sun) ★☆=====================================================================☆★ こんにちは,二条です。 前回のアンケートは,ソースをWeb上に置いたほうがいいという方3名,メルマガに載せたほうがいいという方8名という結果になりました。ご解答いただいた方,どうもありがとうございました。 前回の発行部数は320部ぐらいだったのですが,反応が少なかったので,どちらでもよいという方が多いのかな,と勝手に思っております。 Web上に置いたほうがいいとご解答いただいた方には申し訳ありませんが,しばらくはこのままのスタイルで発行して行こうと思います。そのうち,どうしようもなくソースが長くなってきたら,メルマガを2種類に分けるなどの対策を考えます。 今回は,もう少し詳しいアンケートを用意いたしました。次回以降のメルマガの内容の参考にさせていただきますので,ご協力をお願いします。 アンケートはこちら。 http://members10.tsukaeru.net/ariera/soft/wx_question.html 今回は,前回の「Hello World」にさらに手を加えてみます。 今回の内容は,前回の内容を前提として進めますので,初購読の方はお手数ですが,バックナンバーを参考にしてくださいませ。 バックナンバーは,まぐまぐのサイト http://www.mag2.com/m/0000108320.htm で見ることができます。 また, http://members10.tsukaeru.net/ariera/soft/wx.html こちらにダウンロード用のテキストファイルも用意してあります。(個人サイトの方はいろいろ不具合があったりもしますが,気づき次第修正しています。) ------------------------------------------------------------------------ (1)背景色を変える 前回の一番最後のプログラムに,手を加えてみます。 プログラムの最後の方, HelloWorldFrame::OnHelloWorldButton(wxCommandEvent &event) の実装部分の,wxMessageBox の前に,次の2行を加えて,コンパイル・実行してみてください。 SetBackgroundColour(wxColor("RED")); Refresh(TRUE, NULL); 「こんにちは」ボタンを押すと,背景が赤に変わるはずです。 そのあと,ダイアログボックスが出るのは,前回のままです。 SetBackgroundColour は,wxWindow クラスのメンバー関数で,背景色を変更するためのものです。 ※wxWindowクラスは,wxFrame や wxButton などのクラスの基底クラス(親クラス)になっています。 HelloWorldFrame::OnHelloWorldButton の中で呼び出していますので,呼び出し元のインスタンスを明示的に書かなければ,OnHelloWorldButton を呼び出している HelloWorldFrame のインスタンスに対して,この関数が実行されます。従って,外側の枠の背景色が変更されます。 引数は,wxColor クラスのインスタンスです。wxWindowsでは,英国式に wxColour となっていますが,米国式 wxColor でもどちらでも使えるようです。色の指定は,wxColour(red=0, green=0, blue=0) のように,RGB値(0-255)で指定する方法と,wxColor("RED")のように,色名を指定する方法の2種類があります。 色名は,wxWindows2.4.0のマニュアルによると,以下のものが使えます。 AQUAMARINE, BLACK, BLUE, BLUE VIOLET, BROWN, CADET BLUE, CORAL, CORNFLOWER BLUE, CYAN, DARK GREY, DARK GREEN, DARK OLIVE GREEN, DARK ORCHID, DARK SLATE BLUE, DARK SLATE GREY DARK TURQUOISE, DIM GREY, FIREBRICK, FOREST GREEN, GOLD, GOLDENROD, GREY, GREEN, GREEN YELLOW, INDIAN RED, KHAKI, LIGHT BLUE, LIGHT GREY, LIGHT STEEL BLUE, LIME GREEN, MAGENTA, MAROON, MEDIUM AQUAMARINE, MEDIUM BLUE, MEDIUM FOREST GREEN, MEDIUM GOLDENROD, MEDIUM ORCHID, MEDIUM SEA GREEN, MEDIUM SLATE BLUE, MEDIUM SPRING GREEN, MEDIUM TURQUOISE, MEDIUM VIOLET RED, MIDNIGHT BLUE, NAVY, ORANGE, ORANGE RED, ORCHID, PALE GREEN, PINK, PLUM, PURPLE, RED, SALMON, SEA GREEN, SIENNA, SKY BLUE, SLATE BLUE, SPRING GREEN, STEEL BLUE, TAN, THISTLE, TURQUOISE, VIOLET, VIOLET RED, WHEAT, WHITE, YELLOW, YELLOW GREEN 次の Refresh も,wxWindow クラスのメンバー関数で,画面を書きなおすためのものです。これがないと,画面を再描画しないので,色を設定しても次に画面が再描画されるまで,色の変更は反映されなくなってしまいます。 ためしに,Refresh をなくして,コンパイル・実行して「こんにちは」ボタンを押してみてください。何も起こりませんね。次に,HelloWorld プログラムをたちあげたまま,別のプログラム(エディタでもIEでも何でも)をたちあげて,HelloWorld プログラムの上に重ねて,それから元に戻してみてください。そうすると,重なっていた場所の背景色は赤に変わっているはずです。なぜこうなるかというと,ウインドウの重なり状態が変ると,OSが画面を再描画するためです。 Refresh の一つ目の引数は,背景を再描画するかどうかを指定します。TRUE の場合は背景を再描画しますが,FALSE の場合は,背景は再描画せず,文字などの上に載っているものだけを再描画します。 二つ目の引数は,wxRect型の引数で,NULLでない場合は指定したrectangle(長方形の領域)だけを再描画します。NULLの場合は全体を再描画します。 ------------------------------------------------------------------------ (2)ボタンの色を変える (1)と同じようにして,ボタンの色も変えてみましょう。(1)で追加した Refresh の直前に,次の2行を追加してみてください。 helloWorldButton->SetBackgroundColour(wxColor("BLUE")); closeButton->SetBackgroundColour(wxColor("VIOLET")); 今度は,「こんにちは」ボタンを押すと,背景だけでなく,ボタンの色も変わります。 (配色がかなり気持ち悪いですが,あまり気にしないでください。) フレームの背景色を変えたときとの違いは,helloWorldButton-> というように,呼び出し元のインスタンスを指定していることです。 helloWorldButton は,HelloWorldFrame のメンバー変数で,型は wxButton のポインタ,実体は HelloWorldFrame のコンストラクタで作っています。wxButton も,wxWindow を継承したクラスなので, wxWindow クラスのメンバー変数が使えます。 前回の(3)で, 『また,ボタンのポインタを HelloWorldFrame のコンストラクタのなかで宣言していましたが,これではコンストラクタを抜けるとポインタは消えてしまいます。(ボタンの実体は残っていますが。) ボタンの色を変えたり文字を変えたりといった処理をするにはポインタが必要です。部品IDではこれらの処理はできません。』 というようなことを書きましたが,前回の(2)までのようにボタンのポインタをメンバー変数にしないでおくと, helloWorldButton->SetBackgroundColour(wxColor("BLUE")); のような形でボタンの色を変えることができなくなってしまいます。 ------------------------------------------------------------------------ (3)ボタンいろいろ ついでなので,Refresh の直前に,さらに以下の文を追加してみてください。 helloWorldButton->SetFont(wxFont(10, wxROMAN, wxNORMAL, wxNORMAL, FALSE, "HG正楷書体-PRO", wxFONTENCODING_SYSTEM)); closeButton->SetForegroundColour(wxColor("WHITE")); closeButton->SetLabel(_T("終了")); 最初の setFont は,文字のフォントを変える関数で,wxWindow クラスのメンバー関数です。Windowsで,HG正楷書体-PRO のフォントが入っている方は「こんにちは」ボタンを押すと「こんにちは」ボタンの文字のフォントが変わったと思います。フォントが入っていない場合はデフォルトのフォントが使われるので,変化はありません。ご自分のシステムにはいっているフォント名を入れて試してみてください。 引数は wxFont 型で,wxFont を作るのに必要なパラメータ(コンストラクタの引数)は,サイズ(point),フォントファミリー,フォントスタイル,太さ,アンダーライン,フォント名,エンコード となっています。マニュアルにはそれぞれ詳しく説明が載っていますが,ここでは説明しません。 次の SetForegroundColour は前景色(文字色)を変える関数で,これもwxWindow クラスのメンバー関数です。引数は背景色の場合と同じなので,説明はいらないでしょう。この例では,「こんにちは」ボタンをクリックすると「さようなら」ボタンの文字色が白になります。 setFont と SetForegroundColour は,wxWindow クラスのメンバー関数なので,wxWindow クラスの継承クラスであれば,どこからでも呼び出すことができます。たとえば,wxFrame に文字を書いた場合は,そのフォントと色を変えるのに使うこともできます。 最後の SetLabel は wxButton のメンバー変数で,ボタンのラベルを変更することができます。この例では「こんにちは」ボタンをクリックすると「さようなら」ボタンのラベルが「終了」に変わります。 ------------------------------------------------------------------------ (4)さらにしつこくボタンをいじる Refresh の直前に,さらに以下の文を追加してみてください。 if(closeButton->IsEnabled()) { closeButton->Enable(FALSE); } else { closeButton->Enable(TRUE); } 「こんにちは」ボタンを一度押してから,「さようなら」ボタン改め「終了」ボタンを押してみてください。何も起こらなくなりました。これはボタンが無効になっているためです。(ボタンの色をデフォルトにもどすとわかりやすいかもしれません。) もういちど「こんにちは」ボタンを押してから「終了」ボタンを押すと,今度は終了するはずです。 IsEnabled は,ボタンやフレームなどが有効になっているかどうかをチェックする関数で,wxWindow クラスのメンバー関数です。有効になっている場合は TRUE 無効になっている場合は FALSE を返します。 そして,Enable は,ボタンやフレームなどを有効/無効にする関数です。これもwxWindow クラスのメンバー関数です。引数が TRUE の場合は有効に,FALSE の場合は無効に設定します。この例では使っていませんが,この関数は戻り値を持っていて,状態が有効->無効,無効->有効に変わった場合はTRUE,元の状態と同じ状態に設定されたため変わらなかった場合は FALSE を返します。 また,Enable(FALSE) と全く同じ動作をする Disable(引数なし) という関数もあります。 これで,上のコードが何をしているかわかると思います。 このコードは,「こんにちは」ボタンを押したときに「さようなら」または「終了」ボタンが有効になっていれば無効に,無効になっていれば有効に変更します。 初期状態では,「さようなら」ボタンは有効になっていますので,「こんにちは」ボタ ンを押すと closeButton->IsEnabled() は TRUE となり,closeButton->Enable(FALSE); が実行されます。次に「こんにちは」ボタンを押すと closeButton->IsEnabled() は FALSE となり,closeButton->Enable(TRUE); が実行されます。 ------------------------------------------------------------------------ 今回はこれで終わりです。メニューバーやツールバー,リソースファイルなどにも触れようかと思っていたのですが,長くなりそうなので次回以降にします。 だいたい,wxWindows のイメージはつかめてきたと思いますので,次回からは実践プログラム編(数回でひとつのプログラムを完成させる)と,基礎知識編(wxWindowsのクラスや関数の解説)の2本立てにしようかと考えています。冒頭にも書きましたが,次回以降の参考にさせていただきますので,ぜひアンケートにご協力ください。よろしくお願いします。 アンケートはこちら。 http://members10.tsukaeru.net/ariera/soft/wx_question.html 編集後記: 久々に18時間睡眠をやらかしてしまいました。金曜日の夜,疲れていたので21時ごろに帰宅してすぐにバタンキュー,翌日起きたら15時過ぎでした。別にそれまで特別忙しかったというわけでもないのですが,怠け者は怠けるチャンスだけは無駄にしないんですね(笑) まあ,雨がひどかったらしいので,早起きしても外に遊びにいけたわけではなし……と勝手に自己正当化しています。 次回発行日は2003.6.15(日)の予定です。 ★☆=====================================================================☆★ メールマガジン:wxWindowsでGUIプログラミング 第3号 2003.06.01(Sun) 発行人:二条 ご意見・ご感想はこちらへ: ariera@members10.tsukaeru.net 解除・バックナンバーはこちらからどうぞ http://members10.tsukaeru.net/ariera/soft/wx.html マイサイト「気まぐれ歴史散歩」もよろしくお願いします http://members10.tsukaeru.net/walk/ このメールマガジンは「まぐまぐ」を使って配信しています http://www.mag2.com/ ★☆=====================================================================☆★