HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0414
TNK処理の割り込みと関数27解決


TNK

リンク

2015/4/14(Tue) 02:11:08|NO.68547

何度も質問申し訳ありません。
なお、昨日HSPダウンロードしたばかりでよく分かってません。

マニュアルによると、buttonなど処理の割り込みと呼ばれる物があるようですが、
#deffunc や #defcfunc に対して飛ばせるにはどう記述するのでしょうか?
いろいろ書いて見ましたが、呼び出し側の行でエラーが発生してしまいます。

一応マニュアルやヘルプを探して見ましたが、この辺について一切触れられてないように思えました。
(出来るのか出来ないのかに関しても)。


goto label
*label
この記述が気持ち悪くて使いたくないと、
ボタンを押すことによって関数に引数を渡したいです。


それとも、HSPは基本的にラベルへのgotoで解決していくプログラムなのでしょうか?
出来るならば、ラベルは一切使わずにやりたいです



この記事に返信する


ht_ask

リンク

2015/4/14(Tue) 02:22:36|NO.68548

ご推察のとおり、HSPの処理単位はラベルが主体です。
buttonに限らずイベントハンドラの類はラベルジャンプで行います。

一方でラベルには引数が設定できないので、
まともなプログラムを書こうとすればこの二つの併用は避けられないと思います。



TNK

リンク

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が代入されてます。
これで分岐するのが普通でしょうか。



ht_ask

リンク

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のカウントもずれるので注意が必要です。



TNK

リンク

2015/4/14(Tue) 03:14:08|NO.68552

>科学太郎さん
>ht_askさん。
そのように処理させるのですね、ありがとうございます!
おかげさまで記述の勉強にもなります。

ただ、私のHSP読解力だと、その記述はボタンのIDは自動で付けられてるように見えます。
(違ったらすみません)

自分でID名を付けることは出来ますでしょうか?
プログラム時点で、どのボタンが押されたかを判断したいです。
それとも、IDには何か命名規則があって、あらかじめ分かるようになってるんでしょうか?
(よく分かりませんが、命名規則があるんでしょうね、話しの雰囲気的に)。



ht_ask

リンク

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



TNK

リンク

2015/4/14(Tue) 03:40:13|NO.68554

何度もありがとうございました。
分かりました、その方式で作らせてもらいます。



科学太郎

リンク

2015/4/14(Tue) 04:00:39|NO.68555

ginfo_newidがありますよ。



TNK

リンク

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がずれないような工夫をすることになります。



Moz

リンク

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



kk

リンク

2015/4/14(Tue) 10:26:00|NO.68559

>>科学太郎さん
ボタンとかのオブジェクトを作った直後のstatに、そのオブジェクトIDが代入されてるのでいちいち0から数えていく必要ないですよ。
オブジェクトの数が少ないならいいけど増えたら数えるの大変ですし。



kk

リンク

2015/4/14(Tue) 10:27:35|NO.68560

しまった、かぶった。



科学太郎

リンク

2015/4/14(Tue) 11:25:39|NO.68561

> ソースの改変によりずれてもいいように私の場合は毎回、
> オブジェクト作成時に変数へオブジェクトIDを保持するようにしていますね。
同感。
オブジェクトが多く動的に配置を変える場合は、配列に代入しますね。

> ボタンとかのオブジェクトを作った直後のstatに、
> そのオブジェクトIDが代入されてるのでいちいち0から数えていく必要ないですよ。
変えたくないので「enum」を使ってるんです。



kk

リンク

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)



TNK

リンク

2015/4/21(Tue) 09:26:49|NO.68679

マクロを調べた事がなかったので返信が遅れてしまいました。
cputimeやoptimizationを気にしなければ色々できるのですね。
大変参考にさせて頂きました。
オブジェクトにイベントハンドラを参照渡しできますと言われたら完全に騙されたと思います。



TNK

リンク

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



ht_ask

リンク

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"



TNK

リンク

2015/4/25(Sat) 20:53:10|NO.68763

まさかのコンパイルより先ッ!
コンパイラに対する制御をおこなうものだったんですね。
(実行に対して制御するなにかはなし?)



ht_ask

リンク

2015/4/25(Sat) 21:12:21|NO.68765

HSPに限らず、大方の言語でプリプロセッサ命令とはそういうものですよ。
include等と同じく、"前処理"としてソースコードを直に置換するのでpre-processorです。



TNK

リンク

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



TNK

リンク

2015/4/25(Sat) 23:18:16|NO.68771

意味が分かってきました。
これはたぶんあとから入ってきた文字列への、
そこの実行時点での再コンパイルの手続きでしょうか。
呼び出すときのマクロの引数は文字列(記述)であって、ソースではないと。

<PRE>
;動的に変数名を作る
#define test(%1,) %ttest %1aaa = 100

;引数は記述でもリテラルでもなんでもないので裸で書いてエラーにならない
test bbb
mes bbbaaa


evalでも実装すればいいものを…



TNK

リンク

2015/4/25(Sat) 23:45:17|NO.68773

あ、それコンパイルエラーだった(一応)

(%1,) → (%1)



ONION software Copyright 1997-2023(c) All rights reserved.