Contents Up Previous Next

イベント処理の概要

クラス: wxEvtHandler, wxWindow, wxEvent

イントロダクション
イベント処理の仕組み
ユーザの生成したイベントとプログラム的に生成したイベント
動的イベントハンドラ
ウィンドウ識別子
イベントマクロの概要
カスタムイベントの概要


イントロダクション

wxWidgets 2.0 より前のバージョンでは、イベント処理はコールバック関数か、OnSize といった仮想メンバ関数のオーバーライドで実現されていました。

wxWidgets 2.0 からは一部の例外を除き、代わりに イベントテーブル が使用されています。

イベントテーブルはソースファイルに配置され、wxWidgets にイベントとメンバ関数のマッピング方法を知らせます。これらのメンバ関数は非仮想関数ですが、すべて同じ形式をとります: wxEvent を継承した引数をひとつ取り、戻り値の型は void です。

イベントテーブルの例を以下に示します。

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
  EVT_MENU    (DO_TEST,   MyFrame::DoTest)
  EVT_SIZE    (           MyFrame::OnSize)
  EVT_BUTTON  (BUTTON1,   MyFrame::OnButton1)
END_EVENT_TABLE()
最初の 2 つのエントリはメニューコマンドを異なる 2 つのメンバ関数にマッピングしています。EVT_SIZE マクロはウィンドウ識別子を必要としません。なぜなら、通常は現在のウィンドウのリサイズイベントにのみ関心があるはずだからです。

EVT_BUTTON マクロはイベントの発生元がウィンドウクラスである必要がないことを表しています。ウィンドウ階層をたどりながらイベントテーブルを検索するため、イベントの発生元がフレーム内のパネルにあるボタンである場合でも動作します。この場合、まずボタンのイベントテーブルが検索され、続いて、その親パネル、フレームの順に検索されます。

前に述べたように、イベントを処理するメンバ関数は仮想関数である必要はありません。実際に、イベントテーブルはメンバ関数が仮想関数であることを無視する、つまり、仮想メンバ関数を継承クラスでオーバーライドしてもなにも影響を及ぼしません。そのため、メンバ関数を仮想関数にするべきではありません。これらのメンバ関数はイベント引数を取りますが、その引数のクラスはイベントの型と発生元ウィンドウのクラスに応じて異なります。リサイズイベントでは wxSizeEvent が使用されます。メニューコマンドと (ボタン押下といった) 大半のコマンドコントロールでは wxCommandEvent が使用されます。より複雑なコントロールのときには特定のイベントクラスが使用されます。例えば、wxTreeCtrl から発生するイベントには wxTreeEvent が使用されます。

イベントテーブルをソースファイルに配置するように、クラス宣言のどこかに DECLARE_EVENT_TABLE マクロを配置しなければなりません。以下に例を示します:

class MyFrame : public wxFrame
{
public:
  ...
  void OnExit(wxCommandEvent& event);
  void OnSize(wxSizeEvent& event);

protected:
  int       m_count;
  ...

  DECLARE_EVENT_TABLE()
};
このマクロはクラスの任意の場所 (public、protected、private) に配置することができますが、おそらく例示のように最後に挿入する方が良いでしょう。なぜなら、このマクロは暗黙的にアクセス制御を protected に変更してしまうためです。

最後に、マクロを使ってイベントテーブルを静的に初期化したくない場合、wxEvtHandler::Connect を使用して動的に (実行時に) イベントとイベントハンドラを接続することもできます。これを行なっているサンプルとして イベントサンプル を参照してください。


イベント処理の仕組み

ウィンドウからイベントを受信したとき、wxWidgets はイベントを生成したウィンドウに属する最初のイベントハンドラオブジェクトの wxEvtHandler::ProcessEvent を呼び出します。

wxWidgets の行うイベント処理の仕組みは通常の C++ の仮想関数にとても近いことに着目してください。つまり、イベント処理関数をオーバーライドすることでクラスの振る舞いを変更できるということです。ネイティブコントロールの振る舞いを変更するような場合にも、これは動作します。例えば、ネイティブテキストコントロールに送られるキーイベントをフィルタリングする場合、wxTextCtrl をオーバーライドし、EVT_KEY_DOWN を使用してキーイベントハンドラを定義することで実現できます。実際には、これはネイティブコントロールに送られるキーイベントをすべて横取りしますが、これはおそらく期待する動作ではないと思います。この場合、イベントハンドラの検索を続行させるためにイベントハンドラ関数で Skip() を呼ぶ必要があります。

