前のページ次のページ上に戻るホーム BREW C++ ライブラリ & GUI フレームワーク & XML ミドルウェア : SophiaFramework UNIVERSE 5.0

4.2. SFR アプレット

SFR アプレットとは、SFRApplication クラスを継承して SFR GUI フレームワークを使うアプレットのことです。

ここでは、SophiaFramework AppWizard が自動生成した HelloWorld アプレットのコードを使って、SFR アプレットの起動から終了までの処理の流れを解説します。

4.2.1. アプリケーションの起動

SFR アプレットは、ブートローダと呼ぶ SFCApplet::Boot 関数と Factory 関数を実装する必要があります。

SFCApplet::Boot 関数は、アプレットで最初に実行される関数です。 SFCApplet::Boot 関数では、ライセンスコードを設定し、 ClassID が "AEECLSID_HELLOWORLD" ( HelloWorld アプリケーションクラス ) の Factory 関数を返します。

SFCApplet::Boot 関数の次に実行されるのが Factory 関数です。 Factory 関数は、HelloWorld アプリケーションクラスのインスタンスを生成するコンストラクタを呼び出します。

[Note] ClassID とライセンスコード

実機の場合、ClassID に対応した正規のライセンスコードを設定しなければ、SFR アプレットは起動しません。

開発用実機に製品パッケージの Example ディレクトリ内のサンプル アプレットの ClassID とライセンスコードが利用可能です。

シミュレーターでは、ライセンスコードを設定しなくても SFR アプレットは起動します。

例 4.1. ブートローダとファクトリ関数

//
//  HelloWorld.cpp
//

#include "HelloWorld.hpp"

// ブートローダ
SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license)
{
    *license = "heap://"
               "TIXDRQXNU5WHU8Y3Z9WOHWQR6Z3VPSDHDV5CR1S4XASPWLUHWAS7Z5Z2TGS3XMSAT3UPUQTLTARCYPSF"
               "UEJZ6ROSJWGUQSEYKR6V2U4VESMTQLHKZ6X7Y2VKXHWIX3XBU0Z7VHWHXIZBSGT5SPU3XLX0Z1Y4R3TC"
               "U6WGT9WHWIVNYHYCUCR9T3SMTEWPRNVAX1Y4VPW2YCY9YQV5R7Z9UIVHT6SDUPU2SIW6VCRCWBR2S4WQ"
               "UPYFWCYGT4VIT1WHXGYPTQSFYPWNV3ULRNWFW7RBRFVKUKS2YQSQYHW1TPUPXBZ6UEY2WOYKR7S3TAU4"
               "TQS6UHVFVEVLU3R5SDSKW7RPTNTPVQU2T4R8Z4VLUGEW3U98TLDR8/";

    return (id == AEECLSID_HELLOWORLD) ? (&HelloWorld::Factory) : (null);
}

// ファクトリ関数
SFCInvokerPtr HelloWorld::Factory(Void)
{
    return ::new HelloWorld;
}

4.2.2. アプリケーションクラスの定義

SFR GUI フレームワークを使う SFR アプレットの HelloWorld クラスは SFRApplication クラスを継承します。

SFMTYPEDEFCLASS は HelloWorld に関する便利なユーザー定義型を自動生成するマクロです。

SFMSEALCOPY はインスタンスのコピーを禁止するマクロです。 SFRApplication を継承するクラスのインスタンスはコピーしてはいけません。

HANDLER_DECLARE_VOIDRENDER(OnRenderContent) で描画ハンドラ、 HANDLER_DECLARE_BOOLEVENT(OnKey) でキーハンドラを宣言しています。

例 4.2. HelloWorld アプリケーションクラスの定義

//
//  HelloWorld.hpp
//

#ifndef __HELLOWORLD_HPP
#define __HELLOWORLD_HPP

#include <SophiaFramework.hpp>
#include "HelloWorld.bid"

//
//  HelloWorld アプリケーションクラス
//
SFMTYPEDEFCLASS(HelloWorld)
class HelloWorld : public SFRApplication {
    SFMSEALCOPY(HelloWorld)
public:
    static SFCInvokerPtr Factory(Void);
private:
    HelloWorld(Void) static_throws;
    virtual ~HelloWorld(Void);
    HANDLER_DECLARE_VOIDRENDER(OnRenderContent)
    HANDLER_DECLARE_BOOLEVENT(OnKey)
};

#endif // __HELLOWORLD_HPP //
[Note] SFC アプレットの場合

GUI フレームワークを使わない SFC アプレットSFCApplication クラスを継承します。

4.2.3. コンストラクタの実装

アプリケーションクラスのコンストラクタでは、 RegisterHandler 関数を使ってイベント ハンドラ関数を登録するなどして、アプリケーションクラスのインスタンスを生成します。 RegisterHandler 関数の引数として、イベントコード、イベントコードに付随するデータ、イベント ハンドラ関数を呼び出すタイミング、イベント ハンドラ関数へのポインタを渡します。

