シリーズ「BREWで複数画面を(分割して開発可能な)開発する場合の方法論」のつづきです。
前回、第一画面を入れたので、今回は、第二画面を入れます。
この作業は、第一画面作成作業と同時に出来ます。
今回は、第二画面作成というより、一般的に、この方式で画面を作る場合について説明します。
なお、第一作業と並行できるため、今回は、前々回の全体作業が終わったところからはじめるものとします。
■IHTMLCTLの取り込み
これは、前回の第一画面のときとまったく同じです。
以下のファイルをプロジェクトに追加します。
IHtmlCrl.c IHtmlCtl.h
■全体部分の修正
第一画面のように、はじめの画面の場合は、問題ないのですが、第二画面のように、途中からはじめる場合、共通領域に、受け渡す値をセットして、ハンドルイベントのスタートで、対象画面が始まるようにします。
・共通領域に、受け渡す値をセット
関数fukusu1_InitAppData内で、共通領域を初期化するところを
// テスト用に設定
STRCPY(pMe->sei_ritu,"20");
STRCPY(pMe->byo,"40");
のように、ダミーで受け渡す値をセットします
・ハンドルイベントのスタートで、対象画面が始まる
fukusu1_HandleEventで、
// スタート時に、はじめの画面を呼ぶ
if ( eCode == EVT_APP_START)
{
// ここをはじめの画面に変える
return gamen2_InitAppData(pMe);
}
のように、第二画面(gamen2_InitAppData)から始めています。
これらの修正を行ったものが、以下のソースです。
fukusu1.c
■gamen2.hの修正
修正をらくにするため、以下の変数を取っています。
#define GAMEN2_NO 2 // この画面の画面番号
#define GAMEN2_ITEM_SU 2 // この画面の項目数
#define GAMEN2_FNAME "gamen2.htm" // 読み込みファイル名
どのように楽なのかは、gamen3.cのところで説明します。
今回、領域の構造体は、以下の形になります。
typedef struct _gamen2 { IDisplay *pIDisplay; IShell *pIShell; IHtmlCtl *phc; int curno; // カーソルの番号 // カーソル移動 int cur_next[GAMEN2_ITEM_SU]; int cur_down[GAMEN2_ITEM_SU]; } gamen2; |
この画面では、共通領域の値をInitAppDataで参照するだけなので、
とくに必要ないので、とっていません。
カーソル移動のcur_next、cur_downに関しては、gamen2.cの
gamen2_NextCurItemで説明します。
あとは、関数宣言となります。
これらの修正を行ったものが、以下のソースです。
gamen2.h
■gamen2.cの修正
以下の関数を作成・修正します。
boolean gamen2_InitAppData(fukusu1* pMe);
boolean gamen2_HandleEvent(fukusu1* pMe,AEEEvent eCode, uint16 wParam,uint32 dwParam);
void gamen2_FreeAppData(fukusu1* pMe);
boolean gamen2_DispAppData(gamen2* pMe);
int gamen2_NextCurItem(gamen2* pMe,int flg);
以下、各関数について説明します。
●gamen2_InitAppDataについて
この関数の中では、
・領域確保
・表示するHTMLファイルの取得
・HTMLViewer生成
・HTMLViewerデータ設定
・HTMLViewer表示・メモリ解放
を行います。以下順次説明します
(1)領域確保
ここでは、以下の処理を行います。
・画面領域を確保し、
・アプリ全体の領域のgareaに画面領域を設定
画面番号も設定
・アプリ全体の領域の内容を、画面領域に設定
・カーソル移動設定
共通領域から画面の共通領域に保存しておいたほうがいい
ものがある場合は、ここでコピーしますが、今回はないので
その処理はしていません。
カーソル移動設定とは、後述のgamen2_NextCurItemで
行います。カーソル移動が複雑でないとき便利です。
なお、ここ以外でも、画面番号が必要なところがあるので
GAMEN2_NOとマクロにしています。
こうすると、違う画面に、このソースを流用する場合、
GAMEN2をGAMEN11とかに変えればいいだけなので、便利です。
(2)表示するHTMLファイルの取得
IHTMLCTL_GetDispFileDataで読み込みます。
読み込むファイルは、GAMEN2_FNAMEとマクロで宣言しています
が理由は、上記GAMEN2_NOと同じです。
なお、そのまま表示する場合は、よいのですが、一部の文字を
入れ替える場合は、ここで入れ替えます。
今回は、あらかじめ、正解率と秒数を%sと書いておいて、
SPRINTFで入れ替えています。
(3)HTMLViewer生成
IHTMLCTL_Createで、生成しています
・HTMLViewerデータ設定
IHTMLCTL_SetDispData(pMe->phc,fdata2)で読み込んだHTMLと、
それに付随する項目の情報を設定しています。
・HTMLViewer表示・メモリ解放
読み込んだHTMLをフリーして、gamen2_DispAppDataで
再描画しています。
●gamen2_HandleEventについて
イベント処理です。
このとき、他の場面にいく場合は、
gamen2_FreeAppData(poya);のように、現在の画面を開放したあと
gamen1_InitAppData(poya);のように、次の画面の開始処理を行います。
また、上下左右キーで、移動するときは
gamen2_NextCurItemで、次のカーソルの位置を求め
(スクロールする場合は、カーソル位置からスクロール位置を求め)
IHTMLCTL_DispData(pMe->phc,カーソル番号,スクロール位置);を呼び出し
gamen2_DispAppDataで再描画します。
終了させるときは、
gamen2_FreeAppDataで現在の画面を開放した後
poya->gno = -1;
として、画面番号を-1にします。
●gamen2_FreeAppDataについて
ここで行う処理は、以下のとおり
・画面の共通領域があれば、それをアプリの共通領域にコピーし
必要があれば画面の共通領域を解放する
(今回はないので省略)
・IHTMLCTLをリリースし、
・親の画面エリアpoya->gareaをクリーンにする。
●gamen2_DispAppDataについて
リドローします。
IHTMLVIEWER_Redrawなど、リドローの関数を
コントロールに応じて呼びます。
●gamen2_NextCurItemについて
次のカーソル位置をもとめます。
今回は、かんたんなものなので、こんな求め方をしています。
・cur_downに、下キーが押されたら、飛んでいく項目番号を順番にいれていき
・cur_nextに、右キーが押されたら、飛んでいく項目番号を順番にいれます。
→ここまでgamen2_InitAppDataで行います。
・そうしたら、キーごとに、まず、現時点のカーソル位置と、
cur_down(またはcur_next)の番号と同じものを探します。
下(右)キーは、その同じモノ(=現在のカーソル位置)の次を取得し
上(左)キーは、その同じモノ(=現在のカーソル位置)の前を取得します
(範囲外になったら補正する)
このようにすると、飛んでいく画面番号をcur_down、cur_nextにセットする
だけで、一般的に、上下左右のキーが求まります。
ここで、画面数が必要なのでGAMEN2_ITEM_SUという形でマクロにしています。
ここまでの修正でできたソースは、以下のようなかんじです。
gamen2.c gamen2.htm
ということで、次は第一画面と第二画面を合わせて完成です。
(って、もうあとソースをいれかえるだけだけなんで、
説明しなくてもいいようなことなんだけど。。。)