要約すると、C++ の仮想関数で行うように基底クラスの関数を直接呼ぶ (つまり、wxTextCtrl::OnChar() を呼ぶ) 代わりに、 Skip を呼ぶようにしてください。

実際に、テキストコントロールで 'a' から 'z' と 'A' から 'Z' までのみを受け付ける場合、以下のようになります。

void MyTextCtrl::OnChar(wxKeyEvent& event)
{
    if ( isalpha( event.KeyCode() ) )
    {
       // キーコードが正しい範囲に入っている。wxWidgets の規定クラスや
       // ネイティブコントロールでもイベントを処理するため、
       // event.Skip() を呼び出す。

       event.Skip();
    }
    else
    {
       // 対象外のキーが押下された。このイベントを他の場所で処理することはないため、
       // event.Skip() は呼び出さない。

       wxBell();
    }
}
ProcessEvent によるイベントテーブルの検索は通常、以下の順番で行われます:

  1. (wxEvtHandler::SetEvtHandlerEnabled を呼ぶことで) オブジェクトが無効化されている場合、(6) までスキップします。
  2. オブジェクトが wxWindow の場合、ProcessEvent はウィンドウの wxValidator から再帰的に呼び出されます。ProcessEvent が true を返した場合、処理を終了します。
  3. このイベントハンドラから SearchEventTable が呼ばれます。ProcessEvent が true を返さなかった場合、基底クラスのイベントテーブルを検索します。これを順次、イベントテーブルが存在しなくなるか、適切な関数が見つかるまで行います。適切な関数が見つからなかった場合、処理を終了します。
  4. 次に、イベントハンドラの連鎖を辿って検索します。(通常、この連鎖の長さは 1 です) 検索に成功した場合、処理を終了します。
  5. オブジェクトが wxWindow で、かつ、イベントが伝播するように設定されている (ライブラリの中では wxCommandEvent の派生イベントのみ、伝播するよう設定されています) 場合、親ウィンドウの ProcessEvent が再帰的に呼ばれます。ProcessEvent が true を返した場合、処理を終了します。
  6. 最後に、wxApp オブジェクトの ProcessEvent が呼ばれます。

ステップ 5 に注意してください。 wxWidgets のイベント処理システムの持つこの強力な機能はしばしば見落とされたり、人を混乱させたりします。別の言い方をすると、伝播するように設定されたイベント (参照: wxEvent::ShouldPropagate) (よくあるのは wxCommandEvent を直接、または間接的に継承したイベントです) は最大回数、伝播するか event.Skip() を呼んでいないイベントハンドラが見つかるまで、子から親へコントロール階層をさかのぼっていきます。

最後に、他にも複雑な仕組みがあります (実際には、これは wxWidgets プログラマの生活を非常にシンプルにしてくれるものです): コマンドイベントが親ウィンドウへ伝播するとき、親ダイアログまで到達した時点で伝播が終了します。これはつまり、モーダルダイアログを表示しているときにダイアログコントロールから意図しないイベントを受け取ることがないことを意味します。 (それらのイベントは処理されないままになるでしょう) しかし、通常のイベントはフレームを超えて伝播します。このようにした理由は、普通のアプリケーションでは数個のフレームしか存在せず、プログラマはそれらの親子関係のことをよく理解している一方で、複雑なプログラムで表示されるすべてのダイアログを追跡することは、不可能でないにしても非常に難しいためです。 (いくつかのダイアログは wxWidgets によって自動的に生成されることを思い出してください) なんらかの理由で別の振る舞いをさせる必要がある場合、明示的に SetExtraStyle(wxWS_EX_BLOCK_EVENTS) を使用することでイベントが指定されたウィンドウ外へ伝播するのを止めたり、ダイアログ (デフォルトでこのフラグが設定されています) のフラグを解除したりできます。

