10) あたしも「あぁ、勘違い」 〜 Ver.1.10とハードキー
 光栄にも、おぢー製作所のおぢーさんに、「06)ホントは好きじゃないの」のタイトルを流用していただけました。
いやはや、逆の立場で同じ事を考えていたようで、私からは「あぁ、勘違い」をお届けします。

新しいバージョン Ver.1.10は、日本語版正式アナウンス前にフライングで連絡がくる、というトラブルの中リリースされました。IDEのバージョンを見ると、1.10.1となっていますので、リビジョンアップがなされているバージョンのようです。
1.09で問題のあったハードキーに関する不具合は修正されているようで、NS Basicアプリ上でハードキーを押すと、SetEventHandledの処理がされていなければ、きちんとそのアプリに切り替るようになりました。まずは、めでたしめでたしです。
また、今回、ハードキーのキーコードが変更になったようで、本文は、

   20. Runtime: Application key now sends 17 as keycode, not 6

つまり、キーコード6であった「ホーム」が17に変更になった、ということです。
例えば、SetEventHandled等を使って、連続的な処理を行っていた時、ホームを押したら、明示的にメニューに戻すには、例えば次のようにしますね。


   Dim strKey As String
   If getEventType()=nsbKeyOrButton Then
      strKey=GetKey()
      If strKey=&H6 Then
            Stop
      End If
      SetEventHandled
   End If

今回のバージョンでは、このキーコード6が「17」になりましたから、今までに作成したアプリを作り変えなければなりません。
また、単に変更6を17に変えるだけでなく、1.10以前のランタイムを使っている可能性もありますから、両方に対応したアプリにしないといけませんね。
ランタイムのバージョンは、SysInfo()という関数を使って調べることができ、バージョンを調べる引数は「0」ですので、SysInfo(0)=110が、 バージョン1.10の境界となります。
一番簡単なのは、1.10以前の環境の人には注意を促した方が良いわけで、ハンドブックの例が一番正しいのでしょう。

   If SysInfo(0)<105 then MsgBox "Please install latest version of the Runtime."
さて、Amiシリーズで、キーコード6を使ってプログラミングをしたモノと言えば、最近作ったAmi宝当LOTO!(以下、Ami宝)です。
調べてみると、ありました。

    Case &h6
        Stop

これを「17」に変えれば良いわけですね。
ん?でも待てよ、1.10のランタイムを入れて、最終回のPalmで一攫千金の予想をしたような・・・と言うことに気が付いて、実際の動作をしてみると、全然問題なく 動作してしまいます。

ランタイムのバージョンを疑ったのですが、しっかりと1.10で、問題はありませんでした。
問題は、上記のコードがAmi宝に実装されていた点です。特に値を保存する必要のないAmi宝でこれはいったい?と、思いついたのが前のバージョン。 そう、Ver.1.09の時の大きな不具合として「ハードキーが正常に動作せずホームに戻ってしまう」ということがありましたね。それ用の対策だったのです。
ハードキーがまともに動作するものは、そんなことをしなくてもアプリが切り替るわけですよね。ここに大きな勘違いがありました。
(思わず、おぢーさんの製作所付属研究所で見かけた「あぁ、勘違い」が思い浮かんで、このタイトルを使っちゃいました。)

Ami宝では、ドラムが回転し始める前の「祈りなさい」の画面でタップすると、FormのAfter部分にあるループからSysEventAvailable()を使って抜け出して、ドラム回転を行って、Afterを抜けます。Afterを抜けると、ループでトラップしたイベントが発生していますので、Event部分に1回だけ無視するような処理をしています。

(コードの概略です。実際のコードから抜粋してあります)

Sub Form1004_after()

  'ここが大麻を振るアニメーション処理の部分です。
    Do
        DrawBitmap 1011,51,97
        Delay 0.25
        DrawBitmap 1012,51,97
        Delay 0.25
        If SysEventAvailable()=1 Then
            Exit Do
        End If
    Loop
  '次にドラム回転ルーチンがあります。
   (ドラム回転ルーチン)

End Sub

Sub Form1004_events()

  'TrapEventはイベントトラップ用のグローバル変数です
  'このフォームが表示されるときに 0にしています。
  '1回だけ処理を無効にします。
  If TrapEvent=0 Then
      SetEventHandled
      TrapEvent=1
  End If

  'ただし、ホームを押したときは1回目でも有効になるようにSTOPしてホームに戻ります。
  If GetEventType()=nsbKeyOrButton Then
    dxStr=GetKey()
    If dxStr = &h6 Then
        Stop
    End If
  End If

End Sub

そう「1.09の次のバージョンでハードキー問題が無くなるだろうから、今回は、最低限としてホームだけ用意しておこう!」という意図で作ったものでした。
なので、1.10のランタイムを入れたものは SetEventHandledで無効になった1回目をのぞく2回目で、各アプリが立ちあがるようになりました。
ということは、ルーチンの中でムダにキーコード6をチェックしているようですが、ホームが17になって、他のキーが6になった訳ではないので、問題はないと思います。

Ami宝は、終了時に値を保存しているわけではないので、問題がなかったわけですが、では、AmiSolはどうしているのでしょう?
コードを見てみると、Terminationコード内に保存ルーチンが置いてあるだけです。
・・・・・ん!はた、と気が付きました。ハードキーが押されたら、Terminationが処理されるじゃん!と言うことでした。
あったりまえのこのことですが、このように勘違いをしていたようで、全部のアプリを6と17チェックルーチンを置かなければいけないっ!と思っていた自分が恥ずかしいです。

Terminationは、作成したアプリケーションが終了する時に発生するイベントです。(断末魔ですね)
アプリケーションが終了するのは、
  • ハードキーで他のアプリに切り替る
  • Stopを使った
  • ホットシンクした
これらの場合ですが、どの場合でも必ずTermination処理をします。AmiSolは、毎回データベースに保存しているわけではなく、Terminationで保存処理をしています。
比較的書き込みが早いのと、データが小さいので、あまり問題はありませんが、大きなデータを保存する場合は、おぢーさんのお言葉を参考にされると良いでしょう(途中リンクすみません>おぢーさん)
そんなことで、まとめです。
  • 意図的にホームのハードキーをチェックする時には注意
  • SetEventHandledを使う時も注意してみよう
  • Terminationを活用する
  • できるだけ、新しいランタイムを使わせる
と言ったところでしょうか。
今回はとんだ勘違いから、Terminationの存在を思い出し、ハードキー関連の整理がついたような気がしますので、怪我の功名、ってやつでしょう。
NS Basicのバージョンも1.10になり、バグがだんだん無くなってきて使いやすくなってきました。値段的にはそれほど高価なソフトではないのに、サポートが充実していて、とても感謝しております。とはいえ、値が変わったりするような変更はできるだけ止めてもらいたいトコロです。