開発者なら誰でも夢見るクロスプラットフォーム。
wxWidgetsはそんな夢をかなえてくれるハイテンションなツールキット。
プラットフォーム(OS)毎にラッパーのように機能し、プラットフォームスイートなGUIを実現してくれる。
2.8.4 リファレンス wxWidgets 2.8.4: A portable C++ and Python GUI toolkit
【参考】
、、、これからMFCを覚えるのも、、そんな感情も抱きながら、、。
「Downloads - wxWidgets」のページに移動する。
私が訪問したとき(2008/03/09)の安定版は 2.8.7 でした。
「SourceForge.net」のページに飛んで、ダウンロードが始まります。
ちなみに私は、「(other formats: zip)」の zip版をダウンロードしてみました。
ちなみに私のビルド環境はVS2005である。
解凍後のディスクに占める容量は106MB
ファイル数 6,067
フォルダ数 515
と少々大きいものとなった。
ビルド環境がVS2005であるので、wx.dswはじめ各ビルドファイルの保存形式が異なるため更新が求められる。
すべてYESとし、環境を取り込む。
以下のようにプロジェクトファイルが再構成された。
元のファイル名 | 更新後のファイル名 | |
---|---|---|
wx.dsw | → | wx.sln |
wx_wxregex.dsp | wx_wxregex.vcproj | |
wx_wxzlib.dsp | wx_wxzlib.vcproj | |
wx_wxpng.dsp | wx_wxpng.vcproj | |
wx_wxjpeg.dsp | wx_wxjpeg.vcproj | |
wx_wxtiff.dsp | wx_wxtiff.vcproj | |
wx_wxexpat.dsp | wx_wxexpat.vcproj | |
wx_base.dsp | wx_base.vcproj | |
wx_net.dsp | wx_net.vcproj | |
wx_core.dsp | wx_core.vcproj | |
wx_adv.dsp | wx_adv.vcproj | |
wx_media.dsp | wx_media.vcproj | |
wx_odbc.dsp | wx_odbc.vcproj | |
wx_dbgrid.dsp | wx_dbgrid.vcproj | |
wx_html.dsp | wx_html.vcproj | |
wx_qa.dsp | wx_qa.vcproj | |
wx_xml.dsp | wx_xml.vcproj | |
wx_xrc.dsp | wx_xrc.vcproj | |
wx_aui.dsp | wx_aui.vcproj | |
wx_richtext.dsp | wx_richtext.vcproj | |
wx_gl.dsp | wx_gl.vcproj |
なお、コンパイルに当たっては以下のwarningがいくつか検出されたが、errorはなくビルドできた。
include\wx/confbase.h : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
include\wx/generic/helpext.h : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
..\..\src\generic\dcpsg.cpp(1835) : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
..\..\src\generic\progdlgg.cpp : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。 include\wx/generic/progdlgg.h : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
include\wx/fileconf.h : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
..\..\src\msw\thread.cpp(545) : warning C4535: _set_se_translator() の呼び出しは /EHa が必要です。
..\..\src\common\string.cpp(1041) : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
..\..\src\common\regex.cpp : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。 include\wx/regex.h : warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。
Microsoft Visual Studio 2005(Version 8.0.50727.42)
(MFC使えばっ、て感じかもしれませんが、、)
「ファイル」-「新規作成」-「プロジェクト」を選択する。
左ペインの「プロジェクトの種類」で「Visual C++」-「全般」を選択し、右ペインの「テンプレート」の中から「空のプロジェクト」を選択する。
ダイアログ下方の「プロジェクト名」に「wxHelloWorld」と入力します。
好みにもよりますが、このチュートリアルでは作成しないこととします。
後述する「wxHelloWorld.cpp」を「wxHelloWorld」のディレクトリに作成し、ソースファイルに追加します。
この時点で以下のようなディレクトリ構成になるようにして下さい。
wxHelloWorld/wxHelloWorld.sln /wxHelloWorld.vcproj /wxHelloWorld.cpp wxMSW-2.8.7/include /lib . .
(※作業ごとに更新される「*.ncb」、「*.user」、「*.suo」は省略しています。)
プロジェクトのプロパティを開き、以下の項目を設定します。
Debug|Win32 | Release|Win32 | ||||
---|---|---|---|---|---|
構成プロパティ | C/C++ | 全般 | 追加のインクルードディレクトリ | ..\wxMSW-2.8.7\lib\vc_lib\mswd;..\wxMSW-2.8.7\include | ..\wxMSW-2.8.7\lib\vc_lib\msw;..\wxMSW-2.8.7\include |
デバッグ情報の形式 | エディット コンティニュ用プログラム データベース (/ZI) | 無効(そのまま) | |||
警告レベル | レベル 4 (/W4) | ||||
最適化 | 最適化 | 無効 (/Od) | 実行速度 (/O2)(そのまま) | ||
コード生成 | ランタイム ライブラリ | マルチスレッド デバッグ DLL (/MDd) | マルチスレッド DLL (/MD) | ||
リンカ | 全般 | 追加のライブラリ ディレクトリ | ..\wxMSW-2.8.7\lib\vc_lib | ||
入力 | 追加の依存ファイル | wxbase28d.lib wxmsw28d_core.lib RpcRT4.Lib ComCtl32.Lib | wxbase28.lib wxmsw28_core.lib RpcRT4.Lib ComCtl32.Lib | ||
デバッグ | デバッグ情報の生成 | はい (/DEBUG) (自動的に「プログラム データベース ファイルの生成」の項目に「$(TargetDir)$(TargetName).pdb」が設定されます。) |
いいえ(そのまま) |
以上でプロジェクトの設定は終了です。「wxHelloWorld.cpp」が作成できたら、ビルド、実行してみましょう。
【補足】
※wxbase28d.lib/wxbase28.libのリンクで以下の参照が解決されるようです。
※wxmsw28d_core.lib/wxmsw28_core.libのリンクで以下の参照が解決されるようです。
基本的に本家サイトのチュートリアル(英語)「'Hello world' in wxWidgets: A Very Short Tutorial」と同じ内容です。
Fancyな翻訳、、+α?、という感じです。
ファイル名を「wxHelloWorld.cpp」とし、以下のコーディングを行います。
ヘッダファイルは個別にインクルードしてもいいんですが、「wx.h」をインクルードすると一通りインクルードしてくれるようです。
#include "wx/wx.h"
wxApp クラスを継承し、HelloWorldアプリケーション用のサブクラス HelloWorldApp を定義する。
特に、OnInit() (アプリケーションの初期化)をオーバーライド(再定義)します。
class HelloWorldApp : public wxApp { virtual bool OnInit(); };
wxFrame クラスを継承し、メインウィンドウのクラス MainFrame を定義する。
ちなみにメインウィンドウには、メニューとステータスバーを持たせることになってます。(後述)
また、メニューからのイベント受信にイベントテーブルを使用するので、それを宣言するようです。
DECLARE_EVENT_TABLE() マクロを記述すればいいようです。
class MainFrame : public wxFrame { public: MainFrame( const wxString& title, const wxPoint& pos, const wxSize& size); void OnQuit( wxCommandEvent& event ); void OnAbout( wxCommandEvent& event ); DECLARE_EVENT_TABLE() };
メニューとして「終了」と「「Hello World!」について」を用意する予定なので、メニューと各ハンドラ関数を繋ぐためのこれらのIDを定義する。
enum { ID_QUIT = 1, ///< 終了 ID_ABOUT, ///< ~について };
BEGIN_EVENT_TABLE() と END_EVENT_TABLE() のマクロによってイベントテーブルの宣言をするようである。
また、メニューのイベント定義は EVT_MENU() マクロを使用するようである。
BEGIN_EVENT_TABLE( MainFrame, wxFrame ) EVT_MENU( ID_QUIT, MainFrame::OnQuit ) EVT_MENU( ID_ABOUT, MainFrame::OnAbout ) END_EVENT_TABLE()
wxWidgets では、IMPLEMENT_APP() マクロによって、main()関数からアプリケーションのインスタンスが生成され、初期化( OnInit() )が行われるらしいです。
IMPLEMENT_APP( HelloWorldApp )
続く、、、
続きです。
OnInit() では、メインウィンドウを生成します。
インスタンス化に成功したら、ウィンドウの表示です。
また、アプリケーションのトップレベルウィンドウに設定します。
bool HelloWorldApp::OnInit() { MainFrame *p_frame; bool result; p_frame = new MainFrame( _T("Hello World!"), wxPoint(40,40), wxSize(400,300) ); if ( p_frame ) { p_frame->Show( TRUE ); SetTopWindow( p_frame ); result = TRUE; } else { result = FALSE; } return result; }
MainFrame のコンストラクタでは、メニューとステータスバーの各パーツを設定します。
MainFrame::MainFrame( const wxString& title, const wxPoint& pos, const wxSize& size ) : wxFrame( (wxFrame *)NULL, -1, title, pos, size ) { wxStatusBar *p_status_bar; wxMenu *p_menu_file; wxMenuBar *p_menu_bar; bool result; result = FALSE; p_status_bar = CreateStatusBar(); p_menu_file = new wxMenu; p_menu_bar = new wxMenuBar; if ( p_menu_file && p_menu_bar ) { p_menu_file->Append( ID_ABOUT, _T("「Hello World!」について(&A)") ); p_menu_file->AppendSeparator(); p_menu_file->Append( ID_QUIT, _T("閉じる(&X)") ); p_menu_bar->Append( p_menu_file, _T("ファイル(&F)") ); SetMenuBar( p_menu_bar ); result = TRUE; } if ( p_status_bar ) { if ( result ) { SetStatusText( _T("はぁ、できました、、。") ); } else { SetStatusText( _T("あれ?だめでした?") ); } } }
Close() 関数でウィンドウを閉じます。
void MainFrame::OnQuit( wxCommandEvent& WXUNUSED( event ) ) { Close(TRUE); }
ここではメッセージボックスを出すだけです。
OKボタンとインフォメーションアイコンを表示するようにしてます。
void MainFrame::OnAbout( wxCommandEvent& WXUNUSED( event ) ) { wxMessageBox(_T("Hello World のサンプルです。"),_T("「Hello World」について"), wxOK | wxICON_INFORMATION, this); }
wxWidgetsを使用する上での小技集です^^
Windows向けの wxWidgets は「WinMain()」をエントリポイントとしているようで、
そのままではコンソールアプリケーション(CUI)を作成できません。
(wxPrintf()等、stdin/stdout の処理が無効となるようです。)
Win32 APIの AllocConsole() 等を使用すればコンソールを作成できますが、
AllocConsole() は wxWidgets 内に実装されておらず、直接呼ぶことになります。
Win32 APIを直接呼ぶのでは、wxWidgets を使用する意図から外れてしまいます。
また、コンソールから実行された場合に対応できません。(おそらく、、。)
以下ではそれを解決します。
プロジェクトのプロパティを開き、【構成プロパティ】-【リンカ】-【システム】-【サブシステム】を以下に変更します。
コンソール (/SUBSYSTEM:CONSOLE)
main()関数を以下の様に実装します。
int main(int argc,char *argv[]) { return wxEntry( argc, argv ); }
なお、【サブシステム】を
Windows (/SUBSYSTEM:WINDOWS)
にすると、main()関数の実装は無視され、通常のGUIアプリケーションとして機能します。