(リサイズ、移動、描画、マウスイベント、キーボードイベントといった) ウィンドウに関係する一般的なイベントはウィンドウに対してのみ送られます。(ボタンクリック、メニュー選択、ツリーの展開といった) 高水準で、ウィンドウ自身が生成するイベントはコマンドイベントと呼ばれ、そのイベントを処理対象とする場合に親コントロールに対して送られます。

ProcessEvent をオーバーライドすることでイベント処理をリダイレクトしたいと思うかもしれません。これは例えば、ドキュメント/ビューフレームワークがドキュメントやビューでイベントハンドラを定義するために行います。コマンドイベントかどうか (おそらくリダイレクト対象のイベントかどうかだと思いますが) を調べるため、遅い実行時型情報の代わりに wxEvent::IsCommandEvent を使用することができます。

上で述べたように、コマンドイベントだけが親コントロールのイベントハンドラで再帰的に処理されます。このことについて混乱する人が多いため、親コントロールのイベントハンドラへ送信 "されない" システムイベントの一覧を以下に示します。

wxEvent イベントの基底クラス
wxActivateEvent ウィンドウまたはアプリケーションのアクティブ化イベント
wxCloseEvent ウィンドウの終了、またはセッションの終了イベント
wxEraseEvent 背景の消去イベント
wxFocusEvent ウィンドウフォーカスイベント
wxKeyEvent キー押下イベント
wxIdleEvent アイドルイベント
wxInitDialogEvent ダイアログの初期化イベント
wxJoystickEvent ジョイスティックイベント
wxMenuEvent メニューイベント
wxMouseEvent マウスイベント
wxMoveEvent 移動イベント
wxPaintEvent 描画イベント
wxQueryLayoutInfoEvent レイアウト情報の問い合わせに使用される
wxSetCursorEvent 現在のマウス位置に基づいた特殊なカーソル処理に使用される
wxSizeEvent リサイズイベント
wxScrollWinEvent (スクロールバーではなく) スクロール可能なウィンドウから送信されるスクロールイベント
wxSysColourChangedEvent システムカラーの変更イベント

例えばダイアログ内のネイティブコントロールへ送信される (そのコントロール自身では使用しない) キーイベントなど、特定のシステムイベントを親ウィンドウで取得したいと思うことがあるかもしれません。この場合、すべてのイベント (もしくはその中の特定のイベント) を親ウィンドウへ渡すようにイベントハンドラの ProcessEvent() をオーバーライドする必要があります。


ユーザの生成したイベントとプログラム的に生成したイベント

一般的に wxEvents はユーザ操作 (wxWindow のリサイズなど) と関数呼び出し (wxWindow::SetSize など) のどちらからでも発生しますが、wxCommandEvent を継承したイベントはユーザが操作した場合のみ、wxWidgets コントロールから送信されます。このルールの 例外 は以下のとおりです:

wxNotebook::AddPage イベントを送信しない代替方法を持たない
wxNotebook::AdvanceSelection イベントを送信しない代替方法を持たない
wxNotebook::DeletePage イベントを送信しない代替方法を持たない
wxNotebook::SetSelection wxNotebook::SetSelection は非推奨のため、代わりに wxNotebook::ChangeSelection を使用してください。
wxTreeCtrl::Delete イベントを送信しない代替方法を持たない
wxTreeCtrl::DeleteAllItems イベントを送信しない代替方法を持たない
wxTreeCtrl::EditLabel イベントを送信しない代替方法を持たない
wxTextCtrl のすべての関数 wxTextCtrl::SetValue の代わりに wxTextCtrl::ChangeValue を使用できますが、ReplaceWriteText といった他の関数にはイベントを送信せずに同じことを行う関数はありません。


動的イベントハンドラ

実際のところ、ウィンドウクラスを継承して新しいクラスを作成したくない場合は、必ずしもそうする必要はありません。代わりに wxEvtHandler を継承した新しいクラスを作成して適切なイベントテーブルを定義し、wxWindow::SetEventHandler (か、より望ましいのは wxWindow::PushEventHandler) を呼び出してこのイベントテーブルを使用するようにできます。この方法を使うことで、たくさんの継承クラスを作成しなくてすむとともに、同じイベントハンドラクラスのインスタンスを異なるウィジェットクラスのインスタンスから利用することができます。 (ただし、異なるオブジェクトを同じイベントハンドラオブジェクトとして複数回使用するべきではありません) もし手動でウィンドウのイベントハンドラを呼ぶ必要がある場合、GetEventHandler 関数でウィンドウのイベントハンドラを取得し、そのメンバ関数を呼び出してください。SetEventHandler や PushEventHandler を使用してイベント処理をリダイレクトしていない場合、デフォルトでは GetEventHandler はウィンドウ自身を返却します。

