第6回 PilRC の定義ファイルの書き方 (1) -- メニュー


前回は "Hello World" を、フォームと呼ばれるリソースを使って表示する方法を説明しました。フォームはユーザインタフェースの基本となる部品で、そこにいろいろな部品を配置することでユーザインタフェースを実現します。

その今回は、このフォームにメニューを追加する方法を説明します。

準備


クリエータ ID の登録


前回同様、今回作成するプログラムにも筆者が登録した 'YS00' を使ってください。

作業ディレクトリの作成


ソースコード、オブジェクトコード等を格納する作業ディレクトリを作り、そのディレクトリに移動します。以下の例では MenuHelloWorld という名前のディレクトリを作成しています。

% mkdir MenuHelloWorld
% cd MenuHelloWorld

プログラム作成

新しいファイルをつくり、プログラムを作成します。ファイル名は MenuHelloWorld.c としてください。

今回作成するプログラムは以下の通りです。この内容を MenuHelloWorld.c に書き込んでください。

/*
* PRC-Tools 講座 サンプルプログラム 3
*
* Copyright (c) 2002 WATANABE, Yoshiki
*/

#include <PalmOS.h>
#include "MenuHelloWorldRsc.h"

/*
* StartApplication -- アプリケーションの初期化を行なう
*
* MainForm を開く
*/
static Err StartApplication(void)
{
  FrmGotoForm(MainForm); // MainForm を開く
  return errNone;
}

/*
* OpenAboutDialog -- About ダイアログを表示する
*
* AboutDialog を開き, OK が押されたあとに削除する
*/
static void OpenAboutDialog(void)
{
  FormPtr form = FrmInitForm(AboutDialog);
  FrmDoDialog(form);
  FrmDeleteForm(form);
}

/*
* MainFormHandleEvent -- MainForm に関わるイベントを処理する
*
* MainForm の初期化に関するイベントを処理する
*/
static Boolean MainFormHandleEvent(EventPtr event)
{
  Boolean handled = false;

  switch (event->eType) {
  case frmOpenEvent: // MainForm が開かれた
    FrmDrawForm(FrmGetActiveForm()); // MainForm を表示する
    handled = true;
    break;

  case menuEvent: // メニューが選ばれた
    switch (event->data.menu.itemID) {
    case MainFormAboutCmd: // "About..." が選択された
      OpenAboutDialog(); // About 画面を表示する
      handled = true;
      break;
    }
    break;

  }

  return handled;
}

/*
* ApplicationHandleEvent -- アプリケーション全体に関わるイベントを処理する
*
* 開かれたフォームをアクティブにしイベントハンドラを設定する
*/
static Boolean ApplicationHandleEvent(EventPtr event)
{
  Boolean handled = false;

  if (event->eType == frmLoadEvent) { // フォームをロードする
    UInt16 formId = event->data.frmLoad.formID; // ロードするフォームの ID
                                 // を取得 (この例では常に
                                 // MainForm)
    FormPtr form = FrmInitForm(formId); // フォームをロードして初期化する

    FrmSetActiveForm(form); // ロードしたフォームをアクティブにする

    switch (formId) {
    case MainForm:
      // このフォームに対するイベントを MainFormHandleEvent で
      // 処理するように設定する
      FrmSetEventHandler(form, MainFormHandleEvent);
      break;
    }
    handled = true;
  }

  return handled;
}

/*
* EventLoop -- イベントを取り込み必要な処理を行なう
*
* イベントを処理する API, 関数を適宜呼び出す
*/
static void EventLoop(void)
{
  EventType event;

  do {
    EvtGetEvent(&event, evtWaitForever); // 次のイベントを取得する
    if (!SysHandleEvent(&event)) { // システム関連のイベントを処理する
      Err error;
      if (!MenuHandleEvent(NULL, &event, &error)) { // メニュー関連のイ
                // ベントを処理する
        if (!ApplicationHandleEvent(&event)) {
          // 現在のフォームでイベントハンドラとして設定されている関数
          // を呼び出す (この例では MainFormHandleEvent が呼ばれる)
          FrmDispatchEvent(&event);
        }
      }
    }
  } while (event.eType != appStopEvent); // 終了のイベントが来るまで繰り返す
}


/*
* StopApplication -- アプリケーションの終了時の処理を行なう
*
* 開いているフォームに frmSave を送り, それらのフォームを閉じる
*/
static void StopApplication(void)
{
  FrmSaveAllForms();
  FrmCloseAllForms();
}

/*
* PilotMain -- このアプリケーションのメイン関数である
*
* このサンプルでは通常の起動方法 (sysAppLaunchCmdNormalLaunch) でのみ動作する
*/
UInt32 PilotMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
  Err error = errNone;

  switch (cmd) {
  case sysAppLaunchCmdNormalLaunch:
    error = StartApplication();
    EventLoop();
    StopApplication();
    break;
  }

  return error;
}


MenuHelloWorld.c

