他のファイルを操作
エディターやプレイヤー、ビューワー等を作成するときに既存のファイルを読み込んだり、
逆に作成した文書、画像等をハードディスクに書き込んだりする時にファイル操作命令を使用します。
まずはbcopy命令から。bcopy命令は既存のファイルをコピーします。
書式は「bcopy "コピー元の名前","コピー先の名前"」です。
bcopy "c:\\windows\\calc.exe","c:\\dentaku.exe" ; 電卓をC:\にコピーする
bcopy命令はPACKFILE内(実行ファイル)のファイルもコピーすることができます。
これにより使用したい時にハードディスクに書き出したり、インストーラみたいなこともできます。
既存のファイルのデータをHSPに読み込んで使用するにはbload命令を使います。
書式は「bload "ロードするファイル名",変数,ロードサイズ,オフセット」です。
p1の変数にはロードするファイルサイズ以上の大きさを確保しておいてください(オフセット0の場合)。
p1をsdim命令でメモリ確保しなかったり、確保サイズがファイルより小さかった場合、
p1で指定した変数やその他の変数の中身が壊れてしまいます。
p2のロードサイズは通常省略しても問題ありません。
p3のオフセットとは、ファイルの先頭から何バイトの位置からロードするかを指定します。
これによりファイルの一部分だけを読み込むことができます。
sdim buf, 32000
bload "c:\\windows\\win.ini", buf
mesbox buf, 640, 480, 0
stop
上記のスクリプトだとサイズを32000バイト確保していますが、
内容がそんなに大きくないのにメモリを大きく確保するのはもったいないですよね。
こんな時に役立つのはexist命令で、ファイルをロードする前にサイズを調べることができます。
書式は「exist "調べたいファイル名"」です。
サイズが取得できたら、システム変数strsizeにバイト単位のサイズが代入されます。
取得できなかった場合には0ではなく−1が入るので、ファイルの有無を調べるときにも役立ちます。
exist "c:\\windows\\win.ini"
mes "sdimで" + strsize + "バイト確保すれば大丈夫ですネ"
stop
sdim file, 128
buf = ""
pos 0, 0 : input file, 575, 25, 128
pos 575, 0 : button "open", *open
pos 0, 25 : mesbox buf, 640, 455, 0
stop
*open
exist file
if strsize ! -1 {
sdim buf, strsize
bload file, buf
} else : buf = "ファイルがありません"
objprm 2, buf ; オブジェクトを更新する
stop
今度は、ハードディスクにファイルとして変数の中身を書き出すbsave命令を説明します。
書式は「bsave "セーブするファイル名",変数,セーブサイズ,オフセット」です。
p1で指定した変数の内容をp2のサイズ分、指定したファイルのp3分ずれた位置から書き込みます。
セーブサイズを省略すると、その変数が確保しているサイズ(初期設定で64バイト)になります。
sdim buf, 256
objsize 640, 25
button "save", *save
mesbox buf, 640, 455, 5
stop
*save
bsave "c:\\hspbc_sample.txt",buf ; 「c:\hspbc_sample.txt」に保存
stop
上記の例を試すと分かると思いますが、セーブサイズを省略しているので、
内容にかかわらず256バイトのファイルが作成されていると思います。
無駄のないように中身のサイズだけ保存するには、第17章で出てきたstrlen命令を使いましょう。
sdim buf, 256
objsize 640, 25
button "save", *save
mesbox buf, 640, 455, 5
stop
*save
strlen len, buf ; bufのサイズを測る
bsave "c:\\hspbc_sample.txt",buf,len ; 「c:\hspbc_sample.txt」にlenバイト保存
stop
CD−ROM等や読取専用のファイルに対してセーブしようとするとエラーが出て強制終了してしまいます。
こういった場合にはHSPで起こるエラーを一時的に無視させることで回避できます。
エラーを無視する命令はskiperr命令で、書式は「skiperr 無視スイッチ」。
無視スイッチを1にすると、通常エラーが出て終了するような状況でも処理を続行させます。
0にすると通常のエラーが出てその時点で終了するモードに戻ります。
「元々エラーが出てもいけるように『skiperr 1』にしとけばいいのでは?」と思うかもしれませんが、
初めから最後まで『skiperr 1』としていると、
HSP以外のメモリ領域に書き込んでしまったりと致命的な問題が起こってしまうかもしれないので、
やむを得ずスキップするところ以外はスイッチを0に戻すように心掛けましょう。
エラースキップ中にエラーが発生するとシステム変数errにエラー番号が入りますので、
通常は「エラー発生すれば通知用に番号を表示してソフトは終了する」ようにすべきです。
次に「ファイルロード・セーブのお供と言えばコレ!」とまで言えるdialog命令に入ります。
先程やってきたbload、bsave命令はロードするファイル・セーブするファイルが決まっていましたね?
ユーザーが開きたいファイル・指定した位置と名前で保存をさせるにはどうしたらよいでしょう。
input命令とbutton命令を使ってもできますけど、dialog命令を使った方がすっきりします。
書式は「dialog "メッセージ",タイプ,"オプション"」です。
メッセージとオプションは指定したタイプにより変わります。
タイプ0〜3は、通常の「はい・いいえ」「OK」のあるボックスで、
メッセージに内容文をオプションにタイトルバーに表示したい文字列を指定します。
ダイアログのボタンを押すとシステム変数「stat」にどのボタンが押されたかというメッセージが入ります。
「OK」は1、「はい」は6、「いいえ」は7がstatに代入されます。
dialog "ここに内容文を書く\n複数行もOK!", 2, "タイトルバーはココです"
if stat = 6 : mes "「はい」が押されました"
if stat = 7 : mes "「いいえ」が押されました"
stop
タイプ16〜17はファイル選択ダイアログで、16はオープン、17はセーブダイアログとなります。
メッセージには開きたい拡張子を指定、オプションにはその拡張子の補助的な説明を指定します。
ファイルが正常に選択されるとstatに1が、キャンセルまたはエラーで0が代入されます。
勘違いされる方が多いですがこのダイアログだけでは実際に開いたり、保存したりすることができません。
dialog "txt", 16, "テキスト文書" ; オープンダイアログ
if stat = 1 : mes "正常に選択されました"
if stat = 0 : mes "キャンセルまたはエラーが生じました"
stop
また正常に終了すると、システム変数refstrに選択したファイル名(フォルダ含む)が代入されます。
このdialog命令とbload・bsave命令を使って実際にロード・セーブをしてみましょう。
sdim buf, 32000
objsize 320, 25
pos 0, 0 : button "load", *load
pos 320, 0 : button "save", *save
mesbox buf, 640, 455, 5
stop
*load
dialog "txt", 16, "テキストファイル"
if stat=0 : stop ; エラー・キャンセルでストップ
bload refstr, buf ; refstrには選択したファイル名が入っている
objprm 2, buf
stop
*save
dialog "txt", 17, "テキストファイル"
if stat = 0 : stop
strlen size, buf ; bufのサイズを測る
bsave refstr, buf, size
stop
タイプ32〜33はカラー選択ダイアログです。メッセージとオプション部分は使用しません。
32はペイントで言う、「色の編集」ダイアログが出てきて、固定色の中から選択ができます。
33は「色の作成」を押した時に出現する約1677万色の中から自由に選択ができます。
選択をキャンセルするとstatに0が代入され、無事選択が終わるとstatに1が代入されます。
そして、システム変数rvalに選択色の赤輝度、gvalに緑輝度、bvalに青輝度が代入されます。
10章で出てきたcolor命令で使うものと同じ形式(赤、緑、青要素に分かれている)なので、
そのままcolor命令に代入することもできます。
dialog "", 33, ""
if stat = 0 : stop
color rval, gval, bval ; 選択色が入る
boxf ; 全体を塗りつぶす
stop
続いてファイルを削除するdelete命令に入りマス。
「delete "削除したいファイル"」で削除したいファイルが削除されます。
指定したファイルがない場合、エラーとなってしまいます。
あるかないか分からない場合はexist命令で前もって調べるとよいと思います。
sdim file, 128
input file, 300, 25, 128
button "削除", *del
stop
*del
exist file ; 指定したファイルがあるか調べる
if strsize = -1 : dialog "存在しません", 0, "エラー" : stop ; 存在しない場合ストップ
dialog "本当に削除してよろしいですか?", 2, "確認" ; 確認メッセージを出す
if stat = 7 : stop ; 「いいえ」を押すとストップ
delete file ; 指定ファイルを削除
dialog "削除しました",0,"結果" ; 終了を知らせるダイアログ
stop
尚、delete命令では、フォルダ(ディレクトリ)の削除はできません。
逆のフォルダを作成することはmkdir命令で出きます。
作成できるのは既に存在するフォルダに1階層分だけの空っぽのフォルダです。
mkdir curdir + "\\hspbc_test" ; カレントディレクトリに「hspbc_test」と言う名前で作成
stop
今回はたくさん命令が出てきましたね。
bload命令やbsave命令なんてゲームでもハイスコアの保存等によく利用される命令です。
使用頻度は高いと思いますので覚えておいて損はありません。
次回はpicload命令で読み込んだ画像を処理する「画像処理」についてやって行きます。