この内容は、
アプリケーションライブラリで提供される各機能の使い方について、
補助的な説明を行うものである。
主な内容は以下の2部から構成されている。
尚、各関数に関する具体的な説明については、 「2.6 パネル」、 「2.7 メニュー」、 「2.18 その他」 を参照されたい。
ここでは、データボックスを併用し且つ直接システムコールを利用する事なく、
パネル及びメニューを表示・操作する方法について、例を挙げながら解説を行う。
まず、使用するデータボックスでは、
以下の内容を必ず組み込まなければならない。
stddef.d
より組み込むべき内容..Base = BASE ----// データ参照テーブル //-------------------------------------------------- -- (データ番号)と(オフセット)のペアのエントリとなっており、 -- データ番号によりデータを検索するため、エントリの順番は任意。 .BASE = 0L --/ データ番号カテゴリ /-- .SPNL = 0x8000 -- 標準パネルデータ番号 .PSTR = 0x9000 -- パネル文字列バッファデータ番号 .MENU = 0xA000 -- メニューデータ番号 .SMSG = 0xB000 -- システムメッセージデータ番号 .MISC = 0xF000 -- その他のデータ番号 ----// パーツ定義 //---------------------------------------------------------- -- 各パーツの定義データはパーツの定義データと等しい。 -- r.c.right はパーツの幅、r.c.bottom は パーツの高さを示す。 -- r.c.left が +CU の場合は、標準文字サイズ / 16 の単位であることを示す .BASE = 0L --/ パーツタイプ /-- .TB_PARTS = 1 -- テキストボックス .XB_PARTS = 2 -- シークレットテキストボックス .NB_PARTS = 3 -- 数値ボックス .SB_PARTS = 4 -- シリアルボックス .AS_PARTS = 5 -- オルタネートスイッチ .MS_PARTS = 6 -- モーメンタリスイッチ .PA_PARTS = 7 -- ピクトグラムオルタネートスイッチ .PM_PARTS = 8 -- ピクトグラムモーメンタリスイッチ .WS_PARTS = 9 -- スイッチセレクタ .SS_PARTS = 10 -- スクロールセレクタ .VL_PARTS = 11 -- ボリューム .HWS_PARTS = WS_PARTS+P_HALIGN .HVL_PARTS = VL_PARTS+P_HALIGN+P_DISABLE+P_NONOB .XHVL_PARTS = VL_PARTS+P_HALIGN .DTB_PARTS = TB_PARTS+P_DISABLE .VOB_PARTS = 0x7fff -- 仮身表示領域 --/ パーツ状態・属性 /-- .P_DISABLE = 0x800 -- 不能パーツ .P_PRESS = 0x040 .P_DCLICK = 0x080 .P_HALIGN = 0x020 .P_DOUBLE = 0x040 .P_NOSEL = 0x080 .P_NOFRAME = 0x400 .P_ND = 0x400+0x800 -- P_NOFRAME+P_DISABLE .P_INACT = 0x1000 .P_DISP = 0x4000 .P_DPNF = 0x400+0x80 -- P_NOFRAME+P_APPEND .P_DPAP = 0x4000+0x80 -- P_DISP+P_APPEND .P_NONOB = 0x0080 .P_APPEND = 0x0080 .P_EMPHAS = 0x0200 --/ 属性コード /-- .BASE = 0H .MC_STR = 0x1000 .MC_ATTR = 0x1002 .MC_LINE = 0x1004 .MC_INACT = 0x1800 .MC_IND = 0x1100 .MC_EMPHAS = 0x1400 .MC_FIG = 0x1001 .CU = 0x8000 -- 標準文字サイズ / 16 単位 ----// 標準パネル定義 //------------------------------------------------------ -- (項目指定 項目オフセット) のペアで定義する。 -- 最大 64 項目まで -- 内部番号により処理との対応をとるため、項目の配置は任意に変更可能。 -- 項目の定義は、左から右、上から下への順で定義する。 -- -- 項目指定: E D C F R M T N N N N N T T T T -- B K K K K .BASE = 0L -- T : パネル項目タイプ .NULL = 0 -- 空項目 rect -- offset は RECT データの先頭を示す。 .PNTR = 1 -- ポインタ項目 h, v, dnum [,data] .PICT = 2 -- ピクトグラム項目 h, v, dnum [,data] .PATN = 3 -- パターン項目 h, v, dnum [,data] .BMAP = 4 -- ビットマップ項目 h, v, dnum [,data] -- 上記の 4 つの場合、offset は 以下のデータ列の先頭 -- を示す。 -- h: 水平サイズ(ドット数) -- v: 垂直サイズ(ドット数) -- dnum: データ番号 -- data: データ本体(データ番号 = 0 の時のみ) .ATXT = 5 -- 属性付文字列 h, v, data -- offset は 以下のデータ列の先頭を示す。 -- h: 全体の水平サイズ(ドット数) -- v = 0 の時は、標準サイズでの文字数 -- を示す。 -- v: 全体の垂直サイズ(ドット数) -- v = 0 の時は、標準文字サイズを示す。 -- data: 文字列データ本体 .TEXT = 6 -- 文字列 data -- offset は 文字列データの先頭を示す。 .PART = 7 -- パーツ data -- offset は パーツ定義データの先頭を示す。 .ACTI = 8 -- ACT_ITEM .RECT = 8 -- NULL + ACT_ITEM .FTXT = 0x206 -- TEXT と同じであるが、項目の長さを標準文字サイズの -- 固定ピッチで計算する。 -- 特殊タイプ: .Vadj = 0x0c00 -- 垂直位置調整項目 -- offset は垂直位置の増加分を(標準文字サイズ / 16) -- の単位で示す。(ーの値も可能) .Hadj = 0x0c01 -- 水平位置調整項目 -- offset は水平位置の増加分を(標準文字サイズ / 16) -- の単位で示す。(ーの値も可能) .Vpos = 0x0c02 -- 垂直位置一時調整項目 -- offset は垂直位置の増加分を(標準文字サイズ / 16) -- の単位で示す。(ーの値も可能) -- 続く 1 項目のみの垂直位置を調整する。 .Habs = 0x0c03 -- 水平絶対位置(左から)指定項目 -- offset は水平絶対位置を(標準文字サイズ / 16) -- の単位で示す。 .Hsav1 = 0x0c10 -- 現在の水平位置を保存。offset は記述しないこと。 .Hsav2 = 0x0c11 -- .Hsav3 = 0x0c12 -- .Hsav4 = 0x0c13 -- .Hrst1 = 0x0c20 -- 保存した水平位置に設定。offset は記述しないこと。 .Hrst2 = 0x0c21 -- .Hrst3 = 0x0c22 -- .Hrst4 = 0x0c23 -- -- K : 種別、B : ブザー::先頭項目のみ .pNRM = 0x0000 -- パネル形状 0 (通常) .pERR = 0x0110 -- パネル形状 1 (警告)+ブザー -- N : 内部番号 : 先頭項目以外(0 〜 31) .pIN0 = 0x0000 -- 内部番号 0 .pIN1 = 0x0010 -- 内部番号 1 .pIN2 = 0x0020 -- 内部番号 2 .pIN3 = 0x0030 -- 内部番号 3 .pIN4 = 0x0040 -- 内部番号 4 .pIN5 = 0x0050 -- 内部番号 5 .pIN6 = 0x0060 -- 内部番号 6 .pIN7 = 0x0070 -- 内部番号 7 .pIN8 = 0x0080 -- 内部番号 8 .pIN9 = 0x0090 -- 内部番号 9 .pIN10 = 0x00a0 -- 内部番号 10 .pIN11 = 0x00b0 -- 内部番号 11 .pIN12 = 0x00c0 -- 内部番号 12 .pIN13 = 0x00d0 -- 内部番号 13 .pIN14 = 0x00e0 -- 内部番号 14 .pIN15 = 0x00f0 -- 内部番号 15 .pIN16 = 0x0100 -- 内部番号 16 .pIN17 = 0x0110 -- 内部番号 17 .pIN18 = 0x0120 -- 内部番号 18 .pIN19 = 0x0130 -- 内部番号 19 .pIN20 = 0x0140 -- 内部番号 20 .pIN21 = 0x0150 -- 内部番号 21 .pINE = 0x01F0 -- 内部番号 31 : エラー情報用 .pMID = 0x0400 -- 中央に配置 (横の列で 1 つのみ) .pRIT = 0x0800 -- 右端に配置 (横の列で 1 つのみ) .pFIL = 0x1000 -- 水平(pNXT の時) / 垂直(pNXTで無いとき)詰め指定 .pNXT = 0x2000 -- 次に水平継続項目がくる .pDEF = 0x4000 -- デフォールトスイッチ (全体で 1 つのみ) .pEND = 0x9000 -- 最終項目(+ 詰め指定) ----// メニューデータ定義 //-------------------------------------------------- -- 項目の順番の変更、項目の削除の場合は、項目番号変換テーブルの内容も -- 変更する必要がある。 -- 最大親項目数は 16 個まで -- キーメニューを設定する場合は、「英大文字」のモードで入力される文字を -- 指定する。 --/ 共通メニュー /-- .BASE = 0L .MN_WINDOW = 1 -- [ウィンドウ]メニュー指定 .MN_TOOL = 2 -- [小物]メニュー指定 .MN_EXEC = 3 -- [実行]メニュー指定 .MN_VOBJ = 4 -- [仮身操作]メニュー指定 .MN_FILE = 5 -- [ファイル操作]メニュー指定 .MN_DISK = 6 -- [ディスク操作]メニュー指定 --/ メニュー属性コード /-- .BASE = 0H .MC_STRKEY4 = 0x1040 -- MC_STR + 4 キーマクロ .MC_INDKEY4 = 0x1140 -- MC_IND + 4 キーマクロ .MC_STRKEY1 = 0x1010 -- MC_STR + 1 キーマクロ .MC_INDKEY1 = 0x1110 -- MC_IND + 1 キーマクロ .MC_INDATR = 0x1102 -- MC_IND + MC_ATTR .BASE = Base
libapp.d
より組み込むべき内容..Base = BASE .BASE = 0H .err_dmy: "\0"
なお、上記の内容は stddef.d
及び libapp.d
によって宣言されているので、
これを include するという方法もある。
次に、パネル及びメニューをデータボックス中で宣言する方法について述べる。
例として、「[テスト]と表示されるパネル」・ 「エラーパネル」・「更新して保存の時に出るパネル」と、 「一般的なメニュー」の表示方法について取り上げる。
まず、データボックスの先頭では以下のような内容が必要となる。
この内容は、 データボックス内で宣言する各要素に対するオフセット値のテーブル (フォーカステーブル)であり、 アプリケーションライブラリではデータボックスを参照する際に、 この値を元にポインタを割り出している。 そのため、この内容を省く事はできない。
.BASE = 0L DATA_END/4 -- データエントリ数 -- パネル宣言部 SPNL+0 pnl_test SPNL+1 epnl_window SPNL+2 pnl_update -- メニュー宣言部 MENU+0 test_menu .DATAEND:
まず、パネルの使い方から説明する。
最初にパネル内で使用するパーツの宣言を行う。
MS_PARTS
はテキストモーメンタリスイッチである事を意味し、
それ以降の内容は
単にパーツマネージャで定義された内容を宣言しているだけである。
.BASE = 0H .sw_cnfm: MS_PARTS {0+CU 0 88 24} -- [確認] 0L OFFSET:L+4 MC_STR "確認\0" .sw_cancel: MS_PARTS {0+CU 0 88 24} -- [取り消し] 0L OFFSET:L+4 MC_STR "取り消し\0" .sw_update: MS_PARTS {0+CU 0 114 24} -- [更新して終了] 0L OFFSET:L+4 MC_STR "更新して終了\0" .sw_destroy: MS_PARTS {0+CU 0 114 24} -- [廃棄して終了] 0L OFFSET:L+4 MC_STR "廃棄して終了\0"
続いて、パネルそのものの宣言を行う。
TEXT
は文字列を指し、
PART
はパーツを使用する事を意味する。
また、これらにつづいて +***+***
となっている部分では属性を宣言するものである。
この属性は、おおまかに以下のようになっている
(他の内容については前述の stddef.d
の内容を参照)。
pERR : エラーパネルとする pMID : 中央に表示する pRIT : 右端に表示する pDEF : デフォルトスイッチとする pNXT : 改行しないで続けて次のパーツを表示する pINn : 複数個パーツがあった時のパーツの番号 pINE : エラー情報用のダミー領域である事を宣言 pEND : パネルに表示したい内容の終点
.BASE = 0L .str_test: "テスト\0" .pnl_test: TEXT str_test PART+pMID+pDEF+pEND sw_cnfm .str_window: "ウィンドウが開けませんので終了します。\0" .epnl_window: TEXT+pMID+pERR str_window TEXT+pMID+pINE err_dmy PART+pMID+pDEF+pEND sw_cnfm .str_update: "現在の内容は元の内容と異なっていますがどうしますか?\0" .pnl_update: TEXT str_update PART+pIN0+pNXT sw_cancel PART+pIN1+pMID+pNXT sw_destroy PART+pIN2+pRIT+pDEF+pEND sw_update
次に、メニューの宣言を行う方法を示す。
ユーザ側で独自に使用したい内容に加えて、
MN_WINDOW
や MN_TOOL
といった宣言を追加する事により、
ウィンドウメニューや小物メニューを追記する事が可能である。
.BASE = 0L .test_menu: menu_cnv -- 変換テーブル 0 -- メニューの属性 mitem_0 -- [終了] mitem_1 -- [操作] MN_WINDOW -- [ウィンドウ] MN_TOOL -- [小物] 0 -- 終点 .BASE = 0H -- メニューの内容を宣言 .mitem_0: MC_STRKEY1 "E" "終了" 0 .mitem_1: MC_STR "操作" MC_STRKEY1 "T" "テスト" 0 .menu_cnv: -- 内部番号への変換テーブル 0x001 0 0 -- [終了] 0x101 1 1 -- [操作] - [テスト]
以上までの事をまとめると、以下のように記述されるる
#include <stddef.d> -- なるべく先頭で組み込む --======== データボックス内の各内容のデータフォーカステーブル .BASE = 0L DATA_END/4 -- データエントリ数 -- パネル宣言部 SPNL+0 pnl_test SPNL+1 epnl_wind SPNL+2 pnl_update -- メニュー宣言部 MENU+0 test_menu .DATAEND: #include <libapp.d> -- この辺りに入れておく --======== パーツの宣言 .BASE = 0H .sw_cnfm: MS_PARTS {0+CU 0 88 24} -- [確認] 0L OFFSET:L+4 MC_STR "確認\0" .sw_cancel: MS_PARTS {0+CU 0 88 24} -- [取り消し] 0L OFFSET:L+4 MC_STR "取り消し\0" .sw_update: MS_PARTS {0+CU 0 114 24} -- [更新して終了] 0L OFFSET:L+4 MC_STR "更新して終了\0" .sw_destroy: MS_PARTS {0+CU 0 114 24} -- [廃棄して終了] 0L OFFSET:L+4 MC_STR "廃棄して終了\0" --======== パネルの内容の宣言 .BASE = 0L .str_test: "テスト\0" .pnl_test: TEXT str_test PART+pMID+pDEF+pEND sw_cnfm .str_window: "ウィンドウが開けませんので終了します。\0" .epnl_window: TEXT+pMID+pERR str_window TEXT+pMID+pINE err_dmy PART+pMID+pDEF+pEND sw_cnfm .str_update: "現在の内容は元の内容と異なっていますがどうしますか?\0" .pnl_update: TEXT str_update PART+pIN0+pNXT sw_cancel PART+pIN1+pMID+pNXT sw_destroy PART+pIN2+pRIT+pDEF+pEND sw_update --======== メニューの宣言 .BASE = 0L .test_menu: menu_cnv -- 変換テーブル 0 -- メニューの属性 mitem_0 -- [終了] mitem_1 -- [操作] MN_WINDOW -- [ウィンドウ] MN_TOOL -- [小物] 0 -- 終点 .BASE = 0H -- メニューの内容を宣言 .mitem_0: MC_STRKEY1 "E" "終了" 0 .mitem_1: MC_STR "操作" MC_STRKEY1 "T" "テスト" 0 .menu_cnv: -- 内部番号への変換テーブル 0x001 0 0 -- [終了] 0x101 1 1 -- [操作] - [テスト] --========
次に、 このデータボックスをアプリケーションの側で利用する方法についてを述べる。
まず、データボックスで宣言した内容と同じ項目番号で、 使用する内容に対する名前を宣言しておかなければならない。 その為、ヘッダファイルなどで以下の内容を宣言する。
/* データボックスのデータフォーカステーブルでの番号と合わせる為 */ #define DB_SPNL 0x8000 /* 単純パネルデータ番号 */ #define DB_PSTR 0x9000 /* パネル文字バッファデータ番号 */ #define DB_MENU 0xa000 /* メニューデータ番号 */ #define DB_SMSG 0xb000 /* システムメッセージデータ番号 */ #define DB_MISC 0xf000 /* その他のデータ番号 */ /* データボックスのデータフォーカステーブルで宣言した順に */ #define PNL_TEST (DB_SPNL + 0) /* [テスト]のパネル */ #define EPNL_WINDOW (DB_SPNL + 1) /* エラーパネル */ #define PNL_UPDATE (DB_SPNL + 2) /* [更新]確認のパネル */ #define TEST_MENU (DB_MENU + 0) /* メニュー */
main()
などで以下のような操作を行う
(レコードタイプ10にデータボックスがある場合とする)。
・ ・ /* ほかの設定内容 */ ・ prc_inf(0, PI_LINK, (VP)&lnk, sizeof(LINK)); /* lnk : 自アプリケーション実身へのリンク */ opendbox(&lnk, USER_DATA, 0x2000); getscreen(); /* 画面情報の取得 */ initstdpnl(); /* パネルの初期化 */ ・ ・ /* ほかの設定内容 */ ・ openmenu(TEST_MENU); /* メニューを設定 */ ・ ・ /* ほかの設定内容 */ ・ evt_loop(&wfunc, window); /* イベントループの開始 */ ・ ・ /* 終了処理 */ ・ closemenu(); /* メニューを廃棄 */ closedbox(); /* データボックスを閉じる */ ・ ・ /* 終了処理 */ ・
このようにする事により、 上述したデータボックスを使用する事ができるようになる。
パネルを開く場合は、開く必要がある時に、 適宜以下のような操作を行えばよい。
---- エラーパネルを開く /* er : エラーコード */ errpanel(EPML_WINDOW, er); /* エラーパネルを開く */ ---- 普通のパネルを開く panel(PNL_TEST); /* 標準パネルを開く */ ---- 終了確認パネルを開く rv = panel(PNL_UPDATE); /* 終了確認パネルを開く */ swicth (rv) { case 0: /* 取り消し */ break; case 1: /* 廃棄して終了 */ break; case 2: /* 更新して終了 */ break; default: }
メニューを開くにはイベントループのメニューイベント処理関数で、
---- メニューを開く /* mfunc : メニュー処理関数 */ selmenu(-1, mfunc); /* メニューを開く */
とすればデータボックスで設定したメニューを開く事ができる
(mfunc
に各メニュー項目([終了]・[操作]・[小物]など)
の処理用の関数テーブルを設定しなければならない)。
なお、以上の内容は説明に必要な箇所だけを抜き出して記述しており、 ほかに行わなければならない操作が記述されていないので注意が必要である。
ここでは、 システム環境設定やユーザ環境設定などで利用されている 見出しパネルの利用方法について解説を行う。
見出しパネルとは、見出しとなるタグを持ち、 各見出し毎にページとして操作できるようになる 一種のパーツのようなライブラリである。 しかし、 見出しパネルで管理するのは各見出しのタブの部分までであり、 各ページの中にパーツなどを登録して 自動的に操作を行えるようにできるものではない。
そのため、見出しパネルを使用しているアプリケーションでも、
結局は ccre_par()
などによってパーツの登録を行い、
またそれらパーツの表示領域も見出しパネルの領域内に入るようにして、
あたかも見出しパネルのページ内にパーツが登録されて動作しているかのように振る舞っているだけである。
また、見出しパネルの再表示などについても、 他のパーツ同様にアプリケーションに一任されている。
見出しパネルを用いる場合、一般に以下の操作を行う。
cre_tagpnl()
によってウィンドウに登録を行い、
初期ページで表示されるべきパーツ類を
ccre_par()
などによって 登録・表示を行う。
dsp_tagpnl()
によって、
再表示が必要な場合は再表示を行う。
pres_tagpnl()
によって見出しパネルが押されたのかを判断させる。
見出しパネルでなければ、他のパーツに対する操作を行う。
sw_tagpnl()
によって見出しパネルのページの変更を行う。cdel_par()
によって廃棄しなければならない。evt_loop()
にそのまま戻り、
2.或いは3.の動作を繰り返す事となる。
dsp_tagpnl()
によって見出しパネルの現在のページの変更を表示しなければならない。ccre_par()
によって現在のページに応じたパーツの登録などの操作を行う。
evt_loop()
に復帰し、
2.ないしは3.の動作を繰り返し行う。
del_tagpnl()
によって、
見出しパネルを廃棄する。
なお、ここでは見出しパネルの表示・切り替え・ 廃棄操作の行い方を説明するに留まり、 実際に一般のパーツ類を併用した場合については割愛する。
見出しパネルは、 見出しとなる文字を登録するだけで利用する事が可能である。
書式は以下のようである。
見出しの親・子を作る @name\n : 親 +name\n : 子(追加) 親子のない見出しを作る name\n
たとえば、子ページを2つ持つ親1つと、 子をもたないもの2つを作る場合では以下のようになる。
TC page11[] = {L"@親ページ1",L"子ページ11"}; TC page12[] = {L"+子ページ12"}; TC page21[] = {L"親ページ2"}; TC page31[] = {L"親ページ3"};
次に、これら見出しの文字をテーブルに登録する。
VP pnl_tbl[4] = {page11, page12, page21, page31};
次に、このテーブルを cre_tagpnl()
に引き渡すことにより、
見出しパネルをウィンドウに登録する事ができるようになる。
引数は以下のようになる。
cre_tagpnl(wid, 4, (TC *)pnl_tbl, &rect, subrp, wbgpat, pbgpat, &tagpnl);
このようにする事より、今後は tagpnl
を通じて見出しパネルの操作を行えるようになる。
イベントループの中でプレスイベントを受けた場合は、
evt_press() /* プレスイベント処理 */ { RECT r; i = pres_tagpnl(tagpnl, &wevt); if (i > 0) { sw_tagpnl(tagpnl, i, &r); dsp_tagpnl(tagpnl, &r); } }
とする事により、見出しパネルの切り替え・再表示を行う事ができる。
基本的に見出しパネルでは見出しタブのプレスや再表示以外には呼応すべきイベントはないので、ほかのイベントについては特に考慮する必要はない。
見出しパネルを終了(ウィンドウから削除)するには、
del_tagpnl(tagpnl);
とすればよい。
大抵の場合、アプリケーションの先頭(初期化部)で
cre_tagpnl()
を行い、
アプリケーションの末尾(終了処理部)で
del_tagpnl()
を行う事になると思われる。
これらをまとめて表記すると、以下のようになる。
#include <btron/libapp.h> /* 見出しパネルはlibappを使う */ #define MAX_PNLNUM 4 /* 見出しのページ数 */ LOCAL TC page11[] = {L"@親ページ1",L"子ページ11"}; LOCAL TC page12[] = {L"+子ページ12"}; LOCAL TC page21[] = {L"親ページ2"}; LOCAL TC page31[] = {L"親ページ3"}; LOCAL VP pnl_tbl[MAX_PNLNUM] = {page11, page12, page21, page31}; LOCAL VP tagpnl = NULL; main() { ・ ・ /* 色々とした初期化 */ ・ cre_tagpnl(wid, MAX_PNLNUM, (TC *)pnl_tbl, &rect, subrp, wbgpat, pbgpat, &tagpnl); ・ ・ /* 色々とした初期化 */ ・ evt_loop() /* イベントループに入る */ ・ ・ /* 他の終了処理 */ ・ if (tagpnl != NULL) del_tagpnl(tagpnl) ・ ・ /* 他の終了処理 */ ・ } evt_press() /* プレスイベント処理 */ { /* wevtにwindow eventが入っている事 */ RECT r; i = pres_tagpnl(tagpnl, &wevt); if (i > 0) { sw_tagpnl(tagpnl, i, &r); dsp_tagpnl(tagpnl, &r); } }
但し、wid, rect, subrp, wbgpat, pbgpat
の内容に関しては他で定義されていなければならない。
また、include
しているファイルについても割愛されているものがあるので、
他に必要な内容に関して適宜 include
しておかなければならない。