シリーズ仕様書からプログラムソースを生成する方法の続きです。
前のところで、「具体的に」ということだったので、実際に、メニュー項目を入れる話をやってみましょう。
メニュー項目に限らず、このような、雛形があって、そこから、自動生成する場合については、以下のような手順で考えると、考えやすいと思います。
1.仕様を決める
2.仕様を満たすためには、どういう出力をすればいいか-出力ソースサンプルを作る
3.サンプルをもとに雛形を作る
4.雛形から、出力にもってくるプログラム部分を作成する。
まず、今回は1と2について考えます。
■1.仕様
以下のような画面定義をすると

以下のようなメニューの画面

を表示します。
なお、今回は、イベント処理は置いておきます
(他のシリーズでイベント処理についてやっています。
このシリーズが終わったころに、
そっちのシリーズと合流して、イベント処理を追加する予定です)
■2.出力ソースサンプル
仕様書からBREWのソースファイル自動生成で公開したもの(リンク先の一番下のダウンロード)を使って、
まず、以下のように、なにも入れないで、第一画面を作成し、

その後、仕様を満たすようにgamen1.c,gamen1.hを、以下のように修正します
(それ以外の、fukusu2.c,fukusu2.h,version.h,IHtmlCtl.h,IHtmlCtl.c,IKHMap.c,IKHMap.hは、修正しないでメンバーに追加します。fukusu2.bid,fukusu2.mifファイルはMIFエディタを使ってあらかじめ作成しておいてください)
●ヘッダファイル(gamen1.h)
/*========================================
FILE: gamen1.h
=========================================*/
#ifndef _GAMEN1_H
#define _GAMEN1_H
/*==========================================
INCLUDES AND VARIABLE DEFINITIONS
=========================================== */
#include "AEEModGen.h" // Module interface definitions
#include "AEEAppGen.h" // Applet interface definitions
#include "AEEShell.h" // Shell interface definitions
#include "AEEMenu.h"
#include "fukusu2.h" // アプリ画面
//==================================//
// 定数定義 //
//==================================//
typedef struct _gamen1 {
IDisplay *pIDisplay;
IShell *pIShell;
IMenuCtl *pMenu1;
} gamen1;
/*------------------------------------
Function Prototypes
---------------------------------------*/
#ifdef _GAMEN1_C
boolean gamen1_HandleEvent(fukusu2* poya,
AEEEvent eCode, uint16 wParam,uint32 dwParam);
boolean gamen1_InitAppData(fukusu2* poya);
void gamen1_FreeAppData(fukusu2* poya);
// 画面表示
boolean gamen1_DispAppData(gamen1* pMe);
#else
extern boolean gamen1_HandleEvent(fukusu2* pMe,
AEEEvent eCode, uint16 wParam,uint32 dwParam);
extern boolean gamen1_InitAppData(fukusu2* pMe);
extern void gamen1_FreeAppData(fukusu2* pMe);
// 画面表示
extern boolean gamen1_DispAppData(gamen1* pMe);
#endif
#endif
|
(上記のプログラム中の< > ¥は、本当は半角です)
●ソースファイル(gamen1.c)
/*================================
FILE: gamen1.c
=================================*/
#define _GAMEN1_C
#include "gamen1.h"
/*==================================*/
// 関数名:gamen1_HandleEvent //
// 内容 :イベント処理 //
/*==================================*/
boolean gamen1_HandleEvent(fukusu2* poya, AEEEvent eCode,
uint16 wParam, uint32 dwParam)
{
gamen1 *pMe;
// チェック
if ( poya == NULL )
return FALSE;
if ( ( poya->gno != 1 )
|| (poya->garea == NULL ))
return FALSE;
pMe = (gamen1 *)poya->garea;
// 追加:テキストエリア
if ( pMe->pMenu1 != NULL )
{
if ( IMENUCTL_HandleEvent(pMe->pMenu1,
eCode,wParam,dwParam) == TRUE )
{
return TRUE;
}
}
switch (eCode)
{
// App is told it is starting up
case EVT_APP_START:
// Add your code here...
return(TRUE);
// App is told it is exiting
case EVT_APP_STOP:
// Add your code here...
return(TRUE);
// App is being suspended
case EVT_APP_SUSPEND:
// Add your code here...
return(TRUE);
// App is being resumed
case EVT_APP_RESUME:
// Add your code here...
return(TRUE);
// An SMS message has arrived for this app.
// Message is in the dwParam above as (char *)
// sender simply uses this format "//BREW:ClassId:Message",
// example //BREW:0x00000001:Hello World
case EVT_APP_MESSAGE:
// Add your code here...
return(TRUE);
// A key was pressed. Look at the wParam above
// to see which key was pressed. The key
// codes are in AEEVCodes.h.
// Example "AVK_1" means that the "1" key was pressed.
case EVT_KEY:
// Add your code here...
return(TRUE);
case EVT_COMMAND:
switch(wParam)
{
case 2000:
gamen1_FreeAppData(poya);
poya->gno = -1;
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
/*==================================*/
//関数名:gamen1_InitAppData //
//内容 :領域確保・描画 //
/*==================================*/
boolean gamen1_InitAppData(fukusu2* poya)
{
char *fdata;
gamen1 *pMe;
AEERect rect;
AECHAR *menubuf;
char *menuTitle;
//==========================================//
// 領域確保 //
//==========================================//
pMe = (gamen1 *)MALLOC(sizeof(gamen1));
if (pMe == NULL )
{
gamen1_FreeAppData(poya);
return FALSE;
}
// アプリ領域へ設定
poya->garea = (void *)pMe;
poya->gno = 1;
pMe->pMenu1 = NULL;
pMe->pIDisplay = poya->pIDisplay;
pMe->pIShell = poya->pIShell;
//==========================//
// メニューの作成 //
//==========================//
if ( ISHELL_CreateInstance( pMe->pIShell,
AEECLSID_MENUCTL, (void**)&pMe->pMenu1 ) != SUCCESS )
{
gamen1_FreeAppData(poya);
return FALSE;
}
rect.x = 1;
rect.y = 1;
rect.dx = 200;
rect.dy = 150;
IMENUCTL_SetRect(pMe->pMenu1,&rect);
//==========================//
// メニュー項目の表示 //
//==========================//
menuTitle = "開始";
menubuf = (AECHAR *)MALLOC((STRLEN(menuTitle)+1)*sizeof(AECHAR));
if ( menubuf == NULL )
{
gamen1_FreeAppData(poya);
return FALSE;
}
MEMSET(menubuf,0,(STRLEN(menuTitle)+1)*sizeof(AECHAR));
STREXPAND(menuTitle,STRLEN(menuTitle),menubuf,
(STRLEN(menuTitle)+1)*sizeof(AECHAR));
IMENUCTL_AddItem(pMe->pMenu1,NULL,NULL,1000,menubuf,NULL);
FREEIF(menubuf);
menuTitle = "終了";
menubuf = (AECHAR *)MALLOC((STRLEN(menuTitle)+1)*sizeof(AECHAR));
if ( menubuf == NULL )
{
gamen1_FreeAppData(poya);
return FALSE;
}
MEMSET(menubuf,0,(STRLEN(menuTitle)+1)*sizeof(AECHAR));
STREXPAND(menuTitle,STRLEN(menuTitle),menubuf,
(STRLEN(menuTitle)+1)*sizeof(AECHAR));
IMENUCTL_AddItem(pMe->pMenu1,NULL,NULL,2000,menubuf,NULL);
FREEIF(menubuf);
gamen1_DispAppData(pMe);
// 共通領域を設定
// pMe->pMap = poya->pMap;
return TRUE;
}
/*==================================*/
//関数名:gamen1_FreeAppData //
//内容 :領域のフリー //
/*==================================*/
void gamen1_FreeAppData(fukusu2* poya)
{
gamen1 *pMe;
// 対象かどうかチェック
if ( poya->gno != 1 )
return;
if ( poya->garea == NULL )
return;
pMe = (gamen1 *)poya->garea;
// メニューフリー
if ( pMe->pMenu1 != NULL )
{
IMENUCTL_Release(pMe->pMenu1);
pMe->pMenu1 = NULL;
}
FREEIF(pMe);
// 親のエリアをクリア
poya->garea = NULL;
}
/*==================================*/
// 関数名:gamen1_DispAppData //
// 内容 :画面の初期表示 //
/*==================================*/
boolean gamen1_DispAppData(gamen1* pMe)
{
int curpos,buhinpos;
// 初期化
curpos = 0;
buhinpos = 0;
//==================================//
// リドローする //
//==================================//
// ここに、
// 1.リドローと、
// 2.次のフォーカス指示を書く
// テキストエリアのRedrawやUpdateする
if ( pMe->pMenu1 != NULL )
{
// リドロー
IMENUCTL_Redraw(pMe->pMenu1);
// カーソル番号pMe->curnoから、
// 部品の番号(仕様書のA桁のNo)に
// 変換する。その番号をbuhinposだとすると
if(buhinpos == 0)
IMENUCTL_SetActive(pMe->pMenu1,TRUE);
else
IMENUCTL_SetActive(pMe->pMenu1,FALSE);
}
return TRUE;
}
|
(上記のプログラム中の< > ¥は、本当は半角です)
次回のこのシリーズは、3.雛形ソースです。