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

9.11. メニュー

メニューはレスポンダの一種でありユーザにメニューを表示して 選択させます。メニューの生成方法や使用方法はウィンドウの場合と ほとんど同じですが、テキスト メニューなどは生成するだけで すぐに使えるように実装されています。

9.11.1. メニューの生成

メニューを表示するには生成したいメニューのインスタンスを new 演算子で生成します。

以下にテキスト メニューを表示するサンプル コードを示します。


SFMTYPEDEFCLASS(Demo)

class Demo : public SFRApplication {

  public:

    static inline SFCInvokerPtr Constructor(Void)

    {

      return(new Demo());

    }

	

  private:

    inline Demo(Void)

    {

      SFRMenuPtr     m;

      SFUArrayList   a;

      SFUWideString  i0("item0");

      SFUWideString  i1("item1");

      SFUWideString  i2("item2");



      if (Exception() == NO_ERROR) {

        a.Append(&i0);

	a.Append(&i1);

	a.Append(&i2);

        m = new SFRTextMenu(this,SFURect(10,10,100,100),"Sample",a);

        if (m != NULL) {

          if (Exception(m->Exception()) != NO_ERROR) {

            delete m;

          }

        }

	else {

	  Exception(ENOMEMORY);

	}

      }

      return;

    }

	

    virtual inline ~Demo(Void)

    {

      return;

    }

};

9.11.2. イベントの処理

上記コードではテキスト メニューが表示され、セレクト キーが押されるか クリア キーが押されるとメニューが閉じるというデフォルトの動作をします。 テキスト メニューの動作をカスタマイズするには、SREVT_MENU イベントを 受け取るハンドラを登録します。以下にサンプル コードを示します。


SFMTYPEDEFCLASS(Demo)

class Demo : public SFRApplication {

  public:

    static inline SFCInvokerPtr Constructor(Void)

    {

      return(new Demo());

    }

	

  private:

    inline Demo(Void)

    {

      SFRMenuPtr     m;

      SFUArrayList   a;

      SFUWideString  i0("item0");

      SFUWideString  i1("item1");

      SFUWideString  i2("item2");



      if (Exception() == NO_ERROR) {

        a.Append(&i0);

	a.Append(&i1);

	a.Append(&i2);

        m = new SFRTextMenu(this,SFURect(10,10,100,100),"Sample",a);

        if (m != NULL) {

          if (Exception(m->Exception()) == NO_ERROR) {

	    Exception(m->RegisterHandler(SREVT_MENU,HANDLER_BEFORE,Menu_static,this));

	  }

	  else {

            delete m;

          }

        }

	else {

	  Exception(ENOMEMORY);

	}

      }

      return;

    }

	

    virtual inline ~Demo(Void)

    {

      return;

    }

	

    static inline Bool Menu_static(ConstSFUEventRef e,VoidPtr r)

    {

      DemoPtr(r)->Menu_handler(e.P16(),SFRTextMenuPtr(e.P32()));

      return(TRUE);

    }

	

    inline Void Menu_handler(UInt16 s,SFRTextMenuPtr m)

    {

      switch (s) {

        case SRP16_ESCAPE:

          // something to do

	  break;

        /*case SRP16_CANCEL:

	  break;*/

	default:

	  // something to do

          break;

      }

      m->MenuHandler();

      // or...

      m->Invoke(SFUEvent(SREVT_RESPONDER_DISPOSE,SRP16_DISPOSE_DISPOSE,TRUE));

      // or...

      m->Dispose();

      return;

    }

};

上記コードではセレクト キーが押されたときもしくはクリア キーに よりメニューがエスケープされたときに Menu_handler 関数が 呼び出されます。Menu_handler 関数には選択されている項目の インデックスかキャンセルの理由を表す数値と、オブジェクトへの ポインタが渡されますので、それを利用して処理を行います。 また、ハンドラを登録したときにメニューのデフォルト動作を オーバーライトしているので明示的にメニューを削除しなければ メニューが閉じません。 削除する方法はレスポンダのそれと同じですが、ダイアログと 同じように方法が3通りあります。一つは、メニューのデフォルト ハンドラを呼び出す方法。次は、SREVT_RESPONDER_DISPOSE イベントを メニューに送信する方法、最後は Dispose 関数を使用して削除する方法です。

[Tip] Tip

選択項目のインデックスのうち 65000 番以降はキャンセルの 理由を区別するために使用されますので、インデックスに 使用できません。つまり、メニュー項目は多くても 65000 未満で 無ければなりません。

9.11.3. メニューの種類

メニューはデフォルトで1種類定義されており SFRTextMenu がそれです。 メニューは継承して使用することはできません。 用意されているメニューとまったく異なるメニューを定義する場合は、 SFRMenu から継承します。