前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.3

10.10. イベント ハンドリング

10.10.1. イベント

[Note] SFY レスポンダシステム(新レスポンダシステム)のイベント

SFY レスポンダシステム(新レスポンダシステム)のイベントについては、SFY レスポンダシステム : イベントを参照してください。

SophiaFramework UNIVERSE では、BREW 標準のイベントと SophiaFramework UNIVERSE 用に拡張されたイベントが使えます。 また、独自のイベントも定義できます。

BREW の AEEEvent 型に相当する SophiaFramework UNIVERSE のイベントタイプは、 SFCEventEnum として定義されています。

EVT_KEYEVT_APP_START など BREW 標準のイベント名は、 SFEVT_KEYSFEVT_APP_START などのように SF で始まる名前に置き換えられています。

GUI フレームワークで使うイベントの「タイプ」は SFCEventEnum 型のイベントタイプ、 「P16」は UInt16 型の第 1 パラメータ、 「P32」は UInt32 型の第 2 パラメータです。

GUI フレームワークに関連するイベントタイプの名前は SREVT_ で始まります。

表 10.15. BREW 標準の主なイベント

イベント名 解説
SFEVT_APP_START アプリの起動
SFEVT_APP_STOP アプリの停止
SFEVT_APP_RESUME アプリの再開
SFEVT_APP_SUSPEND アプリの中断
SFEVT_KEY キー入力イベント
SFEVT_KEY_PRESS キープレス イベント
SFEVT_KEY_RELEASE キーリリース イベント
SFEVT_CHAR 文字入力イベント
SFEVT_ALARM アラーム イベント
SFEVT_COMMAND アプリケーション固有イベント
SFEVT_APP_CONFIG アプリの起動: 設定画面の表示
SFEVT_APP_HIDDEN_CONFIG アプリの起動: 隠し設定画面の表示
SFEVT_APP_MESSAGE SMS メッセージ受信イベント
SFEVT_ASYNC_ERROR 非同期エラー通知( BREW SDK のバージョンが 2.1 以上の場合にのみ有効 )
SFEVT_APP_TERMINATE アプリの終了 ( BREW SDK のバージョンが 2.1 以上の場合にのみ有効 )
SFEVT_EXIT BREW の終了 ( BREW SDK のバージョンが 2.1 以上の場合にのみ有効 )
SFEVT_USER ユーザー定義

表 10.16. SophiaFramework UNIVERSE 用に拡張された主なイベント

イベントの種類 説明
タイプ:SREVT_RESPONDER_RENDER
P16:SRP16_RENDER_INVOKE
P32:Bool 型
レスポンダを再描画するためのイベントです。再描画するレスポンダに送信します。
P32 は描画対象として登録されていないレスポンダを再描画させるとき true を渡します。
※1. アプリケーションクラスのインスタンスにのみ送信できます。
※2. このイベントを処理してはいけません。
タイプ:SREVT_RESPONDER_RENDER
P16:SRP16_RENDER_BASE
P32:SFXGraphicsPtr
レスポンダのベース領域を再描画するためのイベントです。再描画するレスポンダに送信します。
P32 はグラフィックスへのポインタです。このグラフィックを使用して描画します。
※ イベントに応答するにはハンドラを登録します。
タイプ:SREVT_RESPONDER_RENDER
P16:SRP16_RENDER_CONTENT
P32:SFXGraphicsPtr
レスポンダのコンテント領域を再描画するためのイベントです。再描画するレスポンダに送信します。
P32 はグラフィックスへのポインタです。このグラフィックを使用して描画します。
※ イベントに応答するにはハンドラを登録します。
タイプ:SREVT_RESPONDER_TERMINATE
P16:SRP16_TERMINATE_INVOKE
P32:Bool 型
レスポンダを破棄するためのイベントです。破棄するレスポンダに送信します。
P32 は強制破棄のとき true となります。
※ このイベントを処理してはいけません。
タイプ:SREVT_RESPONDER_TERMINATE
P16:SRP16_TERMINATE_TRY
P32:Bool 型
レスポンダが破棄される前に通知されるイベントです。
P32 は強制破棄か否かを表す値です。
このイベントを処理するとき、破棄を中止する場合は true、破棄を続行する場合は false を返します。
このイベントは、破棄されるレスポンダに含まれる全ての子階層のレスポンダにも送信され、そのうちいずれかのレスポンダが true を返すと、レスポンダの破棄は中断されます。
タイプ:SREVT_DIALOG
P16:UInt16 型
P32:SFRDialogPtr
ダイアログでキーが押されたイベントなどダイアログ固有のイベントです。
P16 はダイアログが閉じられた理由です。OK ボタンが押された場合は SRP16_OK、クリアキーが押された場合は SRP16_ESCAPE がセットされます。
P32 はダイアログへのポインタです。
タイプ:SREVT_MENU
P16:UInt16 型
P32:SFRMenuPtr
メニューでキーが押されたイベントなどメニュー固有のイベントです。
P16 はメニューが閉じられた理由もしくは、メニューが選択された場合はそのインデックスです。クリアキーが押された場合は SRP16_ESCAPE、メニュー項目を選択した場合は項目のインデックスがセットされます。
P32 はメニューへのポインタです。
タイプ:SREVT_CONTROL
P16:UInt16 型
P32:SFRControlPtr
コントロールでキーが押されたイベントなどコントロール固有のイベントです。
P16 はコントロールの値です。
P32 はコントロールへのポインタです。

