トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

wxWidgets

[Research]

wxWidgetsでOpenGL

wxWidgetsはクロスプラットフォームなGUIライブラリです.ネイティブなUIを使うので,それっぽいプログラムが作れます.いろいろ多機能.

このページでは,インストール,コンパイル,実際のプロジェクトの生成までを解説します.

せっかくのクロスプラットフォームだけど,まったくそれを生かさず,M$ W!ndowz とVisualC++.net にべったりな内容を記します.

スタティックリンクの Unicode で,マルチスレッド(/MT) でいきます.つまり,実行時にDLLを必要としない形式です.

インストールとコンパイル

wxWidgets(旧称:wxWindows)のインストールについてのメモ.

  • OpenGLを使う.
  • バージョンは,最新の安定版である2.6.1.

コンパイル済みの"*.lib"は,田村が持っているので,欲しい人は言うように.

 インストール VisualC++.net2003(VC7.1) - wxWidgets2.6.1

配布ファイル同梱のINSTALL-MSW.txtに従う.

ここも参考になるでしょう.http://wiki.wxwidgets.org/wiki.pl?MSVC_.NET_Setup_Guide

入手

本家配布サイト より,zipかexe形式のファイルをダウンロード.zipファイルをダウンロードした場合は,適宜展開してください.実行ファイルをダウンロードした場合は,インストーラの指示に従って展開してください.環境変数WXWINへ展開したディレクトリを登録します.(以下,展開ディレクトリを,$(WXWIN)として表記します)注意事項:パスに空白を含む場所には展開しないでください.

コンパイル

  1. 「$(WXWIN)/build/msw/wx.dsw」 を開きます.
    1. VC6用のファイルなので,vc7で開くときは変換する必要があります.
    2. 確認ダイアログがでるので,「すべてはい」を選んでください.
  2. OpenGLを使うために,「setup.h」の「#define wxUSE_GLCANVAS」を「1」にします(2.6.1では885行目).
  3. 「|> Unicode Debug」
  4. 「|> Unicode Release」
    1. スタティックライブラリにするために,各プロジェクトのプロパティで「C/C++」>「コード生成」>「ランタイムライブラリ」を「マルチスレッド デバッグ(/MTd)」or「マルチスレッド(/MT)」にする.
      1. ソリューションエクスプローラで全部を選択(Shift+クリック)して,プロパティをいじると一度にすべてのプロジェクトのプロパティを設定できます.
  5. ソリューションをビルドする.

コンパイル後のファイルは以下の場所に生成されます.$(WXWIN)/lib/vc_lib$(WXWIN)/lib/vc_dll

注意(1)
テンプレートを使うときは,「include\wx\msw\setup.h」を編集して,「wxUSE_DEBUG_NEW_ALWAYS」を「0」にしてください.これをしない場合は,'new'の再定義という問題が生じます.代わりに「#undef new」をテンプレートヘッダをインクルードするまえに行ってもいいんじゃない.テンプレート使うときは,「wxUSE_IOSTREAMH」を「0」にする必要もあるだろうね.

プロジェクトの設定(2.6.1+Unicode+StaticLibrary)

sample/penguin を参考にしました.

 プロジェクトの新規作成

  • Win32プロジェクト
    • 空のプロジェクトを作成

 プロジェクトのプロパティ

すべての構成

  • 全般
    • 文字セット
Unicode文字セットを使用する
  • C/C++
    • 詳細
      • コンパイル言語の選択
規定値
  • リンカ
    • 全般
      • 追加のライブラリディレクトリ
$(WXWIN)/lib/vc_lib

デバッグ

  • C/C++
    • 全般
      • 追加のインクルードディレクトリ
$(WXWIN)/include;$(WXWIN)/lib/vc_lib/mswud
    • プリプロセッサ
      • プロセッサの定義
WIN32;_DEBUG;_WINDOWS;__WXMSW__;__WXDEBUG__
    • コード生成
      • ランタイムライブラリ
マルチスレッド デバッグ(/MTd)
  • リンカ
    • 入力
      • 追加の依存ファイル(改行してますが1行で入力してください)
wxmsw26ud_gl.lib opengl32.lib glu32.lib wxmsw26ud_core.lib wxbase26ud.lib
wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.lib wxregexud.lib wxexpatd.lib
comctl32.lib rpcrt4.lib

リリース

  • C/C++
    • 全般
      • 追加のインクルードディレクトリ
$(WXWIN)/include;$(WXWIN)/lib/vc_lib/mswu
    • プリプロセッサ
      • プロセッサの定義
WIN32;NDEBUG;_WINDOWS;__WXMSW__
    • コード生成
      • ランタイムライブラリ
マルチスレッド(/MT)
  • リンカ
    • 入力
      • 追加の依存ファイル
wxmsw26u_gl.lib opengl32.lib glu32.lib wxmsw26u_core.lib wxbase26u.lib
wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib wxregexu.lib wxexpat.lib
comctl32.lib rpcrt4.lib

実際にプログラムで使うとき

「編集」「検索と置換」「シンボルの検索」「検索対象」「選択されたコンポーネント」に $(WXWIN)/lib/wxWindows.bsc を追加

