NS Basic/Palmに関する覚え書き(ややVB経験者寄り)。
触ってて気付いたこととかをメモ代わりに書き殴ってます。いや、そんだけなんだけど。
★初期設定に従う必要なし。
NSをインストールした直後にはデフォルトの場合、C:\NSBasic配下に、
C:\NSBasic\Project
C:\NSBasic\BitMap
C:\NSBasic\Downloadの3ディレクトリが作られ、各ファイルは役割に応じて振り分けられるようになってます。
が。
めんどくせー。いきなりかい(笑)。
作り立ての頃はこれでもまだいいんだと思いますが、慣れてきてファイルが増えてくるようになると「あれ?このファイルはどのプロジェクトに使ってる?」と訳わからなくなってくるのが目に見えてますので、とっととこのやり方とは決別しました。
とは言え、やってることは単純で、C:\NSBasicの下にさらに、
C:\NSBasic\mcount
てな感じでディレクトリ作って、コードも何もかも全部放り込みました(笑)。エクスプローラから直接ファイルを移動させるとprjの整合性が崩れますので、NSから名前をつけて保存で該当ディレクトリに保存するか、後で直接prjを編集(後述)するのを推奨。
ただし、コンパイル後のprcだけはC:\NSBasic\Downloadに作るようにしています(ですのでNSのベースディレクトリ設定は変えてない)。分けても問題ないんだろうけど、こうすると配布するべきファイルとかの区別ができるんで。
★配列の細かーい差異。
VBと比べた場合、NSにはこの機能がありません。
- Redimがない。
- 要素は正の整数のみ。
- Option Base 0がない。
つまりがっちがちの静的配列しか作れません(笑)。まぁよく考えたら当たり前かも。PalmOS上でそこまでワガママなメモリの使い方させる事自体が却下なんだろーな。柔軟に動的に扱おうと思ったら、データベースとかをうまく使うしかないでしょーね。設計大事になるよ。
まぁRedimはいいんですけど・・・個人的に要素に0が使えないのがすっげー気持ち悪いー。
★式が渡せな〜い
DBに新しいレコードを追加する場合。
Dim NowDB as database
Dim tmp_Ret as integertmp_Ret = DBInsert(NowDB,1,333,555)
これアウトです。なんでもDB関係の関数に渡すときには必ず変数に格納した形で渡してやらなきゃいけないらしい。しょうがないなぁ。これならどうだ。
Dim NowDB as Database
Dim tmp_Ret as integer
Dim iii as integer
DIm jjj as integer
(中略)
iii = 1
jjj = 111
tmp_Ret = DBInsert(NowDB,iii,jjj*3,jjj*5)アウト。なんでじゃー(笑)。
で、更に見てみたところ、DB関係の関数では式が渡せないらしいと。ということは・・・正解はこうか?
Dim NowDB as Database
Dim tmp_Ret as integer
Dim iii as integer
Dim jjj as integer
Dim kkk as integer
(中略)
iii = 1
jjj = 333
kkk = 555
tmp_Ret = DBInsert(NowDB,iii,jjj,kkk)だっさー(笑)。このおかげで初期化関係のコーディングとかがかなりしょっぱくなります。まぁわかるといえばわかるんだけどね。おそらくランタイムに渡した時点で、メモリの中のタイプと実数を確定させておきたい、という意図でも働いたんだと思いますが。
VB触ってる人がハマる可能性80%。気を付けましょう。
★文字列〜。
あとこれ結構迷ったのがこれ。VBにあたる文字連結式「&」は、NSの場合、「+」で表現するんですけど、例えば。
Dim iii as integer
iii = 3
Msgbox "NowCount=" + iii
これもエラーになります。正解はこう。
Msgbox "NowCount=" + Str(iii)
予めすべて文字列にしておかないと、"+"演算子を評価してくれずにエラーになっちゃう。この辺も式の評価方法に若干の差が生じてます。VBとNS。普段VBの自動変換に慣れ切っちゃってるとこうゆうところでつまづいちゃう典型。
★リソースいじったれ
NSの大きな特徴のひとつに「リソースIDを意識しなくていい」というがあります。特にGCCなどと比べてみるとわかるのですが、画面上にぺたっとオブジェクト貼り付けてしまえば、勝手にIDが振られ、イベントの記述欄が用意されと、ふつーの操作をする限りでは「リソースID?なにそれ?」的なコーディング作業ができてしまいます(いいか悪いかの議論は別ね)。
ま、普段はいいんですよ。ハナクソでもほじりつつコード書き書きしてればいい。ただ、この仕様がかえって障壁になるパターンもある。
というのもこんな場合。予めビットマップを10枚用意しておいて、条件によって違う絵を張りたいと。
その時にわざわざCase Selectなんか使ってられっかと。10枚ならともかく1000枚だったらどーすんだ(つーか1000枚も使うようなプログラムって何だ(笑))。
そんなんだったらリソースIDと変数組み合わせて
For iii = 1 to 10
DrawBitmap 2000+iii, 50,10
Nextとでもやった方がラクに決まってます(Thanx to LazyTrick)。
でも、このためにはリソースIDを連続して振らなきゃいけません。でも現在のNSではアプリ上からIDを変更することはできません。でも意図的にID振れなきゃ上のテク使えません。じゃあどうするか。
無理矢理変えちまえ。
つーことでVBプログラマにはお馴染み「プロジェクトファイルをエディタ編集」強制発動(笑)。
NSのプロジェクトファイルもVBのそれと同様に中身はただのテキストファイルです。とっととエディタ開きましょう(NSを終了させるのを忘れずに。両方で開いたらまずブッ壊れます(笑))。中身見てみると、BMPの設定は、
"bmpfile"
1
"Bmpfile1041"
1041
"C:\NSBasic\mcount\num0.bmp"こんな感じ。まんまですね。この数字4ケタがリソースIDであるのはほぼ確実なので、
"bmpfile"
1
"Bmpfile2000"
2000
"C:\NSBasic\mcount\num0.bmp"必要分は勝手に変えて上書き保存してしまいませう。その後再びNS立ち上げれば設定したリソースIDが反映されているはずです。BMPに限らず、おそらくほとんどのリソースIDはエディタ上で変えられる、と思います。同一フォームの中で条件によって表示オブジェクト出し隠ししたい時には有効ですね。
★服の中身はエヘヘヘ(←をい)。
ついでだからPRJファイルの中身をもうちっと見てみます。
モジュール内のオブジェクト定義、イベントソース、外部モジュールファイルやビットマップの範囲などがずらずらと並んでるんですが・・・・・・。
まんまじゃねぇか。
中身見て「もちっとひねれよ」と思わずツッコミを入れたのは私だけではないはずだ。NSのコードウィンドウ閉じる度にウィンドウがいちいちリロードする理由が垣間見れたぞ。
NS上で見るコード上の差異も「"」を「~」に置き換えてる位。書く要素を「"」で囲って識別し、上から下までつなげてるだけ。マジ見たまんま。
でもこれって、逆に融通利くという意味では嬉しいことです。ある程度慣れてきたら、オブジェクトの定義や配置だけ先にNSで決めて、コーディングは使い慣れたエディタで。終わったら再度NS立ち上げてコンパイル・・・こうゆう方法論が非常に有効だと思うよん(GCCは言うに及ばず、CodeWarrier使いの人でもこうゆう人多いのでは?)。
どーせNSのエディタなんて使い物になんないし(禁句)。
★グループIDに気を付けろ。
これ、冷静になって考えてみればわかることなんだけど、私自身がこれでハマったので整理を兼ねて(笑)。
セレクトボタンやオプションスイッチなど、複数項目からひとつだけを選ばせる時に使うGroup IDというプロパティがありますよね?
これがあるおかげで、セレクトボタンが4つ(choP1〜P4)があるとしても、
・choP2をスタイラスでタップ
・choP2.StatusがONに更新。
・他の3つ(choP1、choP3、choP4)のStatusがOFFに更新
・choP2内のイベントを処理
・画面をリロード
(注:順番は推測です(笑))てな処理を自動的にやってくれる。ラク〜。となるんですが。
ところがここから一歩踏み込んでやろうとした途端。はまりました。
始めからタップのみを前提として操作するのでしたら、これで必要十分なんですけど、私、これをハードウェアキーで連動させてみたかったんですな。ですのでキーバインド拾って、外部Function呼んで、ボタンのステータスを変えて・・・とやってみたんですけど。
ハードキー押してもボタンが変化しない。イベントが走らない。
どうやらグループIDの機能が働く、及びオブジェクトに与えられたイベントが駆動するのはあくまで「タップした時」に限られるようです。
これに気付かなかったために悶絶すること2時間(笑)。
結局最後は↓、
'lastSelectCase Choise.
select case NextDisp
case 1
ChoP1.status = nsbOn
Chop2.status = nsbOff
Chop3.status = nsbOff
Chop4.status = nsbOff
case 2
Chop1.status = nsbOff
ChoP2.status = nsbOn
Chop3.status = nsbOff
Chop4.status = nsbOff
case 3
Chop1.status = nsbOff
Chop2.status = nsbOff
ChoP3.status = nsbOn
Chop4.status = nsbOff
case 4
Chop1.status = nsbOff
Chop2.status = nsbOff
Chop3.status = nsbOff
ChoP4.status = nsbOn
End Select
Chop1.Redraw
Chop2.Redraw
Chop3.Redraw
Chop4.Redrawえぇ、書きましたとも。ダラダラダラダラと。もちろんイベントに入れてあった動作も(おかげでやっぱ遅いなぁ。実用考えたら最終的にはボツになる可能性の方が高いと思う、これ)
イベントの概念と、そのトリガーの成立条件てのが一通り整理できていれば起こりにくいミスなんですけどね。気を付けておいた方がいいよ、という意味で書いておきます。