例 10.70. レスポンダの強制再描画

// アプリケーションクラスのインスタンスを取得する
SFRApplicationPtr app(SFRApplication::GetInstance());

// アプリケーションクラスのインスタンスに再描画イベントを送信する
app->Invoke(SFXEvent(SREVT_RESPONDER_RENDER, 
                     SRP16_RENDER_INVOKE, 
                     true));

例 10.71. コンテント領域の再描画

// コンテント領域を再描画するハンドラの登録
RegisterHandler(SREVT_RESPONDER_RENDER, 
                SRP16_RENDER_CONTENT, 
                HANDLER_BEFORE, 
                HANDLER_FUNCTION(OnRenderContent));

例 10.72. レスポンダの破棄

SFRButtonControlPtr button;

// ボタンの作成と破棄
if ((button = ::new SFRButtonControl(window, SFXRectangle(10, 10, 100, 20), "OK")) != null) {
    // コンストラクタ内部のエラーをチェックする
    if (button->static_catch() == SFERR_NO_ERROR) {  // エラーでないとき
        // SREVT_RESPONDER_TERMINATE イベントを送信してボタンを破棄する
        button->Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE, 
                                SRP16_TERMINATE_INVOKE, 
                                true));
    }
    else {
        // エラーのとき、delete 演算子を使用してボタンを破棄する
        ::delete button;
    }

10.10.2. イベントハンドラ

[Note] SFY レスポンダシステム(新レスポンダシステム)のハンドラ

SFY レスポンダシステム(新レスポンダシステム)のイベントハンドラについては、SFY レスポンダシステム : ハンドラを参照してください。

アプリの開始や停止・中断・再開、キー入力などのイベントは、トレーサによって適切なレスポンダへ通知されます。

そして、イベントハンドラと呼ばれる関数によってイベント毎の処理が自動的に行われます。

参照: トレーサ

10.10.2.1. イベントハンドラの宣言

イベントハンドラは HANDLER_DECLARE_ で始まるマクロを使用して宣言します。

引数にはハンドラ名を設定します。

参照: GUI フレームワーク用マクロ : イベントハンドラ宣言用マクロ

表 10.17. イベントハンドラ宣言用マクロ( Void 型 )

マクロ 意味
HANDLER_DECLARE_VOIDRENDER 描画ハンドラ
HANDLER_DECLARE_VOIDSTART アプリ開始ハンドラ
HANDLER_DECLARE_VOIDSTOP アプリ終了ハンドラ
HANDLER_DECLARE_VOIDRESUME レジュームハンドラ
HANDLER_DECLARE_VOIDSUSPEND サスペンドハンドラ
HANDLER_DECLARE_VOIDDIALOG ダイアログハンドラ
HANDLER_DECLARE_VOIDMENU メニューハンドラ
HANDLER_DECLARE_VOIDCONTROL コントロールハンドラ
HANDLER_DECLARE_VOIDVOID 汎用ハンドラ
HANDLER_DECLARE_VOIDEVENT 汎用ハンドラ

例 10.73. 描画ハンドラの宣言

// MyWindow クラスの定義
SFMTYPEDEFCLASS(MyWindow)
class MyWindow : public SFRTitleWindow {
    SFMSEALCOPY(MyWindow)
public:
    MyWindow(Void) static_throws;
    virtual ~MyWindow(Void)
    
    // 描画ハンドラの宣言
    // 引数はハンドラ名
    HANDLER_DECLARE_VOIDRENDER(OnRenderContent)
};

表 10.18. イベントハンドラ宣言用マクロ( Bool 型 )

