[wxWidgets] wxWidgets覚え書き

※wxWindow という名前だったと記憶していたが、いつの間にか wxWidgetsに改名したらしい。
 何でも、M$からの圧力だとか…… ヒソヒソ( ´д)ヤダァ(д` )ネェ、キイタ?( ´д)オクサン(д` )アラヤダワァ

wxAuiManager使用時に、Windowをドラッグさせると "Timer creation failed"エラーが発生する

idを指定しない状態で wxTimer をインスタンス化すると発生するようだ。
new wxTimer(pParent, ID_TIMER) ときちんとidを設定する。

Windowが MOUSEWHEEL イベントをキャッチしてくれない

同クラスで、EVT_LEFT_DOWN(マウス左クリックイベント)をキャッチしている場合は、
OnLeftDownイベン内で this->SetFocus() していないのが原因。
フォーカスが当たらないので、イベントが違う Windowに飛ばされている。
※this->SetFocus() の代わりに、event.Skip() を記述しても良い

Win環境でリンク時に"GetClassInfoW"シンボルが無いエラーが出る

リンク時に下記のようなエラーが出るときは、wxのヘッダをインクルードする前に、"wx/msw/winundef.h " をインクルードする
> error LNK2001: unresolved external symbol "public: virtual class wxClassInfo * __thiscall wxObject::GetClassInfoW(void)const " (?GetClassInfoW@wxObject@@UBEPAVwxClassInfo@@XZ)

ソース: #2421 (wxGridTableBase::GetClassInfoA, Windows, linker error) – wxWidgets

wxImage#LoadFile で失敗する

wxInitAllImageHandlers() を発行しているかチェック。

ImageHandlersの初期化を行わないと、画像ファイルの読み込みで失敗してしまう。

Windowを作成する際に、ユニークなIDを取得したい

wxNewId() を使用する。
宣言されているファイルは、wx/utils.h

wxAuiManager はデフォルトで登録された wxWindowインスタンスを Close 時に破棄しない。

破棄したい場合は、AddPane時に明示的に wxAuiPaneInfo().DestroyOnClose(true) を指定する。
※デフォルト動作は逆の方が良いんじゃないか??……

wxAuiManagerに管理されている Window で Closeイベントをキャッチする方法

Closeイベントを持っているwxFrameインスタンスを wxAuiManager#AddPaneに 渡すと、表示の挙動がおかしくなるため、
wxAuiManagerの管理下にあるWindowは、自身ではClose イベントはキャッチ出来ない。
そこで、Closeイベントをキャッチする為には、wxAuiManagerの wxEVT_AUI_PANE_CLOSE イベントを連結してやれば良い。


auiManager_ の Closeイベントを MyPane に連結する
2010/4/28修正。 Connectは非推奨で、Bindの使用を推奨しているらしい

auiManager_.Bind(wxEVT_AUI_PANE_CLOSE, &MyPane::OnClose, pMyPane);

※下記は以前のConnectを使用したバージョン(非推奨)

auiManager_.Connect(wxEVENT_AUI_PANE_CLOSE, wxAuiManagerEventHandler(MyPane::OnClose), 0, pMyPane);

マニュアルには明記していないが、Bindの宣言は下記のようになっている

void Bind(const EventTag &eventType,
              void (Class::*method)(EventArg &),
              EventHandler *handler,
              int winid = wxID_ANY,
              int lastId = wxID_ANY,
              wxObject *userData = NULL)


MyPane側には以下を追加

....
void MyPane::OnClose(wxAuiManagerEvent& event) {
    // do anything...
}

BEGIN_EVENT_TABLE(MyPane, wxPanel)
  EVT_AUI_PANE_CLOSE(MyPane::OnClose)
END_EVENT_TABLE()


wxAuiManagerに複数の MyPane が登録されている時
上記の方法でイベントを登録とすると、wxAuiMakagerに登録されている全てのインスタンスに対して OnClose がコールされてしまう。
選択的に OnClose を行うには、下記の方法をとると良い(と思われる)

1. wxAuiManager に登録するときに、登録するインスタンスアドレスを wxAuiPaneInfo#Window で指定する

auiManager_.AddPane(pMyPane, wxAuiPaneInfo().Window(pMyPane));
auiManager_.Bind(wxEVT_AUI_PANE_CLOSE, &MyPane::OnClose, pMyPane);

2.イベントを受ける側(MyPane)はwxAuiManagerEvent::windowの値を手がかりにする

void MyPane::OnClose(wxAuiManagerEvent& event)
{
    if (this == event.GetPane()->window) {
        // do something...
        return;
    }
    event.Skip();    
}