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


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
1030
ゆうやんoncmdで一部 割り込みを停止するには?7解決


ゆうやん

リンク

2019/10/30(Wed) 21:47:00|NO.88770

oncmdで一部割り込みを停止することはできないのでしょうか?
oncmd 0ですべての割り込みを停止することができますが、WM_SIZEだけ割り込みを有効にして、WM_MOVEだけ割り込みを停止することはできないのでしょうか?

#define WM_MOVE 0x0003 #define WM_SIZE 0x0005 screen 1 oncmd gosub *move,WM_MOVE oncmd gosub *resize,WM_SIZE wait 500 oncmd 0,WM_MOVE;WM_MOVEだけ割り込みを停止させたい。「パラメーターの数が多すぎる」というエラーが出てしまう。 stop *move dialog "ウィンドウが移動されました。" return *resize dialog "サイズが変更されました。" return



この記事に返信する


(^_^)v

リンク

2019/10/30(Wed) 23:19:13|NO.88771

残念ながらできませんのでフラグなどで管理する必要があります。

#define WM_MOVE 0x0003 #define WM_SIZE 0x0005 #define TRUE 1 #define FALSE 0 screen 1 oncmd gosub *WindowProc,WM_MOVE oncmd gosub *WindowProc,WM_SIZE WM_MOVE_State = TRUE WM_SIZE_State = FALSE wait 500 WM_MOVE_State = FALSE stop *WindowProc switch iparam case WM_MOVE if WM_MOVE_State: gosub *move swbreak case WM_SIZE if WM_SIZE_State: gosub *resize swbreak swend return *move mes "ウィンドウが移動されました。" return *resize mes "サイズが変更されました。" return

なお、デフォルトプロシージャに戻り値を帰す必要がある場合はもうひと工夫必要になります



MillkeyStars

リンク

2019/10/31(Thu) 10:05:30|NO.88772

return に引数をつけなければいい。
return に引数をつけるとデフォルトプロシージャに移行しない。

[ヘルプ抜粋]
システム変数iparamには、送信されたメッセージIDが代入されます。
また、wparam,lparamはWindowsメッセージとして渡されたパラメータがそのまま格納されています。
割り込みの設定で、 gosubキーワードによるサブルーチンジャンプが発生した場合は、return命令により戻り値を設定することが可能です。
「return 数値」で、ウィンドウプロシージャーが返す値を指定します。
return命令にパラメーターを指定しなかった場合には、デフォルトのウインドゥプロシージャーに処理が渡されます。



(^_^)v

リンク

2019/10/31(Thu) 20:37:50|NO.88776

間違えましたね
デフォルトプロシージャではなくWindowsに戻り値を返したい場合に面倒です
(というか引数つけてないのにそのツッコミはわざとですよね)



ゆうやん

リンク

2019/11/1(Fri) 18:00:25|NO.88780

>(^_^)vさん
ありがとうございます。

つまり、完全に割り込みを停止することはできないのでしょうか?
wait無視されたまま、次の行に移ってしまいますが、他の方法はないのでしょうか?

#define WM_MOVE 0x0003 #define WM_SIZE 0x0005 #define TRUE 1 #define FALSE 0 screen 1 oncmd gosub *WindowProc,WM_MOVE oncmd gosub *WindowProc,WM_SIZE WM_MOVE_State = TRUE WM_SIZE_State = TRUE wait 500 WM_MOVE_State = FALSE wait 6000;WM_MOVEを無効したにも関わらず、ウィンドウを移動すると無視されてしまう。(WM_SIZEも同様だが、無効にしていない) mes "1分経過しました。" stop *WindowProc switch iparam case WM_MOVE if WM_MOVE_State: gosub *move swbreak case WM_SIZE if WM_SIZE_State: gosub *resize swbreak swend return *move mes "ウィンドウが移動されました。" return *resize mes "サイズが変更されました。" return



(^_^)v

リンク

2019/11/1(Fri) 20:15:22|NO.88782

