初心者が陥りやすい罠 |
00.03.05〜 |
バグも仕様も含めて、初心者が勘違いしやすいこと、困ってしまうことを解説しています。 改善予定は、私が改善するわけではないので、誤っている可能性も変更される可能性もあります。 HSP対応バージョン:2.5〜3.21(2.6〜2.61については確認していない記述も残っています) マニュアルの「HSP2よくある質問Q&A (hsp2faq.htm)」(HSP3ではdoclib¥faq.htm)もお読みください。マニュアルの目次は、HSPをインストールしたフォルダのIndex.htmをダブルクリックすると開けます。 また、標準エディタで命令名にカーソルを合わせてF1キーを押すと、その命令の説明が表示されます。 |
11.10.14 HSP3に関する記述を追加 04.12.18 getkeyのキーコードを更新。モジュールの変数がおかしいを追加 04.06.26 4の倍数問題について解説を追加した 03.09.27 sndloadの制限、ウィンドウが小さくできないを追加。Ver. 2.6の情報をいくつか追加 01.02.21 ウィンドウアクティブを追加 |
目次 | |||||
|
【一般・その他】 | ||
【リンク】 | マニュアルに載っている命令なのに、「文法が間違っています」というエラーが出る | |
【リンク】 | スクリプトエディタで「テキストの容量がオーバーしました」と表示される | |
【リンク】 | HSP拡張プラグイン(DLL)の使い方 | |
【リンク】 | スクリプトを実行するとWindowsのエラーメッセージが出て強制終了する | |
【リンク】 | hspda.dllのsortvalで、正しくソートされない場合がある | |
【実行制御】 | ||
【リンク】 | 「if a>b+c:……」などが正しく動かない | |
【リンク】 | 「repeat ,1」や「repeat -1,1」が1回しか実行されない | |
【リンク】 | cmdlineで受け取る起動オプションが63バイトで切られてしまう | |
【リンク】 | モジュールの変数がおかしい | |
【ウィンドウ】 | ||
【リンク】 | EXEファイルを作ったとき、「起動時にメインウィンドウを非表示にする」と、ウィンドウ0が表示されなくなってしまう | |
【リンク】 | メニューやツールバーを表示したい | |
【リンク】 | 「gsel id,1」を実行してもウィンドウがアクティブにならない | |
【リンク】 | ウィンドウが小さくできない | |
【文字列】 | ||
【リンク】 | 文字列を受け取る命令を実行したのに、変数をmes命令で調べると数が表示される | |
【リンク】 | BASICでの文字列の大小比較や、Cのstrcmp関数に相当する処理をしたい | |
【リンク】 | {}を用いた複数行文字列の代入で、「:」「;」等を含んでいると、正しく代入されない | |
【リンク】 | instrで「¥」を検索すると、特定の全角文字を誤認してしまう | |
【リンク】 | 「if (s=="abc")|(s=="def")」などがエラーになる | |
【リンク】 | モジュールの変数がおかしい | |
【グラフィック】 | ||
【リンク】 | 画像ファイルの画像サイズを求めたい | |
【リンク】 | line命令が1ドット欠ける | |
【リンク】 | 画像が正しく表示されない | |
【ファイル・フォルダ】 | ||
【リンク】 | パスを例えば「"C:¥test"」などと書くとエラーになる | |
【リンク】 | フォルダ削除命令がない | |
【リンク】 | フォルダが存在するか否かを調べる命令がない | |
【リンク】 | 短いファイル名(MS-DOSファイル名)を長いファイル名に変換する命令がない | |
【リンク】 | マニュアルに、ファイル読み込みダイアログ(dialog ,16)で、複数の拡張子を指定する方法が書かれていない | |
【マウス・キー】 | ||
【リンク】 | mousex,mouseyが意図通りの値を返してくれない | |
【リンク】 | getkeyのキーコード | |
【リンク】 | hspext.dllのaplkeyで「Ctrl+C」や「Alt+A」などが入力できない | |
【オブジェクト】 | ||
【リンク】 | ボタンのデザインを変えたい | |
【リンク】 | コンボボックスで初期値を設定しようとして、「a=2: combox a, 96, "data0¥n data1¥n data2¥n"」と書いた場合、aの内容がおかしい | |
【サウンド・動画】 | ||
【リンク】 | sndload+sndがうまく行かない場合がある |
メニューやツールバーを表示したい | |
回避方法 | Exforceのmmset命令等やtbset命令等、標準のnewmenu等を使う |
改善予定 | newmenuは3.2以降 |
解説 |
3.1までは、標準ではできませんでした(当然、自分で描いて自分で制御することはできます)。 hsp2.55以降では、Exforce3.08のツールバーにpackfileの画像が使えません。 |
ボタンのデザインを変えたい | |
回避方法 | Exforceのdrawbtn、llmodのbtnimg、標準のobjimageを使う |
改善予定 | btnimgは2.55以降、objimageは3.2以降 |
解説 |
2.55までは、標準ではできませんでした(当然、自分で描いて自分で制御することはできます)。 Exforceのimgbtn命令も参照してください。 |
マニュアルに載っている命令なのに、「文法が間違っています」というエラーが出る | |
回避方法 | 解説参照 |
改善予定 | 不明 |
解説 |
マニュアルの各命令の説明に「(拡張命令:××××.dllが必要です)」と書かれている命令は、標準添付の拡張プラグインを使用します。拡張プラグインの使い方を参照してください。 Ver. 2.55以降では、llmod.as(HSP3ではllmod3/llmod3.hsp)等を#includeしないと使えない命令もあります。命令の説明をよく読んでください。 また、HSP2では「初心者のためのHSP入門」の「作業ディレクトリを作ろう」は無視し、hsed2.exeは、必ずインストールしたフォルダにあるものを使ってください。そうしないと、ワンキーヘルプ・標準マクロ命令・拡張プラグイン命令が使えません。 |
EXEファイルを作ったとき、「起動時にメインウィンドウを非表示にする」と、ウィンドウ0が表示されなくなってしまう | |
回避方法 | gsel 0,1 |
改善予定 | 3.0から直っています |
解説 | ウィンドウ2以降は「gsel 2,-1」を実行した後でも「screen 2,……」を実行すれば表示されますが、ウィンドウ0だけは例外のようです。 |
文字列を受け取る命令を実行したのに、変数をmes命令で調べると数が表示される | |
回避方法 | 事前に何らかの代入(例えば「s=""」)またはsdim命令またはstr命令を実行しておく |
改善予定 | 3.0から直っています |
解説 |
受け取り用に指定した変数が数値変数と解釈されているようです。 HSP3ではこの問題は直った代わりに、プラグイン命令で文字列を受け取る変数とし て未定義・未代入の変数を指定するとエラーが起きたり、数値変数になるようになってしまいました。これは、プラグインのPVAL構造体の書き換えによる型変換が無効になってしまったためです。 |
「if (s=="abc")|(s=="def")」などがエラーになる | |
回避方法 | 「if s=="abc" | (s=="def"+0)」のように書く |
改善予定 | Ver. 2.55では直っています |
解説 |
かっこ内の最後の項が文字列だとエラーになります。そこで、閉じかっこの前に「+0」(ゼロ)などと書いて、最後の項を数値にしてやれば回避できます。 また、かっこを外せるところでは、かっこを外すだけでもOKです。 |
画像ファイルの画像サイズを求めたい | |
回避方法 | buffer 2: picload "ファイル名": width=winx: height=winy |
改善予定 | なし |
解説 | widthに横幅、heightに高さが入ります。 |
「if a>b+c:……」などが正しく動かない | |
回避方法 | 「if a>(b+c)」のように書く |
改善予定 | 3.0から直っています |
解説 |
演算子に優先順位がなく、すべての演算は左から順に行なわれるため、「a>b+c」は「(a>b)+c」と解釈されます。 ちなみに、「a>b」は、真ならば1、偽ならば0になります。また、演算結果をifで判定すると、0以外なら真、0ならば偽と判定されます。 「a>0&b>0」も同様に「(a>0&b)>0」と解釈されます。 |
スクリプトを実行するとWindowsのエラーメッセージが出て強制終了する | |
回避方法 | 解説参照 |
改善予定 | 原因による |
解説 |
さまざまな原因が考えられますので、まずどの命令で強制終了しているかを調べる
ことが必要です。
それでも解決しない場合は、掲示板またはHSP掲示板で。
ただし、質問しても解決しない場合もあります。 |
line命令が1ドット欠ける | |
回避方法 | 状況に応じてp1,p2の一方を+1または-1する、またはpsetで補う |
改善予定 | なし |
解説 |
おにたまさん(HSPの作者)自身が「仕様」と書いたことがあるので、改善予定はないと思われます。 既に長くこのままであり、改善すると互換性の問題が大きいのかもしれません。 どうしても気に入らない方は、拙作anthspex.dllのaline命令をお使いください。 互換性を切り捨てたHSP3でも直りませんでした。 |
画像が正しく表示されない | |
回避方法 | 水平方向のウィンドウサイズを4の倍数にする |
改善予定 | 4の倍数問題はVer. 2.61でほぼ改善されたようです。 |
解説 |
以前、「画像サイズ」が問題であるかのように書いていましたが、Ver. 2.5以降では寧ろウィンドウサイズが4の倍数+1または+2の場合が問題だったようです。ただし、画像サイズによってウィンドウサイズを決定している場合は、画像サイズも問題になります。 HSP2.6までで画像サイズを変えたくない場合は、文字変数fileにファイルパスが入っているとすると、以下のようにするとうまく行きます(コピー先ウィンドウの横幅が4の倍数の場合)。 picload file: w=winx: h=winy if w¥4: w2=w+3/4*4: buffer 2,w2,h: picload file,1やはりHSP2.6までで、パレットモードでbmpsaveする場合は、次のようにすると4の倍数でない横幅のbmpファイルを作成できます。 bmpsave file if w!=w2: bsave file,w,4,18また、プログレッシブJPEGには対応していないそうです。対応プラグインがいくつかありますから、本家HSPの「HSP機能拡張ソフト紹介」やベクターの「Softライブラリから探す」→「Windows」→「プログラミング」→「Hot Soup Processor」から探しましょう。 HSP2.6のgcopyでは、フルカラーモードで、gmodeが1以上、コピー元またはコピー先ウィンドウサイズが4の倍数+1または+2の場合に乱れます。また、jpgファイルやパレットモード時のmagファイルの横幅がpicloadがうまく行きません。 HSP2.61でも、画像ファイルによっては、横幅の判定を間違う場合があるようです(そのせいでgcopyにごみが出る)。 |
パスを例えば「"C:¥test"」などと書くとエラーになる | |
回避方法 | 「"C:¥¥test"」のように、「¥」は必ず2つ書く |
改善予定 | なし |
解説 |
文字定数(ダブルクォート(")で囲んだ文字列)において、「¥n」で改行、「¥"」でダブルクォートなどが書き表せるようになっています。その副作用で、「¥」そのものは「¥¥」と書かなければなりません。 ときどき勘違いする人がいるようですが、「s="C:¥¥test"」を実行すると、sの内容は「C:¥test」になります。「C:¥¥test」にはならない点にご注意ください。 |
instrで「¥」を検索すると、特定の全角文字を誤認してしまう | |
回避方法 | 解説参照 |
改善予定 | Ver. 2.6では直っています |
解説 |
「¥」の文字コードが一部の日本語コードの下位バイトと同じであるために起きます。 「¥」を検索する処理のほとんどはパスのハンドリングでしょうから、Exforce.dllのextract命令を使えば、パスについてのたいていの処理はできます(Ver. 2.6ではgetpath命令でもほぼ同様のことができますが、細かい点でやや劣ります)。 どうしても、検索する必要がある場合は、拙作anthspex.dllのfindl命令またはinstrj命令をお使いください。 |
フォルダ削除命令がない | |
回避方法 | exec "command.com /c rmdir フォルダ名",3(空のフォルダを削除する) |
改善予定 | なし |
解説 |
rmdirのかわりにdeltreeを使えば、空でないフォルダも削除できます。 なお、「rmdir フォルダ名」のところには、DOSコマンドなら何でも書けます。 今(2011年)はなくなってしまったHSPユーザーズグループのFAQによると、Windows NT4.0/2000(XPも同じ)では「cmd /c rd フォルダ名」とします。「rdに /s /q オプションをつけると、それ以下のファイルとフォルダを無理矢理消し去ることが可能」だそうです。なお、「rd」は「rmdir」の短縮形です。さらに言えば「rm」は「remove」の略と思われます。 拙作anthspex.dllのdeldir命令とtreedoモジュールを使う方法もあります。 |
フォルダが存在するか否かを調べる命令がない | |
回避方法 | 「dirlist 文字変数名,フォルダ名,5」でstatが0でなければ存在する |
改善予定 | なし |
解説 |
「dirlist 文字変数名,パス」でファイルまたはフォルダが存在するか否かを知ることができます。 hspext.dllを使えば、fxaget命令一発で、ある名前のファイルまたはフォルダが存在するか否か、存在するならどちらかを知ることができます。 |
mousex,mouseyが意図通りの値を返してくれない | |
回避方法 | 解説参照 |
改善予定 | (たぶん)なし |
解説 | mousex,mouseyの代替ルーチンのサンプル(mouse.as)がサンプルスクリプトのページにあります。 |
HSP拡張プラグイン(DLL)の使い方 | |
解説 |
hspext.dllを例にします。 HSPをインストールしたフォルダを「hsp:¥」で表しています。
プラグインの拡張子は .dllでなく .hpiの場合があります。 インクルードファイル(hspext.asに相当するファイル)は各プラグインに同梱されているはずです。 なお、エクスプローラまたはマイコンピュータの「表示」メニュー→「オプション」→「表示」で「すべてのファイルを表示」(または「ツール」メニュー→「フォルダ オプション」→「表示」で「すべてのファイルとフォルダを表示」)を選択しておかないと、DLLファイルは表示されません。ついでに「登録されているファイルの拡張子は表示しない」のチェックも外しておくといいでしょう。 |
{}を用いた複数行文字列の代入で、「:」「;」等を含んでいると、正しく代入されない | |
回避方法 | 「文字変数+="……¥n……"」を使う |
改善予定 | 3.0から直っています |
解説 |
通常の文字列の代入には、このバグはありません。 「文字変数+="……"」という書式は、HSPの文字列の32Kバイト制限を突破できる書式でもあり("……"は32Kバイト以下)、これを使うのがよいでしょう(strmidはさらに代入元も32Kバイト以上でよい)。 以下のような回避方法もあります。 s={"abc def"}+";"+{"ghi jkl"}+":"+{"mno pqr"} |
getkeyのキーコード | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
解説 |
|
cmdlineで受け取る起動オプションが63バイトで切られてしまう | |
回避方法 | スクリプトエディタ以外のコンパイラを使う |
改善予定 | Ver. 2.55では直っています |
解説 |
これは、スクリプトエディタのみの制限なので、テストランの間は63バイト以下に納めるようにするか、拙作コンパイラ等を使えばいいでしょう。 ちなみに、EXEファイルでは、「515−EXEファイルのパス長」までOKです。 |
「repeat ,1」や「repeat -1,1」が1回しか実行されない | |
改善予定 | Ver. 2.55では直っています |
回避方法 | 例えば「i=1: repeat: ……」のように書き、cntのかわりに i を使う |
解説 |
スクリプトエディタで「テキストの容量がオーバーしました」と表示される | |
回避方法 | #includeかまたは外部エディタを使う |
改善予定 | 不明 |
解説 |
|
hspext.dllのaplkeyで「Ctrl+C」や「Alt+A」などが入力できない | |
回避方法 | Exforceのvkey命令を併用する |
改善予定 | 不明 |
解説 |
aplkeyの第2パラメータは効かない場合があるようです。 anthspex.dllのsetkey命令や、Ver2.55以降ではkeybd_event命令もExforceのvkey命令と同じです。 |
hspda.dllのsortvalで、正しくソートされない場合がある | |
回避方法 | 解説参照 |
改善予定 | Ver.2.55では直っています |
解説 |
自力ソートについては別ページ参照。 |
「gsel id,1」を実行してもウィンドウがアクティブにならない | |
回避方法 | 回避するためのモジュールがサンプルスクリプトのコーナーにあります。 |
改善予定 | 不明 |
解説 |
Windows98以降でマイクロソフトが仕様変更した(私に言わせればバグを入れた)ために起きます。 |
コンボボックスで初期値を設定しようとして、 | |
回避方法 |
combox命令の後に |
改善予定 | comboxについてはVer. 2.55からlistboxは3.0から直っています |
解説 |
comboxを実行した時点で、aには-1が代入されます。したがって、combox命令の後で、もう一度、aに代入する必要があります(複雑すぎてここには書ききれませんが、他にどんなオブジェクトがあるかによっても変わるようです)。 また、objprm命令でコンボボックスの内容を書き変えた場合も、aは-1になってしまうので、注意が必要です(当然ながら、選択インデックスを変えた場合は問題ありません)。 aが自動更新されるのは、ユーザーが何らかのオブジェクトを操作した場合のみのようです(単にwaitを入れただけではダメ、objprmを使ってもダメ。前に書いたように、他のオブジェクトによっては違う場合もある)。したがって、キー入力によって次のステップへ進む判定を行なっている場合、ユーザーが何のオブジェクト操作も行なわずに該当キーを押すと、誤動作します。 listboxも同様です。 comboxについては、Ver. 2.55では直っているようですが、comboxの内容を書き換えるobjprmを実行した場合、aの値は変わらないにも関わらず、comboxの選択は未選択になるようです。 |
BASICでの文字列の大小比較や、Cのstrcmp関数に相当する処理をしたい | |
解説 |
sおよびtが文字変数とすると、「s!t」は、 s==tのとき0、 s>tのとき1、 s<tのとき-1 になります。したがって、例えばBASICの「IF S>T」は「if s!t>0」と書くことができます。 大小比較は次の規則によって判定されます。
なお、if命令は、条件式が0でないとき真、0のとき偽と判定されます。 文字コードについては、マニュアルの「文字列のひみつ」を参照してください。 |
短いファイル名(MS-DOSファイル名)を長いファイル名に変換する命令がない | |
回避方法 | 解説参照 |
改善予定 | 今のところ、なし |
解説 |
パスではなく、ファイル名やフォルダ名のみなら、dirlistで変換できます。 拙作anthspex.dllのLongPath命令を使うと、全体を長いファイル名に変換できます。 |
マニュアルに、ファイル読み込みダイアログ(dialog ,16やdialog ,17)で、複数の拡張子を指定する方法が書かれていない | |
改善予定 | 不明 |
解説 |
セミコロン(;)で区切って、例えば「"bmp;*.mag;*.jpg"」のように書けば、うまくいきます。 行を分けたい場合は、へろへろさんのページのHeloheloFileSelectか、anthspex.dllのselfilesやsavedlgを使いましょう。 |
sndload+sndがうまく行かない場合がある | |
回避方法 | 解説の制限にしたがうかまたはmci命令を使う |
改善予定 | Ver. 2.61β3では直っています |
解説 |
snd命令実行の時点で、最後に実行されたsndload以外は、「"filename"」が15バイト以下でなければなりません。ファイル名のみでも相対パスでも絶対パスでも同じです。 HSP3にはない命令です。HSP3では、mmload、mmplay等を使います。 |
ウィンドウが小さくできない | |
回避方法 | タイトルバーがなくてもよければbgscrを使う(ウィンドウID 2以降) |
改善予定 | 不明 |
解説 |
「screen id,128,……」より小さくできません。ただし、screen 0は130未満にすると右端の表示がおかしくなります。 HSP3では、id1以降は115、id0は117(枠が細いので、ウィンドウの大きさは1以降の115と同じ)が最小です。 bgscrを使った場合のウィンドウの移動方法は、サンプルスクリプトのmovescr.as参照。 Win32APIを使ってもできるようです。 |
モジュールの変数がおかしい | |
回避方法 | 解説参照 |
改善予定 | 不明 |
解説 |
intやstrを指定したパラメータに割り当てた変数は、mrefのp2が同じ変数は、すべて同じ変数になります。例えば、次のスクリプトでは、aとbは同じ変数になります。
#module #deffunc com1 int mref a,0 mes "com1 end a="+a+" b="+b return #deffunc com2 int mref b,0 mes "com2 start a="+a+" b="+b a=36 mes "com2 end a="+a+" b="+b return #global com1 12 com2 23 stopこのことによるバグを回避するには、モジュール命令のintパラメータやstrパラメータに割り当てた変数名は、同じモジュール内では他の目的には使わないことです。 また、strをパラメータとするモジュール命令から、同じ位置にstrを使っているモジュール命令(例えば、llmod.asのdllproc)を直接または間接に呼び出すと、その時点でstrに割り当てた文字変数が書き換えられます。 回避するには、呼び出し前にstrに割り当てた文字変数を別の変数にコピーし、以後コピーの方を使います。 この現象は、intについては起きません。上記スクリプトでも「a=36」の前に「com1 96」を挿入すると、aとbは異なる変数になります。 HSP3では、int型やstr型の引数は定数扱いになったので、このような現象は起きませんが、そのかわり、変数を指定しなければならないところに指定すると、エラーになります。もちろん、代入もできません。 #deffunc com1 str arg1, str arg2, int arg3 c=instr(arg1,arg2,arg3) ;instrの第1引数は変数でなければ ;ならないので、定数扱いのarg1を ;指定するとエラーになる return |