キー長押しでメニュー選択させたい - 逆引き Casio Basic

逆引き Casio Basic
<目次>

誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します

修正:2015/10/13
[fx-5800P / fx-9860GII / fx-CG20]

メニュー選択機能で、同じキーの長押しにより2つ目の選択肢を与えたい。



1つのキーを普通に押すだけでなく、同じキーの長押しで別の動作ができれば、1つのキーに2つの異なるメニュー機能を与えられる。これによって、プログラム電卓の限られた広さの画面を有効に使える。

そこで、定石として使える汎用性の高いコードを紹介する。

以下のようなサンプルプログラムを作る。

[1] キーと [2] キーには、普通に押した時と長押しで異なる処理を割り当て、
[3] キーには、普通に押した時のみ処理を割り当て、
[4] キーには、長押しした時のみに処理を割り当てる

このサンプルプログラムは、テンキーでメニューを選択させたい - 逆引き Casio Basic のサンプルプログラムを拡張したものだ。


画面に、

1:ONE      2:TWO
3-THREE  4.FOUR


と表示させる。

数字の後ろに : があれば普通に押す時と長押しの両方に対応し、数字の後ろが . になっていれば長押しのみの対応、数字の後ろが - なら普通に押すことのみに対応する...と意味を持たせてある。

ここでは、汎用性のある fx-5800P 用のコードを示す。fx-9860GII や fx-CG20 に対応するには、後述するように4カ所のキーコードの記述を変更するだけで良い。

サンプルプログラムの動作仕様;
  • [1] を押せば 3行目に HIT [1] と表示
  • [2] を押せば 3行目に HIT [2] と表示
  • [3] を押せば 3行目に HIT [3] と表示
  • [1] の長押しで、3行目に LONG PUSH [1] と表示
  • [2] の長押しで、3行目に LONC PUSH [2] と表示 
  • [4] の長押しで、3行目に LONG PUSH [4] と表示
  • 3行目の表示と同時に、4行目右端にガイド表示 <EXE> を示し、[EXE] で再入力できることを示す
  • [1][4] 以外のキーを押したり、[1][2][4] 以外の長押しでも誤動作しない。

サンプルコード
Locate 1,1,"1:ONE"
Locate 9,1,"2:TWO"
Locate 1,2,"3-THREE"
Locate 9,2,"4.FOUR"

While 1

0→M
Do
Getkey→K
LpWhile K=0
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M

0→C
While Getkey=35
Isz C:C=9⇒Break
WhileEnd
C=9⇒11→M

0→C
While Getkey=36
Isz C:C=9⇒ Break
WhileEnd
C=9⇒12→M

0→C
While Getkey=21
Isz C:C=9⇒Break
WhileEnd
C=9⇒14→M


If M=1
Then Locate 1,3,"HIT [1]"
Else If M=2
Then Locate 1,3,"HIT [2]"
Else If M=3
Then Locate 1,3,"HIT [3]"
Else If M=11
Then Locate 1,3,"LONG PUSH [1]"
Else If M=12
Then Locate 1,3,"LONG PUSH [2]"
Else If M=14
Then Locate 1,3,"LONG PUSH [4]"
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd


If M
Then Locate 12,4,"<EXE>"◢
Locate 1,3,"       " (スペース13個
Locate 12,4,"   " (スペース5個)
IfEnd

WhileEnd



定石として使えるのは、赤文字のブロック紫文字のブロック、そして青文字のブロックだ。


サンプルプログラムをブロック構造で示すと、

 [初期表示]

 While 1

   [メニュー選択]

   [キー長押しによるメニュー選択]

   [選択したメニュー番号に応じた分岐処理]

   [後処理]

 WhileEnd


このように構造化され、初期表示を行ったのち、While 1 / WhileEnd で構成された無限ループ内で、メニュー選択→分岐処理→後処理 が繰り返される。

==========

メニュー選択のためのキー入力は、赤文字の部分が定石として使える。

Do
Getkey→K
LpWhile K=0


は、何もキー入力が無い時はこのループをグルグルまわっていて、何かキーが押された時に押されたキーのキーコードを変数 K に格納してからこのループを抜けて、次の処理へ進む。この部分は、テンキー以外のキー入力にも対応できる。

このループに続く以下の部分、

K=35⇒1→M
K=36⇒2→M
K=37⇒3→M


ここで、押されたキーのキーコードに応じて、メニュー変数 M にメニュー番号を格納する。

実は、赤文字の部分の冒頭にある 0→M が極めて重要だ。今回はテンキー [1][3]、つまりメニュー番号が 1 ~ 3 のみで、それ以外のキーを押しても、誤動作しないようにしたい。そこで、操作上メニュー番号が 0 になることが無いので、最初にメニュー変数 M に 0 を入れておく。そしてメニュー選択により M が 1、2、3 のいずれかになる。つまり、変数 M は、0 ~ 3 のいずれかのア値になって、絶対に他の値にならないことを保証しているわけた。そのため、0→M は誤動作防止のために極め重要になる。

長押しに関して、記述の追加が無いことから、汎用性のあるコードだと分かってもらえるだろう。

==========

次に、紫文字のブロックでは、特定キー長押しの検出とメニュー番号への割り振りを行っている。

0→C
While Getkley=35
Isz C:C=9⇒Break
WhileEnd

C=9⇒11→M

ここで、赤文字の 3511 以外は、同じ記述を3回繰り返している。この場合は、[1] の長押しの検出と、[1] 長押しに対応するメニュー番号を 11 として、メニュー変数 M に 11 を格納している。

While Getkey=35
Isz C:C=9⇒Break
WhileEnd


これは、Getkey が実行される時にキーコード 35 に対応する [1] キーが押されていれば、While ループを回るようにしている。
ループを1回回ると、Isz C でカウンタ変数 C を1つ増やす。カウンタ変数 C は、While ループに入る前に 0→C で 0 に初期化されている。

そして、C=9 になったとき、つまりループを9回まわると、C=9⇒Break によりループから強制的に抜けて、次の処理へ続く。
この次の処理が、C=9⇒11→M になっていて、きちんとループを9回まわって抜けてきた場合のみメニュー変数 M に 11 を格納する。
普通に [1] を押した時のメニュー番号 M が 1 なので、長押しは 10 を足して 11 としているが、ここは他と重複しなければ何でも良い。

ところで、Break コマンドは、それが記述されているループから強制脱出する。
Casio Basic コマンドリファレンス: Break 参照

2カ所ある C=9 の部分が、ループを抜けるまでに回る回数を示していて、長押しと判定されるための時間(=ループ回数)を指定している。この値を大きくすれば、長押しとして判定される時間が長くなり、小さくすればチョット長押しするだけで長押しとして判定される。

fx-5800P だと C=9 くらいが丁度良いと思って 9 にしてるが、9 である必要はない。fx-9860GII で使う場合は、処理速度が速いので 15 くらい丁度良いかも知れない。


キーコード 36 の [2] キーの長押し判定とメニュー番号指定(M=12とする)は、以下のようになる。

0→C
While Getkey=36
Isz C:C=9⇒Break
WhileEnd
C=9⇒12→M


キーコード 21 の [4] キーの長押し判定とメニュー番号指定(M=14とする)は、以下のようになる。

0→C
While Getkey=21
Isz C:C=9⇒Break
WhileEnd
C=9⇒14→M


このように、汎用性の高いコードになっている。

==========

さて、得られらたメニュー番号に応じて、分岐処理を行う青文字の部分は、上のメニュー選択部と対になる重要な骨組みだ。
If / Else / IfEnd を使っている。 詳しくは、Casio Basic コマンドリファレンス: If 文 を参照。

メニュー変数 M が 1, 2, 3, 11, 12, 14 の6通りで分岐処理を行っている。

If M=1
Then Locate 1,3,"HIT [1]"
Else If M=2
Then Locate 1,3,"HIT [2]"
Else If M=3
Then Locate 1,3,"HIT [3]"
Else If M=11
Then Locate 1,3,"LONG PUSH [1]"
Else If M=12
Then Locate 1,3,"LONG PUSH [2]"
Else If M=14
Then Locate 1,3,"LONG PUSH [4]"
IfEnd:IfEnd
IfEnd:IfEnd
IfEnd:IfEnd



この分岐処理を行うブロックで、If 文での分岐にキーコードを使わす、一旦代入したメニュー変数 M を使うには理由がある。
  • 理由1: 上のfx-5800P 用のコードを fx-9860GII へ移植する場合、赤文字部のメニュー選択部の一部を変更するだけで、青文字の分岐処理のブロックを変更する必要が無い。
  • 理由2: テンキー選択を多い場合や、テンキー以外のキー入力に対応して、分岐処理を増えた場合は、メニュー変数で整理する方がプログラムの可読性が増して、分かりやすくバグが入り込みにくい。
  • 理由3: 長押し検出による機能追加にも、対応するメニュー番号を使って拡張できる。

fx-9860GII / fx-CG20 への対応

なお、上のコードを fx-9860GII 用に変更する場合は、赤文字部を以下のように変更するだけば良い。

0→M
Do
Getkey→K
LpWhile K=0
K=72⇒1→M
K=62⇒2→M
K=52⇒3→M


0→C
While Getkey=72
Isz C:C=9⇒Break
WhileEnd
C=9⇒11→M

0→C
While Getkey=62
Isz C:C=9⇒ Break
WhileEnd
C=9⇒12→M

0→C
While Getkey=73
Isz C:C=9⇒Break
WhileEnd
C=9⇒14→M


変更箇所は、赤文字のキーコードのみにな、プログラムの他の部分を変更する必要がない。

==========

話を元に戻して...

青文字のブロックに続く後処理は、

If M
Then Locate 12,4,"<EXE>"◢
Locate 1,3,"    " (スペース7個)
Locate 12,4,"   " (スペース5個)
IfEnd


となっている。

[EXE] で元に戻るための使用方法の表示 <EXE> を行って、 命令で一旦停止。[EXE] で一旦停止を解除したら、全ての表示をスペースで上書き消去している。なお、これら後処理は、有効なメニュー番号が選択された時のみ実行する。
有効なメニュー番号は 0  以外の整数なので、M が 0 でない時のみ実行するために、If M / IfEnd の中に記述している。ここでも、最初に変数 M を 0 で初期化していることが活きてくる。

If [分岐条件] / IfEnd の書式で、[分岐条件] は、それが 0 以外なら If 内の処理(If と IfEnd の間の処理)へ分岐する。0 なら処理を行わず、次へ進む。従って、If M という記述が可能になる。

詳しくは、Casio Basic コマンドリファレンス: If 文 参照。





応援クリックをお願いします。励みになるので...

人気ブログランキングへ


FC2ブログランキングへ



   



keywords: CasioBasic、プログラミング入門プログラム関数電卓

リンク集 | ブログ内マップ



関連記事

テーマ : プログラム関数電卓
ジャンル : コンピュータ

コメントの投稿

非公開コメント

最新記事
最新コメント
カテゴリ
C# (3)
検索フォーム
Visitors
Online Counter
現在の閲覧者数:
プロフィール

やす (Krtyski)

Author:やす (Krtyski)
since Oct 30, 2013


プログラム関数電卓は、プログラムを作り・使ってナンボ!

実際に触って気づいたこと、自作プログラム、電卓プログラミングについて書いています

おもしろい・役に立つならクリックしてください。励みになります。

人気ブログランキングへ


FC2ブログランキングへ


写真: 「4駆で泥んこ遊び@オックスフォード郊外」

リンク
月別アーカイブ
Sitemap

全ての記事を表示する

RSSリンクの表示
最新トラックバック
ブロとも申請フォーム

この人とブロともになる

QRコード
QR