UWSCで休止状態からの復帰タイマーを設定する
UWSC公式掲示板で、二回ほど、状況に応じて次の復帰時間を決めたい、という欲求を見た。
二回目の方は、UWSC自身を別プロセスUWSCから操作するような決着だったけど、それってくどいよね。
ということで、復帰する関数を作ってみた。(モジュールにするほどではなかったので)
スクリプト
の前に、お断り。
このスクリプト、正しいつもりなんですけど、UWSCのLONGLONGがUNSIGNEDなのかコメントにもあるように、215秒以上で動作しません。
LONGLONGがSIGNEDになればこれで良いので、これはこれとして、現時点の対策を下に追記しました。
Resume.uws
OPTION EXPLICIT IFB GET_UWSC_NAME = "Resume.uws" THEN DIM timer timer = SetResumeTimer(VAL(INPUT("何秒後に復帰?", "60"))) IFB timer THEN POFF(P_SUSPEND) ClearResumeTimer(timer) MSGBOX("成功") ELSE MSGBOX("SetTimer失敗") ENDIF ENDIF // 指定時間はだいたいの目安(60秒単位くらいで考えて) FUNCTION SetResumeTimer(sec, rep=0) // 復帰用タイマー設定 DEF_DLL CreateWaitableTimerW(DWORD, BOOL, wstring): DWORD: kernel32 DEF_DLL SetWaitableTimer(DWORD, var LONGLONG, LONG, pbyte, pbyte, BOOL): BOOL: kernel32 RESULT = CreateWaitableTimerW(NULL, FALSE, NULL) IFB RESULT THEN DIM ltime = -10000000 * sec //指定時刻までのタイマー時間を100ns単位で設定 正だとUTC時刻 IFB !SetWaitableTimer(RESULT, ltime, rep, NULL, NULL, TRUE) THEN // rep はミリ秒。0は単発 ClearResumeTimer(RESULT) RESULT = 0 ENDIF ENDIF FEND FUNCTION ClearResumeTimer(timer) DEF_DLL CancelWaitableTimer(DWORD): BOOL: kernel32 DEF_DLL CloseHandle(DWORD): BOOL: kernel32 RESULT = FALSE IF CancelWaitableTimer(timer) THEN RESULT = CloseHandle(timer) FEND
SetResumeTimer関数で、タイマーのハンドルが戻ります。
タイマー処理が終わったら、ClearResumeTimerしてタイマーを解放してください。
基本はCALLでインクルードして使う想定。
このスクリプト単体で動かすと、指定時間後に復帰する動作確認がとれます。
あんまり精度は良くないです。
60秒未満の場合は休止・復帰コストが高いので、Sleepでもしてください。
LONGLONG対策スクリプト
Resume.uws
OPTION EXPLICIT IFB GET_UWSC_NAME = "Resume.uws" THEN DIM timer timer = SetResumeTimer(VAL(INPUT("何秒後に復帰?", "60"))) IFB timer THEN POFF(P_SUSPEND) ClearResumeTimer(timer) MSGBOX("成功") ELSE MSGBOX("SetTimer失敗") ENDIF ENDIF // 指定時間はだいたいの目安(60秒単位くらいで考えて) FUNCTION SetResumeTimer(sec, rep=0) // 復帰用タイマー設定 DEF_DLL CreateWaitableTimerW(DWORD, BOOL, wstring): DWORD: kernel32 DEF_DLL SetWaitableTimer(DWORD, DWORD[], LONG, pbyte, pbyte, BOOL): BOOL: kernel32 RESULT = CreateWaitableTimerW(NULL, FALSE, NULL) IFB RESULT THEN //指定時刻までのタイマー時間を100ns単位で設定 正だとUTC時刻 DIM ltime[1] ltime[0] = VAL("$" + COPY(FORMAT(-10000000 * sec, 16, -1), 9, 8)) ltime[1] = VAL("$" + COPY(FORMAT(-10000000 * sec, 16, -1), 1, 8)) IFB !SetWaitableTimer(RESULT, ltime, rep, NULL, NULL, TRUE) THEN // rep はミリ秒。0は単発 ClearResumeTimer(RESULT) RESULT = 0 ENDIF ENDIF FEND FUNCTION ClearResumeTimer(timer) DEF_DLL CancelWaitableTimer(DWORD): BOOL: kernel32 DEF_DLL CloseHandle(DWORD): BOOL: kernel32 RESULT = FALSE IF CancelWaitableTimer(timer) THEN RESULT = CloseHandle(timer) FEND
とりあえず、300秒(約5分)で試しましたがOKでした。
これでいけるでしょう。(多分)
(不要でしょうが、UTC時刻での設定(正数での設定)は未対応ですが、対応するなら、FORMATに対してReplaceが必要です。)