PushEventHandler の使用法のひとつは、一時的または永続的に GUI の振る舞いを変更することです。例えば、ダイアログの外見を変更するためのダイアログエディタをアプリケーション内で起動したいと思うかもしれません。その場合、既存のダイアログの振る舞いを元に戻す前にすべての入力を取得し、"その場で" 編集することができます。そのため、アプリケーションの振る舞いをカスタマイズするために新しいクラスを継承していたとしても、あなたのユーティリティから自由に振る舞いを変更することができます。これはオンラインチュートリアルでも有用なテクニックです。レッスンから外れることなく、ユーザに一連のステップを実行させることができます。ここでは、ボタンやウィンドウから送られてくるイベントを検証し、それが適用可能なものである場合に元のイベントハンドラへ渡す、ということを行えます。他のイベントハンドラとは異なる範囲のイベントを独立して処理するようなイベントハンドラを作成する場合に PushEventHandler/PopEventHandler を使用してください。


ウィンドウ識別子

ウィンドウ識別子とは、イベントシステムにおいてウィンドウを一意に識別するための整数値です。 (とはいえ、他の用途に使用することもできます) 実際には、特定のコンテキスト (フレームやその子コントロール) 内で一意であれば、アプリケーション全体で一意である必要はありません。例えば、同じダイアログ内で複数回使うのでなければ、いくつものダイアログで wxID_OK 識別子を使用しても構いません。

ウィンドウのコンストラクタに wxID_ANY を渡した場合、wxWidgets が自動的に識別子を生成します。コントロールの生成するイベントを処理しない場合や、イベントを一箇所で処理する場合 (このときはイベントテーブルに wxID_ANY を指定するか、それと同様に wxEvtHandler::Connect を呼ぶ必要があります) など、コントロールの正確な識別子が必要でないときにこれは役立ちます。自動生成される識別子は常に負の値のため、必ず正の値でなければならないユーザ定義の識別子と衝突することはありません。

標準識別子には以下のものが用意されています。新たな識別子を定義する場合、wxID_HIGHEST 以上の値を使用することで安全に値を決定することができます。もしくは wxID_LOWEST 以下の識別子を使用することもできます。

#define wxID_ANY                -1

#define wxID_LOWEST             4999

#define wxID_OPEN               5000
#define wxID_CLOSE              5001
#define wxID_NEW                5002
#define wxID_SAVE               5003
#define wxID_SAVEAS             5004
#define wxID_REVERT             5005
#define wxID_EXIT               5006
#define wxID_UNDO               5007
#define wxID_REDO               5008
#define wxID_HELP               5009
#define wxID_PRINT              5010
#define wxID_PRINT_SETUP        5011
#define wxID_PREVIEW            5012
#define wxID_ABOUT              5013
#define wxID_HELP_CONTENTS      5014
#define wxID_HELP_COMMANDS      5015
#define wxID_HELP_PROCEDURES    5016
#define wxID_HELP_CONTEXT       5017

#define wxID_CUT                5030
#define wxID_COPY               5031
#define wxID_PASTE              5032
#define wxID_CLEAR              5033
#define wxID_FIND               5034
#define wxID_DUPLICATE          5035
#define wxID_SELECTALL          5036
#define wxID_DELETE             5037
#define wxID_REPLACE            5038
#define wxID_REPLACE_ALL        5039
#define wxID_PROPERTIES         5040

#define wxID_VIEW_DETAILS       5041
#define wxID_VIEW_LARGEICONS    5042
#define wxID_VIEW_SMALLICONS    5043
#define wxID_VIEW_LIST          5044
#define wxID_VIEW_SORTDATE      5045
#define wxID_VIEW_SORTNAME      5046
#define wxID_VIEW_SORTSIZE      5047
#define wxID_VIEW_SORTTYPE      5048