マクロ 意味
HANDLER_DECLARE_BOOLSTART アプリ開始ハンドラ
HANDLER_DECLARE_BOOLSTOP アプリ終了ハンドラ
HANDLER_DECLARE_BOOLRESUME レジュームハンドラ
HANDLER_DECLARE_BOOLSUSPEND サスペンドハンドラ
HANDLER_DECLARE_BOOLDIALOG ダイアログハンドラ
HANDLER_DECLARE_BOOLMENU メニューハンドラ
HANDLER_DECLARE_BOOLCONTROL コントロールハンドラ
HANDLER_DECLARE_BOOLVOID 汎用ハンドラ
HANDLER_DECLARE_BOOLEVENT 汎用ハンドラ

例 10.74. キーハンドラの宣言

// MyWindow クラスの定義
SFMTYPEDEFCLASS(MyWindow)
class MyWindow : public SFRTitleWindow {
    SFMSEALCOPY(MyWindow)
public:
    MyWindow(Void) static_throws;
    virtual ~MyWindow(Void)
    
    // キーハンドラの宣言
    // 引数はハンドラ名
    HANDLER_DECLARE_BOOLEVENT(OnKey)
};
[Note] ハンドラ宣言マクロによって …

ハンドラ関数へのポインタとハンドラ識別番号 ( リファレンス値 ) が生成されます。

10.10.2.2. イベントハンドラの実装

イベントハンドラは HANDLER_IMPLEMENT_ で始まるマクロを使用して実装します。

第 1 引数は所属クラス名、第 2 引数はハンドラ名です。第 3 引数以降はハンドラによって異なります。

参照: GUI フレームワーク用マクロ : イベントハンドラ実装用マクロ

表 10.19. イベントハンドラ実装用マクロ( Void 型 )

マクロ 意味 第 3 引数 第 4 引数 第 5 引数
HANDLER_IMPLEMENT_VOIDRENDER 描画ハンドラ graphics (グラフィック オブジェクト) なし なし
HANDLER_IMPLEMENT_VOIDSTART アプリ開始ハンドラ environment なし なし
HANDLER_IMPLEMENT_VOIDSTOP アプリ終了ハンドラ quitable なし なし
HANDLER_IMPLEMENT_VOIDRESUME レジュームハンドラ environment なし なし
HANDLER_IMPLEMENT_VOIDSUSPEND サスペンドハンドラ reason info なし
HANDLER_IMPLEMENT_VOIDDIALOG ダイアログハンドラ result dialog ( へのポインタ ) なし
HANDLER_IMPLEMENT_VOIDMENU メニューハンドラ result menu ( へのポインタ ) なし
HANDLER_IMPLEMENT_VOIDCONTROL コントロールハンドラ result control ( へのポインタ ) なし
HANDLER_IMPLEMENT_VOIDVOID 汎用ハンドラ なし なし なし
HANDLER_IMPLEMENT_VOIDEVENT 汎用ハンドラ event ( イベント オブジェクト ) なし なし

例 10.75. 描画ハンドラの実装

// 第 1 引数 : 所属クラス、第 2 引数 : ハンドラ名、第 3 引数 : グラフィック オブジェクト
HANDLER_IMPLEMENT_VOIDRENDER(MyWindow, OnRenderContent, graphics)
{
    // 文字列 "Hello World" を描画する
    graphics->DrawText("Hello World", GetContentWorld());
    return;
}

表 10.20. イベントハンドラ実装用マクロ( Bool 型 )

マクロ 意味 第 3 引数 第 4 引数 第 5 引数
HANDLER_IMPLEMENT_BOOLSTART アプリ開始ハンドラ environment なし なし
HANDLER_IMPLEMENT_BOOLSTOP アプリ終了ハンドラ quitable なし なし
HANDLER_IMPLEMENT_BOOLRESUME レジュームハンドラ environment なし なし
HANDLER_IMPLEMENT_BOOLSUSPEND サスペンドハンドラ reason info なし
HANDLER_IMPLEMENT_BOOLDIALOG ダイアログハンドラ result dialog ( へのポインタ ) なし
HANDLER_IMPLEMENT_BOOLMENU メニューハンドラ result menu ( へのポインタ ) なし
HANDLER_IMPLEMENT_BOOLCONTROL コントロールハンドラ result control ( へのポインタ ) なし
HANDLER_IMPLEMENT_BOOLVOID 汎用ハンドラ なし なし なし
HANDLER_IMPLEMENT_BOOLEVENT 汎用ハンドラ event ( イベント オブジェクト ) なし なし

例 10.76. キーハンドラの実装