TIPS

wxWidgetsに関するメモとか調べたことなど.あと,プログラムに関するメモなども.

 イベント(wxWidgets)

メニューイベントなどは,以下のようなイベントテーブルで定義する.クラス宣言部に

DECLARE_EVENT_TABLE()

.cppの方に

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 EVT_MENU( ・・・ )
END_EVENT_TABLE()

で,これらは実際何をしているのか? DECLARE_EVENT_TABLEとかBEGIN_EVENT_TABLEはdefineされたものであろうと考えられるので,調べてみるとevent.hに以下のような記述がある.

#define DECLARE_EVENT_TABLE() \
   private: \
       static const wxEventTableEntry sm_eventTableEntries[]; \
   protected: \
       static const wxEventTable        sm_eventTable; \
       virtual const wxEventTable*      GetEventTable() const; \
       static wxEventHashTable          sm_eventHashTable; \
       virtual wxEventHashTable&        GetEventHashTable() const;
#define BEGIN_EVENT_TABLE(theClass, baseClass) \
   const wxEventTable theClass::sm_eventTable = \
       { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \
   const wxEventTable *theClass::GetEventTable() const \
       { return &theClass::sm_eventTable; } \
   wxEventHashTable theClass::sm_eventHashTable(theClass::sm_eventTable); \
   wxEventHashTable &theClass::GetEventHashTable() const \
       { return theClass::sm_eventHashTable; } \
   const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
#define END_EVENT_TABLE() DECLARE_EVENT_TABLE_ENTRY( wxEVT_NULL, 0, 0, 0, 0 ) };
#define EVT_MENU(winid, fn) wxEventTableEntry(wxEVT_COMMAND_MENU_SELECTED,\
 winid, wxID_ANY, (wxObjectEventFunction)(wxEventFunction)\
 wxStaticCastEvent( wxCommandEventFunction, & fn), (wxObject *) NULL ),

DECLARE_EVENT_TABLEでイベントテーブル用の変数(sm_eventTableEntriesとか)を定義して,BEGIN_EVENT_TABLEからEND_EVENT_TABLEの間で配列sm_eventTableEntriesにイベントテーブルを定義している.定義内容は,例えばEVT_MENUなら,

  1. wxEVT_COMMAND_MENU_SELECTED : イベントの種類.この場合,メニューが選択されたとき呼ばれる.
  2. winid : イベントID.自分で定義したものなど.
  3. fn : イベントが発生したときに呼ばれる関数.

ちなみにイベントテーブルは配列sm_eventTableEntriesに書かれているので,定義されたイベント数は,この配列の大きさを調べれば分かる.

event_num = WXSIZEOF(sm_eventTableEntries);

 イベントの動的追加(wxWidgets)

上記にあるようにイベントは,静的に定義される.しかし,後から追加するなど動的に追加したい場合もある.この場合,イベントハンドラクラス(wxEvtHandler)のConnect関数を用いる.

wxEvtHandler* handle = GetEventHandler();
handle->Connect(id, wxEVT_COMMAND_MENU_SELECTED, fn);

イベントタイプ(wxEVT_COMMAND_MENU_SELECTED)は,コマンドイベントに関してはwxCommandEvent参照.

 カスタムイベント(wxWidgets)

wxで定義されていないユーザ独自のイベントを作りたい場合,その方法は,オフィシャルマニュアル(Event handling overviewの下の方Custom event summary)に書かれている.wxWikiには,このほかの方法も書かれているのでそちらを参考にしてみるといいかも.

 RTTI

オフィシャルマニュアルでRTTI(run-time type identification)というのが出てくる.RTTIは日本語では,実行時型情報となり,そのまんま実行時に型の情報を得る機能である.ちなみに,最新のANSI C++ではサポートされているので,

#include <typeinfo.h>

として,

int x = 10;
cout << "type : " << typeid(x).name() << endl;

int x = 10;
if(typeid(int) == typeid(x)){
    xがint型だったときの処理
}

という風に使える.

このRTTIは,どちらかというとクラスのポリモーフィズム(多態性)を使うときに便利である.

 VC++.net2003でインテリセンス(intellisense :入力補完)を使う.

http://www.litwindow.com/Knowhow/Intellisense/intellisense.html

 ほげほげ.

Unicode使うときにやられた.あと trackball.c のようなC言語ファイルで怒られた.このへんに注意すれば後は問題なく使えるかと.

実際にプログラムで使うとき「編集」「検索と置換」「シンボルの検索」「検索対象」「選択されたコンポーネント」に $(WXWIN)/lib/wxWindows.bsc を追加

参考URL

配布元
http://www.wxwindows.org/
wxWiki
http://wiki.wxwindows.org/
wxWindows 日本語プロジェクト
http://wxwindowsjp.sourceforge.jp/
Let's wxWidgets
http://dot-gray.s33.xrea.com/index.xcg?page=FrontPage
wxWindows こうかい日誌
http://www.fiercewinds.net/programming/wxWindows/index.html
wxWindowsで始めるC++ GUIプログラミング
http://www.h3.dion.ne.jp/~k5_n/wxwin/index.html