#define wxID_FILE1              5050
#define wxID_FILE2              5051
#define wxID_FILE3              5052
#define wxID_FILE4              5053
#define wxID_FILE5              5054
#define wxID_FILE6              5055
#define wxID_FILE7              5056
#define wxID_FILE8              5057
#define wxID_FILE9              5058

#define wxID_OK                 5100
#define wxID_CANCEL             5101
#define wxID_APPLY              5102
#define wxID_YES                5103
#define wxID_NO                 5104
#define wxID_STATIC             5105

#define wxID_HIGHEST            5999

イベントマクロの概要

イベントクラスごとのマクロ

このドキュメントではイベントマクロをイベントクラスごとに分類しています。詳細は各章を参照してください。

wxActivateEvent EVT_ACTIVATE、EVT_ACTIVATE_APP マクロはアクティブ化、非アクティブ化イベントを捉えます。
wxCommandEvent よく使われる一連のコントロールイベント。
wxCloseEvent EVT_CLOSE マクロは wxWindow::Close によるウィンドウの終了を処理します。
wxDropFilesEvent EVT_DROP_FILES マクロはファイルドロップイベントを処理します。
wxEraseEvent EVT_ERASE_BACKGROUND マクロはウィンドウの消去要求を処理するために使用されます。
wxFocusEvent EVT_SET_FOCUS、EVT_KILL_FOCUS マクロはキーボードフォーカスイベントを処理するために使用されます。
wxKeyEvent EVT_CHAR、EVT_KEY_DOWN、EVT_KEY_UP マクロは任意のウィンドウのキーボード入力を処理します。
wxIdleEvent EVT_IDLE マクロはアプリケーションのアイドルイベントを処理します。 (例えば、バックグラウンド処理などに使用します)
wxInitDialogEvent EVT_INIT_DIALOG マクロはダイアログの初期化イベントを処理するために使用されます。
wxListEvent これらのマクロは wxListCtrl のイベントを処理します。
wxMenuEvent これらのマクロは特殊なメニューイベント (メニューコマンドではありません) を処理します。
wxMouseEvent マウスイベントマクロは個別のマウスやすべてのマウスのイベントを処理することができます。
wxMoveEvent EVT_MOVE マクロはウィンドウの移動を処理するために使用されます。
wxPaintEvent EVT_PAINT マクロはウィンドウの描画要求を処理するために使用されます。
wxScrollEvent これらのマクロは wxScrollBarwxSliderwxSpinButton から送信されるスクロールイベントを処理するために使用されます。
wxSetCursorEvent EVT_SET_CURSOR マクロは特殊なカーソル処理のために使用されます。
wxSizeEvent EVT_SIZE マクロはウィンドウのりサイズを処理するために使用されます。
wxSplitterEvent EVT_SPLITTER_SASH_POS_CHANGED、EVT_SPLITTER_UNSPLIT、EVT_SPLITTER_DCLICK マクロはさまざまなウィンドウ分割イベントを処理するために使用されます。
wxSysColourChangedEvent EVT_SYS_COLOUR_CHANGED マクロはユーザによるシステムカラーの変更イベントを処理するために使用されます。 (Windows のみ)
wxTreeEvent これらのマクロは wxTreeCtrl のイベントを処理します。
wxUpdateUIEvent EVT_UPDATE_UI マクロはアプリケーションがメニュー、ツールバー、コントロールの見た目の状態を変更するための擬似イベントを処理するために使用されます。


カスタムイベントの概要

一般的なアプローチ

wxWidgets 2.2.x から 実行時に 決定される ID を使用してイベントの型を識別します。これにより、ID の衝突を起こす (異なるふたつのイベント型が同じイベント ID を取得してしまう) ことなく、新しいイベント型をライブラリやアプリケーションに追加することができます。このイベント ID は const wxEventType 型の構造体に格納されます。

新しいイベント型を定義する方法として、主に 2 種類の選択肢があります。ひとつは完全に新しいイベントクラスを定義することです。 (通常は wxEventwxCommandEvent を継承します) もう一方の方法は、既存のイベントクラスを使用し、それらに新しいイベント型を与える方法です。どちらの方法を使うにせよ、新しいイベント型の定義と宣言が必要となりますが、それには以下のマクロを使用します:

