ホーム > デベロッパ > SophiaFramework > BREW C++ 逆引きコード集

BREW C++ プログラミング 逆引きコード集 : その他Tips

C++ で作成されたBREW アプリで使えるTipsを紹介しています。
SophiaFramework を用いています。

BREW センタープッシュ (SMS) により BREW アプレットを起動するには …

BREW センタープッシュ (SMS) による BREW アプレットの起動は、SFEVT_APP_MESSAGE (EVT_APP_MESSAGE) イベントを受信し、そのイベントハンドラの中で目的とする BREW アプレットを起動することにより実現可能です。

このとき、SFEVT_APP_MESSAGE (EVT_APP_MESSAGE) イベントは、標準トレーサに「配信条件:なし」の配信ルールで登録されていますので、ルートを含めレスポンダに配信されません。

このイベントは、『標準トレーサに「配信条件:なし」で配信規則が登録されているイベントの取得方法』にあるように、アプリケーションクラスのコンストラクタ内でSFYDistributer から受信します。
 
SFEVT_APP_MESSAGE (EVT_APP_MESSAGE) イベントのハンドラでは、目的とする BREW アプレットを起動する処理を記述します。

サンプルコードダウンロード( smsdemosf.zip: 7.93kb )

// コンストラクタ
smsdemosf::smsdemosf(Void) static_throws
{
    // 開始イベントのハンドラを登録します。
    if (static_try()) {
        static_throw(RegisterHandler(
            SFXEventRange(SFEVT_APP_START, SFEVT_APP_START, SFP16_BEGIN, SFP16_END),
            XANDLER_INTERNAL(OnAppStart)
        ));
    }

    // 描画イベントのハンドラを登録します。
    if (static_try()) {
        static_throw(RegisterHandler(
            SFXEventRange(SFEVT_RESPONDER_RENDER, SFEVT_RESPONDER_RENDER, SFP16_RENDER_REQUEST, SFP16_RENDER_REQUEST),
            XANDLER_INTERNAL(OnRenderRequest)
        ));
    }

    // SMS メッセージイベントのハンドラを "配信クラス" に登録します。
    if (static_try()) {
        SFYDistributerPtr distributer = GetDistributer();
        if (distributer != null) {
            static_throw(distributer->RegisterHandler(
                SFXEventRange(SFEVT_APP_MESSAGE, SFEVT_APP_MESSAGE, SFP16_BEGIN, SFP16_END),
                XANDLER_INTERNAL(OnAppMessage)
            ));
        }
    }
}

// 開始ハンドラ
XANDLER_IMPLEMENT_VOIDSTART(smsdemosf, OnAppStart, invoker, environment)
{
    // 未使用変数のワーニングを回避します。

    unused(invoker);

    // ここにアプリケーション開始時の処理を記述します。

    // 起動引数から SMS メッセージを取り出します。
    _message = environment->pszArgs;

    // 再描画を要求します。
    Invalidate();

    return;
}


// 描画ハンドラ
XANDLER_IMPLEMENT_VOIDRENDER(smsdemosf, OnRenderRequest, invoker, reason, graphics)
{
    // 未使用変数のワーニングを回避します。

    unused(invoker);
    unused(reason);

    // ここに描画時の処理を記述します。

    // 画面にメッセージを描画します。
    graphics->DrawSingleText(_message.GetCString(), GetLocalBound(), SFXRGBColor(0x00, 0x00, 0x00, 0x00));
    return;
}


// SMS メッセージ ハンドラ
XANDLER_IMPLEMENT_VOIDEVENT(smsdemosf, OnAppMessage, invoker, event)
{
    // 未使用変数のワーニングを回避します。

    unused(invoker);

    // ここに SMS メッセージ受信時の処理を記述します。

    TRACE("## SFEVT_APP_MESSAGE ##");
    if (event.GetP32() != null) {

        ACharConstPtr message;
        message = reinterpret_cast<ACharConstPtr>(event.GetP32());

        // SMS メッセージを表示
        TRACE("## SMS Message = %s ##", message);

        SFBShellSmp shell;
        if ((shell = SFBShell::GetInstance()) != null) {

            // メッセージをアプリケーションの起動引数として渡します。
            if (shell->StartAppletArgs(AEECLSID_SMSDEMOSF, message) != SFERR_NO_ERROR) {

                // 起動失敗時のエラー処理を記述します
                // ...

            }
        }
    }
    return;
}
      

SophiaFrameworkから BREW エクステンションに AEEApplet 構造体のポインターを渡す方法

SophiaFramework には AEEApplet 構造体が存在しません。

SophiaFramework で AEEApplet に相当するクラスは、SFCApplet クラスですが、このクラスは IApplet クラスを独自に拡張した変数の並びとなっています。

そのため、SFBApplet::GetInstance() 関数や SFXHelper::getinstance() 関数を利用しても SFCApplet 構造体へのポインタが返ってくるので互換性はありません。

例えば、BREW エクステンション側が単純に IDisplay へのポインタを必要としているのであれば、以下の例のようにアプリ内で自前の AEEApplet 構造体を確保し、メンバを初期化した後、その AEEApplet 構造体へのポインタを渡すという方法が考えられます。

AEEApplet _brew_applet;

_brew_applet.m_pIDisplay = interface_cast(SFXGraphics::GetInstance()->GetSFBDisplay().Get());

3d_function(3d, &_brew_applet, ...);

// 必要に応じて他のメンバも初期化して渡します。

※ この方法は、エクステンション側がインターフェースへのポインタを単純に参照するだけの場合は有効ですが、アプレット自身の参照カウンタを変更するような特殊な場合には正常に動作しない可能性があります。