|
|
2015/4/14(Tue) 02:11:08|NO.68547
何度も質問申し訳ありません。
なお、昨日HSPダウンロードしたばかりでよく分かってません。
マニュアルによると、buttonなど処理の割り込みと呼ばれる物があるようですが、
#deffunc や #defcfunc に対して飛ばせるにはどう記述するのでしょうか?
いろいろ書いて見ましたが、呼び出し側の行でエラーが発生してしまいます。
一応マニュアルやヘルプを探して見ましたが、この辺について一切触れられてないように思えました。
(出来るのか出来ないのかに関しても)。
goto label
*label
この記述が気持ち悪くて使いたくないと、
ボタンを押すことによって関数に引数を渡したいです。
それとも、HSPは基本的にラベルへのgotoで解決していくプログラムなのでしょうか?
出来るならば、ラベルは一切使わずにやりたいです
|
|
2015/4/14(Tue) 02:22:36|NO.68548
ご推察のとおり、HSPの処理単位はラベルが主体です。
buttonに限らずイベントハンドラの類はラベルジャンプで行います。
一方でラベルには引数が設定できないので、
まともなプログラムを書こうとすればこの二つの併用は避けられないと思います。
|
|
2015/4/14(Tue) 02:35:56|NO.68549
ご返信ありがとうございます。
>イベントハンドラの類はラベルジャンプで行います。
ではイベントの類は、全てラベルで見分けなきゃならないのでしょうか?
たとえば100個ボタンを作ると、100個のラベルと100個のgotoが発生するのでしょうか?
もし他の方法を知っていればお願いします。
(出来ればでいいのですが、1個のオブジェクト、または関数に対して引数を送れる形式がいいです)。
マニュアルを読んでもよく分かりません。
|
|
2015/4/14(Tue) 02:48:35|NO.68550
> たとえば100個ボタンを作ると、100個のラベルと100個のgotoが発生するのでしょうか?
基本的には100個のラベルに飛びますが、同じラベル名にジャンプさせることが可能です。
title "300個のボタン・テスト"
objsize 32,32
repeat(ginfo_winY/32):cntY=cnt
repeat(ginfo_winX/32):cntX=cnt
pos(32*cntX),(32*cntY)
button gosub strf("%d",no),*PushButton
no++
loop
loop
stop
*PushButton
dialog strf("ボタンのIDは%dです。",stat),0,"確認"
return
ボタンが押されると同じ「*PushButton」へジャンプしますが、
この時にシステム変数「stat」にボタンIDが代入されてます。
これで分岐するのが普通でしょうか。
|
|
2015/4/14(Tue) 03:02:21|NO.68551
オブジェクトIDというものがありまして、それを使って同一のラベルから処理を振り分けることが可能です。
objsize 50, 24
repeat 100
if (cnt \ 24) = 0 : pos cnt / 24 * 50, 0
button gosub "" + cnt, *on_button
loop
stop
*on_button
dialog "obj_id=" + stat
return
ちなみにこのIDはあらゆるオブジェクトを配置したあとの戻り値から取得できるもので、
前にinputなどの他のオブジェクトがあるとその分だけIDのカウントもずれるので注意が必要です。
|
|
2015/4/14(Tue) 03:14:08|NO.68552
>科学太郎さん
>ht_askさん。
そのように処理させるのですね、ありがとうございます!
おかげさまで記述の勉強にもなります。
ただ、私のHSP読解力だと、その記述はボタンのIDは自動で付けられてるように見えます。
(違ったらすみません)
自分でID名を付けることは出来ますでしょうか?
プログラム時点で、どのボタンが押されたかを判断したいです。
それとも、IDには何か命名規則があって、あらかじめ分かるようになってるんでしょうか?
(よく分かりませんが、命名規則があるんでしょうね、話しの雰囲気的に)。
|
|
2015/4/14(Tue) 03:33:26|NO.68553
はい、自動で付けられます。
カウントの規則は0からの連番で、オブジェクトが生成されるごとに発行されます。
chkbox "objid=0", dummy
chkbox "objid=1", dummy
chkbox "objid=2", dummy
repeat 10
button gosub "" + cnt, *on_button
if cnt = 0 : btnid_first = stat
loop
btnid_last = stat
mes "" + btnid_first + "-" + btnid_last + "がボタンIDです"
stop
*on_button
dialog "btnidx=" + (stat - btnid_first) ; 0から直感的にカウントしたい場合
return
あと、オブジェクトIDはウィンドウごとに独立します。
screen 0
repeat 5
chkbox "a", dummy
mes stat
loop
screen 1
repeat 5
chkbox "b", dummy
mes stat
loop
|
|
2015/4/14(Tue) 03:40:13|NO.68554
何度もありがとうございました。
分かりました、その方式で作らせてもらいます。
|
|
2015/4/14(Tue) 04:00:39|NO.68555
ginfo_newidがありますよ。
|
|
2015/4/14(Tue) 04:04:15|NO.68556
よくわかりませんが、ginfo_newidと言うのを使えばウインドウが判別できるということですね。
(違う?)
|
|
2015/4/14(Tue) 04:52:30|NO.68557
> よくわかりませんが、ginfo_newidと言うのを使えばウインドウが判別できるということですね。
> (違う?)
あっ。ちょっと間違いました。→忘れて下さい。
HSPでダイアログのような画面を作るときは次のようにするといいと思います。
;列挙定数(オブジェクトID)
#enum FID_CHECK01=0
#enum FID_CHECK02
#enum FID_CHECK03
#
#enum BID_PUSH01
#enum BID_PUSH02
#enum BID_PUSH03
#enum BID_PUSH04
#enum BID_PUSH05
*Init
dim chkFlag,3
*Main
;チェックボックス×3個
objsize 100,23,25
repeat 3
chkbox strf("チェックボックス%d",cnt+1),chkFlag(cnt)
loop
;プッシュボタン×5個
objsize 100,23,25
repeat 5
button gosub strf("プッシュボタン%d",cnt+1),*Push
loop
stop
*Push
switch stat
case BID_PUSH01:s="BID_PUSH01":swbreak
case BID_PUSH02:s="BID_PUSH02":swbreak
case BID_PUSH03:s="BID_PUSH03":swbreak
case BID_PUSH04:s="BID_PUSH04":swbreak
case BID_PUSH05:s="BID_PUSH05":swbreak
swend
dialog s,0,"確認"
return
つまり、ウインドウが作成された時、オブジェクトIDは「0」から始まるので列挙定数でチェック可能です。
また「clrobj」命令で全てのオブジェクトをクリアして再配置するとオブジェクトIDは「0」から始まります。
なお「clrobj」命令で1つのオブジェクトをクリアすると未使用なオブジェクトIDが次の配置で使われ、
通し番号であるオブジェクトIDはずれるためクリアするならすべてクリアした方が良い。
もし、1つだけ消したい場合は非表示してオブジェクトIDがずれないような工夫をすることになります。
|
|
2015/4/14(Tue) 10:23:48|NO.68558
>なお「clrobj」命令で1つのオブジェクトをクリアすると未使用なオブジェクトIDが次の配置で使われ、
>通し番号であるオブジェクトIDはずれるためクリアするならすべてクリアした方が良い。
>もし、1つだけ消したい場合は非表示してオブジェクトIDがずれないような工夫をすることになります。
ソースの改変によりずれてもいいように私の場合は毎回、
オブジェクト作成時に変数へオブジェクトIDを保持するようにしていますね。
button "A1",*label_A : btn_A1_ID=stat
button "A2",*label_A : btn_A2_ID=stat
button "A3",*label_A : btn_A3_ID=stat
dim btn_B_ID,3
repeat 3
button "B"+(cnt+1),*label_B : btn_B_ID(cnt)=stat
loop
stop
*label_A
if btn_A1_ID=stat : mes "A1が押されました"
if btn_A2_ID=stat : mes "A2が押されました"
if btn_A3_ID=stat : mes "A3が押されました"
stop
*label_B
if btn_B_ID(0)=stat : objenable btn_A1_ID,0
if btn_B_ID(1)=stat : objenable btn_A2_ID,0
if btn_B_ID(2)=stat : objenable btn_A3_ID,0
stop
|
|
2015/4/14(Tue) 10:26:00|NO.68559
>>科学太郎さん
ボタンとかのオブジェクトを作った直後のstatに、そのオブジェクトIDが代入されてるのでいちいち0から数えていく必要ないですよ。
オブジェクトの数が少ないならいいけど増えたら数えるの大変ですし。
|
|
2015/4/14(Tue) 10:27:35|NO.68560
しまった、かぶった。
|
|
2015/4/14(Tue) 11:25:39|NO.68561
> ソースの改変によりずれてもいいように私の場合は毎回、
> オブジェクト作成時に変数へオブジェクトIDを保持するようにしていますね。
同感。
オブジェクトが多く動的に配置を変える場合は、配列に代入しますね。
> ボタンとかのオブジェクトを作った直後のstatに、
> そのオブジェクトIDが代入されてるのでいちいち0から数えていく必要ないですよ。
変えたくないので「enum」を使ってるんです。
|
|
2015/4/14(Tue) 11:35:04|NO.68562
>変えたくないので「enum」を使ってるんです
なんか意味あるんですかそれ
|
|
2015/4/14(Tue) 13:32:22|NO.68563
>なお、昨日HSPダウンロードしたばかりでよく分かってません。
あなたは、HSPTV!掲示板に2015年4月12日に初めて質問していますよね?
そのスレッドには、>ダウンロードしたばかりで、ざっとマニュアルを読んだのですが、と書いてありますよね?
なのになぜ、今になってから >なお、昨日HSPダウンロードしたばかりでよく分かってません。何ですか?
ヘンですよ。
|
|
2015/4/15(Wed) 09:11:06|NO.68566
>>シャックリさん
>あなたは、HSPTV!掲示板に2015年4月12日に初めて質問していますよね?
>そのスレッドには、>ダウンロードしたばかりで、ざっとマニュアルを読んだのですが、と書いてありますよね?
>なのになぜ、今になってから >なお、昨日HSPダウンロードしたばかりでよく分かってません。何ですか?
>ヘンですよ。
質問の投稿時間を見れば、さほど変ではないと分かりますし
そうでなくてもいちいち追求するような事ではないですよ。
|
|
2015/4/20(Mon) 20:17:35|NO.68672
マクロ使ってラベル名やボタンIDを気にしないで
buttonを配置して命令や関数を直接書いて実行できるようにしてみた
#module;
#defcfunc split_n str p1, array val,local c,local i;------------------------------------------------------------------
;文字列を改行に沿って分割して返す
txt = p1;
sdim val
repeat; #1行づつ取りだす
getstr txt2, txt, i; #改行までを取り出す
if strlen(txt2) < 1 : break; #何もなければループ終了
val.cnt = txt2; #配列に保存
i = i + strsize; #位置情報を修正
c++
loop;
return c
#global;
//button_goto "文字列",命令や関数等
#define button_goto(%1,%2) button %1,%tbutton *%i :if 0 {%tbutton *%o:%2 :stop}
//button_gosub "文字列",命令や関数等
#define button_gosub(%1,%2) button gosub %1,%tbutton *%i :if 0 {%tbutton *%o:%2 :return}
buf="aaa\nbbb\nccc"
mesbox buf,100,100
button_goto "mes表示",mes buf //命令型はパラメータ一つなら渡せる
button_goto "行数",mes split_n( buf ,var) //関数型ならパラメータ数に制限は無い ( c=split_n( buf ,var) の様な使い方も出来る)
//ctypeマクロと組み合わせると一行に複数命令も使える(マクロには文字数制限があるが・・・)
#define ctype c_gmode_pos_gcopy(%1=0,%2=32,%3=32,%4=0 ,%5=0,%6=0 ,%7=0,%8=0,%9=0) pb@tmp=ginfo_cx,ginfo_cy:gmode %1,%2,%3,%4:pos %5,%6:gcopy %7,%8,%9 :pos pb@tmp,pb@tmp(1)
button_goto "gcopy",c_gmode_pos_gcopy(0,100,200,60 ,300,100 ,0,0,100) //関数型ならパラメータ数に制限は無い
#define ctype c_fill_pos(%1=0,%2=0) color 255,255,255:boxf:color:pos %1,%2
button_gosub "クリア",c_fill_pos(0,200)
| |
|
2015/4/21(Tue) 09:26:49|NO.68679
マクロを調べた事がなかったので返信が遅れてしまいました。
cputimeやoptimizationを気にしなければ色々できるのですね。
大変参考にさせて頂きました。
オブジェクトにイベントハンドラを参照渡しできますと言われたら完全に騙されたと思います。
|
|
2015/4/25(Sat) 19:20:02|NO.68753
他に覚える事がけっこうあるので、マクロはまだあまり頭に入ってませんが、
どうも変数が静的な展開をしていないようでうす。
と言うご報告です。
#module;
#deffunc fnc str val
mes val
return
#global;
//button_goto "文字列",命令や関数等
#define button_goto(%1,%2) button goto %1,%tbutton *%i :if 0 {%tbutton *%o:%2 :return}
//button_gosub "文字列",命令や関数等
#define button_gosub(%1,%2) button gosub %1,%tbutton *%i :if 0 {%tbutton *%o:%2 :return}
repeat 10
count = "" + cnt + ""
button_gosub count, fnc count
loop
|
|
2015/4/25(Sat) 20:38:09|NO.68760
まあこれは仕様ですね。コンパイル時には以下のように置換されますので。
repeat 10
count = "" + cnt + ""
button gosub count, *_button_0000
if 0 {
*_button_0000
fnc count
return
}
loop
ラベル名のチェックです。HSPはなぜかマクロは強力なんですよね。
#define push %ttest mes "push:%i"
#define pop %ttest mes "pop :%o"
push
pop
push
push
pop
pop
HSPに最適化がいつ追加されないとも限らないので、
スタック維持機能のテストがてら、暇人さんのマクロを少し改良してみました。
(%tマクロは一個記述するだけで十分だと思います)
#define button_goto(%1, %2) %tbutton\
button goto %1, *%i : goto *through%p : *%p : %2 : stop : *through%o
#define button_gosub(%1, %2) %tbutton\
button gosub %1, *%i : goto *through%p : *%p : %2 : return : *through%o
button_goto "goto", mes "goto test"
button_gosub "gosub", mes "gosub test"
|
|
2015/4/25(Sat) 20:53:10|NO.68763
まさかのコンパイルより先ッ!
コンパイラに対する制御をおこなうものだったんですね。
(実行に対して制御するなにかはなし?)
|
|
2015/4/25(Sat) 21:12:21|NO.68765
HSPに限らず、大方の言語でプリプロセッサ命令とはそういうものですよ。
include等と同じく、"前処理"としてソースコードを直に置換するのでpre-processorです。
|
|
2015/4/25(Sat) 21:24:15|NO.68766
そういえば#はプリプロセッサでしたね。
プリプロセッサと言うよりプラグマに近いのでしょうか?
最初は、マクロと言う名前だからコンパイルで畳み込まれたあと、
実行ごとに参照するような物だと(勝手に)思ってました。
|
|
2015/4/25(Sat) 22:12:15|NO.68769
理屈は分かったみたいなので
repeatにちょっと無理やり対応してみる・・・
#module;
#deffunc fnc str val
mes val
return
#global;
//button_gosub "文字列",命令や関数等
#define button_gosub(%1,%2) button gosub %1,%tbutton *%i :if 0 {*%o:%2 :return}
sdim count@fnc
repeat 10
count = "" + cnt + ""
button_gosub count,fnc count@fnc(stat) : count@fnc(stat)=count
loop
|
|
2015/4/25(Sat) 23:18:16|NO.68771
意味が分かってきました。
これはたぶんあとから入ってきた文字列への、
そこの実行時点での再コンパイルの手続きでしょうか。
呼び出すときのマクロの引数は文字列(記述)であって、ソースではないと。
<PRE>
;動的に変数名を作る
#define test(%1,) %ttest %1aaa = 100
;引数は記述でもリテラルでもなんでもないので裸で書いてエラーにならない
test bbb
mes bbbaaa
evalでも実装すればいいものを…
|
|
2015/4/25(Sat) 23:45:17|NO.68773
あ、それコンパイルエラーだった(一応)
(%1,) → (%1)
|
|