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


HSPTV!掲示板


未解決 解決 停止 削除要請

2022
0216
motimotiアクティブウインドウを取得できない時がある?4解決


motimoti

リンク

2022/2/16(Wed) 13:12:24|NO.95435

お世話になってます。

ツールを製作してるのですが、そこでちょっと壁にぶち当たったので質問させてください

まずこのコードを実行してボタンを連打してほしいのですが、

screen 1, 200, 50
objsize 200, 50 button gosub "test", *test gsel 0,1 *main gosub *click_check wait 1 goto *main *click_check if ginfo_act != 0 : return getkey leftclick, 1 if leftclick = 1 { if leftclick_pre = 0 { mes "" + mousex +", "+mousey leftclick_pre = 1 } } else { leftclick_pre = 0 } return *test gsel 0,1 return


ボタンクリックしたときに、ウインドウ0がアクティブになっていると
判定される時があるらしく、クリックを検知してしまいます。
ウインドウ1のボタンをクリックしたときはウインドウ0のクリックを検知したくないのですが、
どうしたら良いでしょうか。

よろしくお願いいたします。



この記事に返信する


motimoti

リンク

2022/2/16(Wed) 13:22:01|NO.95436

このコードだと再現率が非常に低いですが、
実際に組み込んだものだと頻発します。

なぜかわかりませんがわかる方いらっしゃったらよろしくお願いいたします。



ネットヤンキーまみ

リンク

2022/2/16(Wed) 15:47:02|NO.95437

当方その様な現象は起こらず、実際にこのソースを見る限り
button gosub "test", *test
*main
の間はスキップされているので再現性はない様に思います。
実際にその現象が起こるコードはここのコードにはない原因があるような気がしますが、
ginfo_act
等を使ってウィンドウのアクティブ/非アクティブをトリガーに組み込むのではだめなのでしょうか。



Drip

リンク

2022/2/16(Wed) 16:28:42|NO.95438

Dripです。
motimotiさん、こんにちは。

ご提示いただいたコードですと、buttonでのラベルジャンプが実行されるサイクルとメインループ内の動作の実行されるタイミングがずれる可能性があるため、期待する動作にならない可能性があります。
実行される順序として、スクリーンID1がマウスダウンによってアクティブになった瞬間、運悪く*click_checkのタスクが実行され、次のアイドルのタイミングでButtonのラベルジャンプが発生するとmotimotiさんの仰るような問題の動作に繋がります。
より再現性を高めるためには、現在 wait 1 とされている箇所を await 0 に変更してみてください。
ほぼ確実に問題の動作が再現されるかと思います。(PC一機でしか検証していないため環境に異存する可能性があるかもしれません。)
さて、実行順序を正しくするためには、メインループでは button などと実行順序が入れ替わっても問題のない処理を記述し、実行順序を一定にしたい処理はonclickで処理を分配するようにしてください。
以下のように改修することで、実行順序が一定になり、問題の動作は起こらなくなるかと思います。

screen 1, 200, 50 objsize 200, 50 button gosub "test", *test //ボタンが押された場合の処理 onclick gosub *click_check //クリックされた場合の処理 gsel 0,1 stop //今回はメインループは不要 *click_check if ginfo_act != 0 : return if iparam = 0 { if leftclick_pre = 0 { gsel 0 //もし他の窓が選択されている可能性があれば指定が必要 mes "" + mousex +", "+mousey } } return *test gsel 0,1 return
なお、余談ですがgselによるウィンドウの「アクティブ化」はWindowsの仕様(?)により絶対に正確じゃない場合があることに注意してください。(単なる操作先ウィンドウの変更は正確に動作します。)
通常は正常にアクティブ化されますが、絶対に設定したウィンドウが想定のタイミングでアクティブにならないとプログラムがクラッシュする恐れがある…というような処理は書かない方が安全です。
可能であれば、強制的にアクティブウィンドウを変更することによって動作の競合を起こす可能性のあるコーディングは避けるようにしてください。



motimoti

リンク

2022/2/17(Thu) 13:51:15|NO.95447

ネットヤンキーまみさん
Dripさん

回答ありがとうございます。

>実行される順序として、スクリーンID1がマウスダウンによってアクティブになった瞬間、運悪く*click_checkのタスクが実行され、次のアイドルのタイミングでButtonのラベルジャンプが発生するとmotimotiさんの仰るような問題の動作に繋がります。

問題発生のメカニズムが理解できました。
タイミングが悪いと、意図しない挙動になってしまうのですね!
waitを0にすると確かに問題の挙動が発生しました。

現状組んでいるものは、クリック中とクリック終わりを監視してるので
*click_checkルーティンをメインループから消すことができませんが、
クリック始めのときだけonclickで対応したいと思います。


>なお、余談ですがgselによるウィンドウの「アクティブ化」はWindowsの仕様(?)により絶対に正確じゃない場合があることに注意してください。(単なる操作先ウィンドウの変更は正確に動作します。)

確かに、別のツールを作っていたときもgselがうまく行かないなと思ったことがありました。
おそらく仕様なので、そこは慎重にコーディングしたいと思います。

ありがとうございました!



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