waitを無視したような動きになっているのは割り込みの停止とは関係ありません。
oncmdで指定したラベルに飛ぶのはstopかwaitでプログラムが止まっているときになります。
そしてreturnするとstopはstopした場所に戻りますが、waitは残り時間を待つということはせずに次の行から実行されます。


#include "winmm.as" #define WM_MOVE 0x0003 #define WM_SIZE 0x0005 #define TRUE 1 #define FALSE 0 screen 1 oncmd gosub *WindowProc,WM_MOVE oncmd gosub *WindowProc,WM_SIZE WM_MOVE_State = TRUE WM_SIZE_State = TRUE waittime = 10 * 1000 //5秒 starttime = timeGetTime() endtime = timeGetTime() + waittime repeat if timeGetTime() > endtime: break await 16 loop WM_MOVE_State = FALSE dialog "10秒経ちました" stop *WindowProc switch iparam case WM_MOVE if WM_MOVE_State: gosub *move swbreak case WM_SIZE if WM_SIZE_State: gosub *resize swbreak swend return *move logmes "ウィンドウが移動されました。" return *resize logmes "サイズが変更されました。" return



ゆうやん

リンク

2019/11/3(Sun) 10:56:46|NO.88789

>(^_^)vさん
ありがとうございます。
今のところ、完全に割り込みを停止する方法はないみたいですね。
しばらくこの方法で使ってみようと思います。



MillkeyStars

リンク

2019/11/3(Sun) 11:01:54|NO.88790

ゆうやんさんの言いたいことは、wait・await 中にウィンドウメッセージで、強制的にウェイトが終了してしまうのを対策したいという事だと思うが、oncmd gosub の指定解除する命令がない以上、別の対策法でしかない。
昔から、oncmd gosub を利用する場合は、wait・await は独自のウェイトに置き換えるか、(^_^)v さんの方法でしかないからね。

ちなみに HSP 内部ではこんな感じになっていて、 MsgWaitForMultipleObjects の QS_ALLINPUT ってのが原因。
関数を抜ける条件がすべての入力メッセージという事になっていて、oncmd gosub で指定されたメッセージが来ると、タイムアウト時間を無視してしまう。

// 高精度タイマー tick = timeGetTime()+5; // すこし早めに抜けるようにする if ( code_exec_await( tick ) != RUNMODE_RUN ) { MsgWaitForMultipleObjects(0, NULL, FALSE, hspctx->waittick - tick, QS_ALLINPUT ); } else { tick = timeGetTime(); while( tick < hspctx->waittick ) { // 細かいwaitを取る Sleep(1); tick = timeGetTime(); } hspctx->lasttick = tick; hspctx->runmode = RUNMODE_RUN; #ifndef HSPDEBUG if ( ctx->hspstat & HSPSTAT_SSAVER ) { if ( hsp_sscnt ) hsp_sscnt--; } #endif
以下、(^_^)v さんのを改良してモジュール化したサンプル

#module #define _THYPER //←をコメントアウトすると標準精度 #ifndef _THYPER //標準精度のタイマー #uselib "kernel32.dll" #cfunc _GetTickCount "GetTickCount" #else //高精度のタイマー #uselib "winmm.dll" #cfunc _GetTickCount "timeGetTime" #endif #deffunc awaitEx int p1 if p1 < 0 : return a_waittick = _GetTickCount() //開始のtick e_waittick = a_waittick + p1 //終了のtick await p1 repeat p_waittick = _GetTickCount() c_waittick = e_waittick - p_waittick if c_waittick <= 0 : break await c_waittick //残りの時間強制再ウェイト loop return #deffunc waitEx int p1 if p1 < 0 : return awaitEx (p1 * 10) return #global #define WM_MOVE 0x0003 oncmd gosub *Dummy,WM_MOVE waitEx 1000 mes "タイムアウト" stop *Dummy return 0

んぁ、書き直してたら締め切られてた。
順序は逆になっちゃったけど、今後の対策法として残しておきます。



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