例 4.3. コンストラクタの実装

// コンストラクタ
HelloWorld::HelloWorld(Void) static_throws
{
    if (static_try()) {
        static_throw(
            RegisterHandler(SREVT_RESPONDER_RENDER, 
                            SRP16_RENDER_CONTENT,
                            HANDLER_BEFORE, 
                            HANDLER_FUNCTION(OnRenderContent)));
    }
    if (static_try()) {
        static_throw(
            RegisterHandler(SFEVT_KEY, 
                            HANDLER_AFTER, 
                            HANDLER_FUNCTION(OnKey)));
    }
    return;
}

4.2.4. デストラクタの実装

アプリケーションの終了時にはデストラクタが呼び出され、デストラクタはアプリケーションクラスのインスタンスを破棄します。 ウィンドウやコントロールなどの全ての UI コンポーネントは自動的に破棄されます ( UI コンポーネントに関する破棄処理のコードは不要です )。

例 4.4. デストラクタの実装

// デストラクタ
HelloWorld::~HelloWorld(Void)
{
    return;
}

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

イベント ハンドラはイベントが発生した時の処理を記述するための関数です。

描画イベントが発生した時の処理は描画ハンドラ HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics) で定義します。

キー押下イベントが発生した時の処理はキーハンドラ HANDLER_IMPLEMENT_BOOLEVENT(HelloWorld, OnKey, event) で定義します。

4.2.5.1. 描画ハンドラの実装

graphics->DrawText 関数を使って、文字列 "Hello World" を画面に表示します。

[Caution] 注意
GUI フレームワークを使う SFR アプレットでは、すべての描画処理は描画ハンドラ内で行わなければいけません。 ( 描画ハンドラの外で行われた描画に対しては開発者がすべての状態を管理する必要があります )

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

// 描画ハンドラ
HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics)
{
    graphics->DrawText("Hello World", GetContentWorld());
    return;
}

4.2.5.2. キーハンドラの実装

セレクトキーが押されたとき、アプリケーションを終了するキーハンドラの定義です。

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

// キーハンドラ
HANDLER_IMPLEMENT_BOOLEVENT(HelloWorld, OnKey, event)
{
    switch (event.GetP16()) {
        case AVK_SELECT: // セレクトキーが押されたとき
            Terminate(); // アプリケーションを終了する
            return true;
    }
    return false;
}
[Caution] 注意

Terminate 関数を呼び出すと、デストラクタが呼び出されてアプリケーションは終了します。

4.2.6. グローバル変数の定義とアクセス

アプリケーションのインスタンスは、アプリケーション内のどこからでも SFRApplication::GetInstance 関数を使ってアクセスできます。 このため、グローバルな変数は下記のようにアプリケーションクラスに定義します。

例 4.7. グローバルな変数の定義とアクセス

//
//  ExampleAppli アプリケーションクラス(AppWizard で自動生成)
//
SFMTYPEDEFCLASS(ExampleAppli)
class ExampleAppli : public SFRApplication
{
    SFMSEALCOPY(ExampleAppli)
public:
    static SFCInvokerPtr Factory(Void);
private:
    explicit ExampleAppli(Void) static_throws;
    virtual ~ExampleAppli(Void);

    // グローバル変数 global_something_val を定義する
    SInt32 global_something_val;
public:
    // グローバル変数 global_something_val にアクセスするための GetGlobalSomethingVal() 関数を宣言する
    SInt32 GetGlobalSomethingVal();
};

// グローバル変数 global_something_val にアクセスするための GetGlobalSomethingVal() 関数を定義する
ExampleAppli::GetGlobalSomethingVal(Void)
{
    return global_something_val;
}

// GetGlobalSomethingVal() 関数経由でグローバル変数 global_something_val の値を取得する
static_cast<ExampleAppli>(SFRApplication::GetInstance())->GetGlobalSomethingVal();

4.2.7. エラー処理の機構

コンストラクタで使用している static_try 関数と static_throw 関数は、 エラー値を検証するための関数とエラー値を設定するための関数です。

設定されたエラー値は static_catch 関数で取得できます。 通常、static_catch 関数はエラー値を throw するクラスを利用する側で使います。

例 4.8. エラー値をキャッチしエラー処理するコード

helloworld = ::new HelloWorld();
switch( helloworld->static_catch() ){

        // エラー値に応じてエラー処理をする

};

static_exception クラスはエラー値を管理する変数を持っています。 この変数はテンプレート型で通常 SFCError 型が利用されます。

static_exception クラスの存在意義は、コンストラクタやオペレータでのエラー値を外部に搬出する、一般的な規約を制定する点にあります。