//ウィンドウが最前面にあるときにキーが押されると実行される
第 1 引数 : 所属クラス、第 2 引数 : ハンドラ名、第 3 引数 : イベント値
HANDLER_IMPLEMENT_BOOLEVENT(MyWindow, OnKey, event)
{
    // 押されたキーの種類に応じて分岐する
    switch (event.GetP16()) {
        case AVK_CLR: // クリアー キーの場合
           // ウィンドウを閉じる
            return Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE,
                                   SRP16_TERMINATE_INVOKE, true));

        case AVK_1:   // 1 キーの場合

            ...

            return true;  // 押されたキーの処理したときは true を返す
    }
    return false;         // 押されたキーの処理しなかったときは false を返す
}

10.10.2.3. イベントハンドラの登録

ハンドラは RegisterHandler 関数で登録し、UnregisterHandler 関数で破棄します。

ひとつのイベントに 2 つ以上のイベントハンドラが登録されたときは、最後に登録されたイベントハンドラが有効となります。

■ イベントハンドラの登録時に必要な設定情報

  1. イベントタイプと第 1 パラメータ : BREW イベントと同様。
  2. イベント処理のタイミング : イベントを処理するのは、 イベントを子階層へ通知する前(HANDLER_BEFORE)かそれとも後(HANDLER_AFTER)か。

図 10.56. イベントの流れ

イベントの流れ

表 10.21. イベント処理のタイミング

処理のタイミング 解説
HANDLER_BEFORE 子レスポンダへイベントを通知する前に、親レスポンダでイベントを処理します。
HANDLER_AFTER 子レスポンダへイベントを通知して処理してから、親レスポンダでイベントを処理します。
[Note] イベント 処理のタイミング

レスポンダ(UI コンポーネント)は、最背面にあるレスポンダ(親レスポンダ)からその前面に位置するレスポンダ(子レスポンダ)へと順に描画する必要があるので、 描画ハンドラの登録ではイベント処理のタイミングは HANDLER_BEFORE を指定します。

一方、キーイベントは最前面のレスポンダ(子レスポンダ)からその背面に位置するレスポンダ(親レスポンダ)の順に処理する必要があるので、 キーハンドラの登録では HANDLER_AFTER を指定します。

親レスポンダと子レスポンダの生成と破棄の順序関係から、再開イベントと中断イベントに対するハンドラ登録では、 それぞれ HANDLER_BEFOREHANDLER_AFTER を指定します。 アプリの開始イベントと終了イベントに関しても、同じ理由でそれぞれ HANDLER_BEFOREHANDLER_AFTER を指定します。

例 10.77. ハンドラの型

Bool  (*SFRResponderSPP)  (SFXEventConstRef event, VoidPtr reference);

例 10.78. 子階層よりも前に処理するハンドラの登録

SFRResponderPtr responder;
SFCError error;

error = responder->RegisterHandler(SREVT_CONTROL, 
                                   HANDLER_BEFORE, 
                                   HANDLER_FUNCTION(OnControl));

例 10.79. 子階層よりも後に処理するハンドラの登録

SFRResponderPtr responder;
SFCError error;

error = responder->RegisterHandler(SFEVT_KEY, 
                                   SFEVT_KEY_RELEASE, 
                                   AVK_SELECT, 
                                   HANDLER_AFTER, 
                                   HANDLER_FUNCTION(OnKey));
[Note] HANDLER_FUNCTION の役割

HANDLER_DECLARE_ で始まるハンドラ宣言マクロの引数を HANDLER_FUNCTION マクロの引数とすることで、 ハンドラへの関数ポインタとハンドラ識別番号 ( リファレンス値 ) が RegisterHandler 関数に渡されます。

キーイベントをハンドルしたことにするには以下のように記述します。

例 10.80. キーイベントをハンドルしたことにする方法

SFRResponderPtr responder;
SFCError error;

error = responder->RegisterHandler(SFEVT_KEY, 
                                   SFEVT_KEY_RELEASE, 
                                   HANDLER_BEFORE, 
                                   HANDLER_NULL);
[Warning] 警告
上記コードでキーイベントをハンドルしたことにできるかどうかはトレーサの設定も影響します。

ハンドラは最も新しく登録されたものが有効です。以下の A と B のサンプルコードは動作が異なります。

例 10.81. ハンドラの登録 A

SFRResponderPtr responder;

responder->RegisterHandler(SFEVT_KEY, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnKey));
responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld1));
responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld2));

例 10.82. ハンドラの登録 B

SFRResponderPtr responder;

responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld1));
responder->RegisterHandler(SFEVT_KEY, 
                           SFEVT_KEY_RELEASE, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnHeld2));
responder->RegisterHandler(SFEVT_KEY, 
                           HANDLER_AFTER, 
                           HANDLER_FUNCTION(OnKey));