Psionのシンプルな開発環境であるOPLの簡単なTipsを週に一度は追加しようと
いう試みです。頓挫したら笑って下さい。
なお、サンプルコード等の著作権は考慮頂かなくて結構です。著作権を
主張するほどの内容はありません(そのままの無断転載は御遠慮願います)。
第3回 メニュー
今回はメニューです。Epoc OSのメニューがMacやWindowsなどのメニューと
異なる点は、メニューバーが常に表示されておらず 必要な時だけ
出現するところでしょう。縦に広がる個々のメニューだけでなく、
メニューが出てくる根っこになるメニューバー自体も普段は隠れているので、
狭い画面をより有効に使える反面、一旦メニューバーを出してからメニューを
選択するというように操作が増えるのが煩わしいという欠点もあります。
メニュー項目の選択方法は大きくふたつあり、ペンで左上のメニューアイコンを
クリックしたり、キーボードのMenuボタンを押してメニューバーを出し、
個々の項目をペンないしカーソルキーで選択する方法と、キーボードから直接
それぞれのメニューに割り当てられているショートカットキーを押す方法です。
後者は直接メニューが表示されるわけではないので、厳密にはメニューの選択
ではありませんが、Epoc OSの作法としては両方とも実装しないと格好悪いですので
ここでは一緒に説明いたします。
まず、イベントループでペンによるメニューアイコン(画面の外の左上のアイコン)の クリックを検出します。これはGETEVENT32で取得したevent&()の一番目が 10000の場合に相当します。同様に、Menuボタンが押された場合は、event&(1)には4150が入ります。両者を区別する必要は特にありません。
GETEVENT32 gEvent&() IF .. ... ELSEIF gEvent&(1)=4150 OR gEvent&(1)=10000 rem -- menu event. rem -- "control+#" event is processed in Event_Key: . Event_Menu: ELSEIF ..このソースではペンによるメニューアイコンのクリックや、Menuボタン押下があった場合Event_Menu:というプロシージャを呼び、その中にメニューの処理を入れています。
proc Event_Menu: local k%, a$(10), cmdstr$(3) cmdstr$ = "dea" mINIT mCARD "File","Dummy",-%d,"Exit",%e mCARD "Info","About..",%a k% = MENU if k% AND (LOC(cmdstr$,chr$(k%))<>0) rem -- it will call "cmd#" (# is d,e or a) a$ = "cmd" + chr$(k%) : @%(a$): endif endp上の4-6行のmINIT/mCARDが具体的なメニューの構造を定義しています。 ここではmCARDを2回呼んでいます。mCARDを1回呼ぶ毎に、メニューバーに 1行メニューが追加されます。
mINIT/mCARDに続くk%=MENUの一文で、ユーザがどのメニューを選んだかを取得できます。ペンを使ったかそれともカーソルキーとリターンキーで選択したかはここでは区別されず、選択されたメニューの値が返されます。キャンセルの場合は0、何かが選択された場合はそのメニューのショートカットのキーコードが返ります。例えば"About"なら%a(=65)です。
LOC()という関数は、第一引数の文字列の何番目に第二引数の文字が入っているかを返す関数です。ここでは、選択されたショートカットが"d""e""a"のどれかであるかどうかの判別に用いています。もし"d""e""a"のいずれかである場合は、"cmd"を頭につけたプロシージャを呼びます。@%(a$):というコードがそれにあたります。これは文字列a$に"%:"をつけたプロシージャ、つまりa$="cmde"ならばcmde%:というプロシージャを呼び出します。もちろん、呼ばれるプロシージャ(cmdd%: cmde%: cmda%:)は別に定義しておく必要があります。
上記のコードだけですと、一度メニューを出さない限りショートカットが動きませんので、直接Ctrl+何かが押された場合のコードも書かなくてはいけません。ここではキーの押下はevent&(1)の値が300以下か否かで判別しています(この300という値は少々自信なし)。
GETEVENT32 gEvent&() IF .. ... ELSEIF gEvent&(1)<=300 Event_Key: ENDIF .. proc Event_Key: local isS%, a$(10), k%, tx%,ty% local cmdstr$(3) cmdstr$ = "dea" if gEvent&(4) AND 4 rem -- Control key is pressed rem -- when ctrl, value of gEvent&(1) is a/A=1, b/B=2,... rem -- then +64 is needed to convert ascii character code. rem -- if you want capital-sensitive code,use gEvent&(4) AND 2 rem -- to find shift is pressed or not. k% = gEvent&(1)+64 if LOC(cmdstr$,chr$(k%)) rem -- it will call "cmd#" (# is d,e or a) a$ = "cmd" + chr$(k%) : @%(a$): return endif endif endpevent&(4)に修飾キーのコードが入っています。Ctrlが押されたかどうかは 4とANDを取ればわかります。(ちなみにShiftの判別はAND 2)
これは、前回と同様ですので省略します。ちなみに、なぜ呼び出されるプロシージャを"cmda%:"などという名称にしたかと言いますと、ツールバーで呼び出されるプロシージャと同じ名称にあわせることでコードが共有できるからというだけの問題です。
今回のサンプルの内容は前回と全く同じものです。
サンプルコード(ttoolbar.opl)
実行バイナリ(ttoolbar.opo)
テキストファイル
圧縮せずにおいてあります。別名で保存などでファイルに落とし、Psionにコピーしてください。
第2回 ツールバー
ツールバーとは、Epoc OS特有のGUIで、一般に右端にあるボタンや時計の表示
された領域のことを指します。
ツールバーには、「他のタスクを表示する」 「ボタンを提供する」「時計や日付やバッテリを表示する」などの機能が 入りますが、実際にプログラムで考えないといけないのは「ボタンを提供する」 部分だけで十分です。ただし、APIとしてはいくつかのオマジナイが必要ですので ひとつという訳にはいきません。
ツールバー用のAPIを利用するために、最初にツールバー用のモジュールを ロードする必要があります(LOADM)。また、TBarLink:()というAPIも最初に呼んでやる 必要があります。引数には、このAPIをコールした後に戻ってきたときの プロシージャの名前を入れてやります。下の例で言うと、TBarLink:()を呼んだ あと、処理はMain:に移ります。
proc Start: LOADM "Z:\SYSTEM\OPL\TOOLBAR.OPO" TBarLink:("Main") endp PROC Main: ...ちょっと注意が必要なのは、Start:のプロシージャにはもう戻らないということです。つまり、TBarLink:()からendpまでの間に何かコードを書いたとしても、そのコードは決して呼ばれないのです。
続いて、ツールバーの本当の初期化ルーチンを書きます。
TBarInit:("tTBar", gWidth, gHeight) TBarButt:("a", 1, "About", 0, &0, &0, 0) TBarButt:("d", 2, "Dummy", 0, &0, &0, 0) TBarButt:("e", 3, "Exit", 0, &0, &0, 0) TBarShow:TBarInit:()の第一引数には、ツールバーの最上段に表示される文字列を入れます。 なお、プログラム実行中に変更することも可能です(TBarSetTitle:()を使う)。また、 大体7文字以上入れると見にくくなるので、そう多くの情報は表示できません。
ツールバーを動作させるのはペン(指でもいいですが)入力のみで、キーボードからは 操作できません。イベントループでペンの入力があった場合には、まずツールバーに対する操作であったかどうかを確認する必要があります。
global gEvent&(16) ... do GETEVENT32 gEvent&() IF gEvent&(1)=Pointer_Used IF TBarOffer%:(gEvent&(3),gEvent&(4),gEvent&(6),gEvent&(7)) RETURN ELSEIF ... until 0GetEvent32でイベントを取得後、ペン入力であった場合はまずTBarOffer%:()を呼びます。もしツールバーに関する入力である場合には、このAPIが自動的にプロシージャを呼ぶなどの処理をやってくれます。ツールバーに関する入力でなかった場合、このAPIはfalseを返すので、ペン入力に対する独自の処理をその下に書けば良いでしょう。
最後に、ツールバーのボタン押下に対する処理を書きます。このプロシージャは TBarOffer%:()から勝手に呼び出されます。
proc cmde%: stop rem -- simply exit endpプロシージャ名はTBarButt:()で設定した文字の前後に"cmd"と"%:"をつけたものにしてください。
サンプルコード(ttoolbar.opl)
実行バイナリ(ttoolbar.opo)
テキストファイル
圧縮せずにおいてあります。別名で保存などでファイルに落とし、Psionにコピーしてください。
第1回 ポップアップメニュー
ポップアップメニューとは、普通のメニューと違い任意の場所に出す
メニューで、カスケード(サブメニュー)ができないなどの制約があります。
一見面倒そうですが実は簡単で、メニューを出したい位置を指定してmPopup()を 呼ぶだけです。ポップアップメニュー表示中は、ペンの他にreturn/esc/arrow/shortcut(ctrl+何か)キーも使えます。escを選ぶと、返り値はゼロになります。
上記のような図を出すコードは以下のようになります。
val% = mPopup(inxpos&, inypos&, 0, "one",1,"two",2,"three",3,"extra",%e)
サンプルコード(tpopmenu.opl)
実行バイナリ(tpopmenu.opo)
圧縮せずにおいてあります。別名で保存などでファイルに落とし、Psionにコピーしてください。
created by H.M 00.09.27