2017-09-15 16 views
0

以下のスクリプトでは、一連のコマンドを実行しようとしています。しかし、F1キーを押して実行すると、内側のループが完了するのを待つことなく、コマンドは両方ともSendAndLoopFor()の呼び出しをすぐに実行します。ループ内の関数補完を待つ方法

関数内にリターンを追加し、その代わりに変数を代入することによってこれを強制しようとしましたが、Foo := SendAndLoopFor()でも、それは操作を待っていません。

次のコマンドを実行する前にSendAndLoopFor()コマンドの完了を待つ方法はありますか?

#NoEnv 
SendMode Input 
SetWorkingDir %A_ScriptDir% 
#MaxThreadsPerHotkey 13 
#SingleInstance 
F1:: 
Done = 0 
Toggle := !Toggle 
Loop 
{ 
    If (!Toggle) 
     Break 
    SendAndLoopFor("4", -13600) 
    SendAndLoopFor("5", -13600) 
} 
return 

SendAndLoopFor(TSend="", Timeout=0) 
{ 
    Send %TSend% 
    SetTimer, LoopLimit, %Timeout% 
    Loop 
    { 
     If(!Toggle) 
      Break 
     If(done == 1) 
     { 
      done = 0 
      Break 
     } 
     MouseClick, left 
     sleep 83 
    } 
} 
LoopLimit: 
    Done = 1 
Return 
+0

あなたは()SendAndLoopF​​or前リターンでお願いします。そして、LoopLimitという名前の存在しないラベルを参照してください –

+0

ああ、本当にその部分を含めるのを忘れてしまった。後で編集してください –

+0

AutoHotkeyはそれらを順番に実行しますが、 'SendAndLoopF​​or'ループのスリープ時間はわずか83ミリ秒です。これは意図的ですか?あなたの現在の遅延がほとんど知覚できないので。 –

答えて

0

あなたの問題は、SetTimerの誤解に由来するようです。これは、スクリプトを本質的にがスクリプトを続行する前に待機するため、タスクを並列化するための優れたツールです。

これを説明するために、スクリプトを簡略化して、同じ効果を観察できます。

F3:: 
SetTimer, LoopLimit, -2000 
SendInput, This is stuff happening before the timer.{Enter} 
return 

LoopLimit: 
SendInput, This is stuff happening after. 

簡単な解決策は、反復回数をカウントしてカウンタの制限値を超えた後にループを強制終了させることです。また、あなたのカットオフ値にループの開始から時間を比較するためにvarious built-in variablesを使用することができますが、これらはで動作するように痛みをすることができ、そのスクリプトは、時間内で作業されていない限り、私はそれらを避けることをお勧めします

F3:: 
count = 0 

Loop 
{ 
; Do stuff. 

count += 1 
Sleep, 1000 

if (count >= 5) 
{ 
break 
}} 

敏感な制約。コメントあたり

編集:

F1:: 
Done = 0 
Toggle := !Toggle 
Loop 
{ 
    If (!Toggle) 
     Break 
    SendAndLoopFor("4", -13600) 
    SendAndLoopFor("5", -13600) 
    Sleep, 2000 
} 
return 

SendAndLoopFor(TSend="", Timeout=0) 
{ 
    Send %TSend% 
    SetTimer, LoopLimit, %Timeout% 
    Loop 
    { 
     If(!Toggle) 
     { 
      SendInput, This is inside the Toggle.{Enter} 
      Break 
     } 
     If(done == 1) 
     { 
      SendInput, This is inside the Done.{Enter} 
      done = 0 
      Break 
     } 
     SendInput, This is after the If statements.{Enter} 
     MouseClick, left 
     Sleep, 999999 ; Note how this has no effect due to above break. 
    } 
} 
LoopLimit: 
    Done = 1 
+0

私はしかし、問題を抱えているループ部分ではありません。それは関数呼び出しの連鎖です。 'SendAndLoopF​​or(" 4 "、-13600)'は、内部的に 'click'コマンドをループします。しかし同時に、他の 'SendAndLoopF​​or(" 5 "、-13600)'も呼び出されます。最初の呼び出しが完了するのを待たずに。 –

+0

@MXDループ内の各条件文をテストする機会はなかったと思いますか? 'SendAndLoopF​​or'の中のあなたの' If(!Toggle) 'は常に真であり、したがってループは常に破損します。あなたが知覚できるほど大きな遅延を持つ睡眠コマンドを持っていないので、同時に発射するように見えますが、そうではありません。彼らはそれをただ完了するだけです。私はあなたのコードを修正して答えを編集し、これを紹介します。 –

+0

効果的に私は同じ方法で別のスクリプトでIf(!Toggle)を使用します。それがうまくいくと、ちょうど良い。 https://gist.github.com/anonymous/36e75336eec880016bc6aef81861edcf(完全なスクリプト)上記の私のコードのサンプルは、まったく同じコードを使用しますが、コピーしたコードを関数に抽出してコードを乾燥させます。また、 'Toggle'文が常に真である場合、それは最初から実行されません。それが最初のループにあることを考慮すると、それはコマンドを呼び出すループです。 –

関連する問題