基本的な構成は前回のResourceHelloWorld.cと同じです。赤くなっている部分がメニューのために新たに追加した部分です。

メニューの選択時にシステムによってevent->>data.menu.itemIDに設定される値が、あとで紹介するMenuHelloWorld.rcpのMENUITEMのIDで指定された値です。

これらフォームやメニューの ID の値を MenuHelloWorld.c と MenuHelloWorld.rcp で共有するために、ヘッダ・ファイル MenuHelloWorldRsc.hが必要です。以下のような内容で作成してください。

/*
* PRC-Tools 講座 サンプルプログラム 3
*
* Copyright (c) 2002 WATANABE, Yoshiki
*/

#define MainForm 1000

#define MainFormMenuBar 1000

#define MainFormAboutCmd 1001

#define AboutDialog 2000


MenuHelloWorldRsc.h

リソースは MenuHelloWorld.rcp で定義されます。内容は以下の通りです。リソースの ID の値を読み込むためにヘッダ・ファイル MenuHelloWorldRsc.hをインクルードしています。

//
// PRC-Tools 講座 サンプルプログラム 3
//
// Copyright (c) 2002 WATANABE, Yoshiki
//

#include "MenuHelloWorldRsc.h"

// ラウンチャに表示されるアプリケーションの名前
APPLICATIONICONNAME ID 1000 "Hello World"

// アプリケーションのバージョン
VERSION "1.0"

// Hello World を表示するためのフォーム
FORM MainForm AT (0 0 160 160) /* 全画面 (160x160). ID は MainForm */

MENUID MainFormMenuBarBEGIN

  TITLE "Hello..." /* フォームのタイトル */
  LABEL "Hello World" AUTOID AT (CENTER CENTER) /* フォームの中央に表示する */
END

MENU ID MainFormMenuBar /* MainForm のメニュー・バー */
BEGIN
  PULLDOWN "Hello" /* 最初のメニュー. タイトルとして "Hello" と表示される */
  BEGIN
  /* About 画面を表示するための項目.
    コマンドストローク + "H" でも起動できる */
    MENUITEM "About..." ID MainFormAboutCmd "H"
  END
END

FORM ID AboutDialog at (2 63 156 95) /* About 画面. 下の方に表示される. */
MODAL /* モーダル・ダイアログ */
BEGIN
  TITLE "About Hello World"

  LABEL "Hello World with Menu" AUTOID AT (10 18)
  LABEL "Copyright (c) 2002" AUTOID AT (PREVLEFT PREVBOTTOM)
  LABEL " WATANABE, Yoshiki." AUTOID AT (PREVLEFT PREVBOTTOM)
  LABEL "All rights reserved." AUTOID AT (PREVLEFT PREVBOTTOM) /* 表示内容 */

  BUTTON "OK" AUTOID AT (5 78 37 12) /* 閉じるためのボタン */
END


MenuHelloWorld.rcp

これらのファイルと同じ内容のものが MenuHelloWorld.zip または MenuHelloWorld.tgz として置いてありますので、適宜ご利用下さい。

コンパイル

コンパイルの方法は、ファイル名が違うことを除けば、前回と同じです。

まず MenuHelloWorld.c を gcc を使ってコンパイルしてみましょう。ファイルをつくったディレクトリで以下のコマンドを実行してください。

% /usr/local/pilot/bin/m68k-palmos-gcc -palmos3.5 -o MenuHelloWorld MenuHelloWorld.c



続いて MenuHelloWorld.rcp を pilrc を使ってコンパイルしてみましょう。ファイルをつくったディレクトリで以下のコマンドを実行してください。

% /usr/local/bin/pilrc MenuHelloWorld.rcp



この例では、結果として5個のファイル MBAR03e8.bin、tAIN03e8.bin、tFRM03e8.bin、tFRM07d0.bin、tver0001.binが生成されます。 MBAR03e8.binがメニューバーの内容を保持するためのリソース、tFRM07d0.binが "About Hello World" 画面のためのリソースです。

リソース・データベースの作成

前回と同様に、build-prc を使用して目的のリソース作成します。

% /usr/local/pilot/bin/build-prc -t appl MenuHelloWorld.prc "Hello World" YS00 MenuHelloWorld *.bin



これを実行すると MenuHelloWorld.prc という名前でリソース・データベースのファイルが作成されます。これでアプリケーションが完成です。

実行

できあがったアプリケーションを、前回と同様に POSE で実行してみましょう。

1. ラウンチャからアプリケーション "Hello World" を起動すると画面に "Hello..." というタイトルのフォームが表示され、その中央に "Hello World" と表示されます。

Hello World

2. メニューボタンをタップするとメニューが表示されます。

Menu

3. メニューから "About..." を選ぶと "About Hello World" の画面が表示されます。

About Hello World

4. Applications ボタンをタップするとアプリケーション "Hello World" は終了してラウンチャに戻ります。



Copyright (c) 2002 WATANABE, Yoshiki