// ヘッダファイルで使用する
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(name, value)
END_DECLARE_EVENT_TYPES()

// ソースファイルで使用する
DEFINE_EVENT_TYPE(name)
DECLARE_EVENT_TYPE の value 引数はイベント ID を明示的に指定していた wxWidgets 2.0.x との後方互換性のために使用されているだけなので、無視することができます。

コードの書き方とカスタムイベント型の動作例として イベントサンプル も参照してください。

既存のイベントクラスの使用

新しいイベント型で wxCommandEvent を使用したいだけの場合、自分自身で新しいマクロを定義するのではなく、以下の汎用的なイベントテーブルマクロを使用することができます。この方法には、スレッド間でイベントを送信するための新しい wxEvent::Clone() 関数を定義する必要がないといった利点もあります。以下にコード例を示します。

DECLARE_EVENT_TYPE(wxEVT_MY_EVENT, -1)

DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)

// イベントを捕まえるユーザコード

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
  // ....
  EVT_COMMAND  (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)
END_EVENT_TABLE()

void MyFrame::OnMyEvent( wxCommandEvent &event )
{
    //処理を行う
    wxString text = event.GetText();
}


// イベントを送信するユーザコード

void MyWindow::SendEvent()
{
    wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
    event.SetEventObject( this );
    // 何か値を設定する
    event.SetText( wxT("Hallo") );
    // 送信する
    GetEventHandler()->ProcessEvent( event );
}
汎用的なイベントテーブルマクロ

EVT_CUSTOM(event, id, func) (wxEVT_SIZE といった) イベント識別子、ウィンドウ識別子、呼び出すメンバ関数を指定してカスタムイベントのエントリをイベントテーブルへ追加することができます。
EVT_CUSTOM_RANGE(event, id1, id2, func) EVT_CUSTOM と同じですが、ウィンドウ識別子を範囲で指定できます。
EVT_COMMAND(id, event, func) EVT_CUSTOM と同じですが、wxCommandEvent を引数に取るメンバ関数を指定します。
EVT_COMMAND_RANGE(id1, id2, event, func) EVT_CUSTOM_RANGE と同じですが、wxCommandEvent を引数に取るメンバ関数を指定します。
EVT_NOTIFY(event, id, func) EVT_CUSTOM と同じですが、wxNotifyEvent を引数に取るメンバ関数を指定します。
EVT_NOTIFY_RANGE(event, id1, id2, func) EVT_CUSTOM_RANGE と同じですが、wxNotifyEvent を引数に取るメンバ関数を指定します。

独自のイベントクラスの定義

(より複雑なデータをある場所から別の場所へ送るといった) 特定の状況下では独自のイベントクラスの定義が必要になるでしょう。イベントクラスの定義とは別に、独自のイベントテーブルマクロも定義する必要があります。 (そしてこれは非常に長くなります) 継承したイベント関数へのキャストが必要なことも忘れないでください。wxPlot ライブラリから抜粋した例を以下に示します。このコードは wxWidgets のソースコードの contrib セクションにあります。

// イベントを定義するコード

class wxPlotEvent: public wxNotifyEvent
{
public:
    wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );

    // アクセサ
    wxPlotCurve *GetCurve()
        { return m_curve; }

    // wxPostEvent() で必要になる
    wxEvent* Clone();

private:
    wxPlotCurve   *m_curve;
};

DECLARE_EVENT_TYPE( wxEVT_PLOT_ACTION, -1 )

typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);

#define EVT_PLOT(id, fn) \
    DECLARE_EVENT_TABLE_ENTRY( wxEVT_PLOT_ACTION, id, -1, \
    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
    wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ),


// イベント型とイベントクラスを定義するコード

DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )

wxPlotEvent::wxPlotEvent( ...


// イベントを捕まえるユーザコード

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_PLOT  (ID_MY_WINDOW,  MyFrame::OnPlot)
END_EVENT_TABLE()

void MyFrame::OnPlot( wxPlotEvent &event )
{
    wxPlotCurve *curve = event.GetCurve();
}


// イベントを送信するユーザコード

void MyWindow::SendEvent()
{
    wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );
    event.SetEventObject( this );
    event.SetCurve( m_curve );
    GetEventHandler()->ProcessEvent( event );
}