Hello,
I'm in trouble. I want to create a script :
When i right click (one time) for the first time : the letter "n" is press and release, and the letter "b" is press and stay press.
Later, when i will right click (one time) for a second time, the letter "b" is released.
I tryed so many way, nothing works. (for testing i replace "b release" by "po", i can see if its working on note pad like that)
Looping methode via variable value :
Etatbutton := "1stclic"
Departboucle:
RButton::
if Etatbutton := "1stclic"
{
send, n{b down}
Etatbutton := "2ndclic"
Goto, Departboucle
}
if Etatbutton := "2ndclic"
{
send, x{b up}
Etatbutton := "1stclic"
Goto, Departboucle
}
A Listen in a Listen :
RButton::
{
send, nb
KeyWait, RButton, po
}
Control script via label version :
"
1listen:
KeyWait, RButton, nb
Goto, 2listen
2listen:
KeyWait, RButton, po
Goto, 1listen
"
Big fail ! Someone can help me ?
First clic = do something, (later) 2nd clic do something else
Re: First clic = do something, (later) 2nd clic do something else
Code: Select all
RButton::Send, % (shouldSendAlternate := !shouldSendAlternate) ? "n{b Down}" : "{b Up}"
Re: First clic = do something, (later) 2nd clic do something else
Code: Select all
Etatbutton := "1stclic"
Departboucle:
RButton::
if Etatbutton := "1stclic"
{
send, n{b down}
Etatbutton := "2ndclic"
Goto, Departboucle
}
if Etatbutton := "2ndclic"
{
send, x{b up}
Etatbutton := "1stclic"
Goto, Departboucle
}
The second problem is that once the first If statement resolves, Etatbutton is set to 2ndclic. That means that when it hits the second if statement, THAT statement reads as true and the second block activates immediately.
The third problem is the Goto statement, which because of issue #2 theoretically turns this into an infinite loop and I'm surprised you haven't had this just constantly spam nbxnbxnbxnbxnbxnbx etc as soon as you right click.
Try this:
Code: Select all
Etatbutton := "1stclic"
Rbutton::
if (Etatbutton = "1stclic" )
{
send, n{b down}
Etatbutton := "2ndclic"
}
else
{
send, x{b up}
Etatbutton := "1stclic"
}
return
Re: First clic = do something, (later) 2nd clic do something else
Sorry. I thought the variable names were not important to you. Because I could very well call them simply "x" (so no info). But next time I'll be careful.swagfag wrote:dont code in your native language please, unless english of courseCode: Select all
RButton::Send, % (shouldSendAlternate := !shouldSendAlternate) ? "n{b Down}" : "{b Up}"
In any case, thank you very much for your answer and your code that works perfectly! I will look at its structure more carefully. And thank you again for your reactivity.
Re: First clic = do something, (later) 2nd clic do something else
MaxAstro wrote:There are three problems with this piece of code. The first is that (in most cases) you never want to use the assignment operator := in an if statement. You need to use an equivalency operator instead, = or == (second one is case-sensitive).Code: Select all
Etatbutton := "1stclic" Departboucle: RButton:: if Etatbutton := "1stclic" { send, n{b down} Etatbutton := "2ndclic" Goto, Departboucle } if Etatbutton := "2ndclic" { send, x{b up} Etatbutton := "1stclic" Goto, Departboucle }
The second problem is that once the first If statement resolves, Etatbutton is set to 2ndclic. That means that when it hits the second if statement, THAT statement reads as true and the second block activates immediately.
The third problem is the Goto statement, which because of issue #2 theoretically turns this into an infinite loop and I'm surprised you haven't had this just constantly spam nbxnbxnbxnbxnbxnbx etc as soon as you right click.
Try this:Code: Select all
Etatbutton := "1stclic" Rbutton:: if (Etatbutton = "1stclic" ) { send, n{b down} Etatbutton := "2ndclic" } else { send, x{b up} Etatbutton := "1stclic" } return
For the first problem, I read and understood that:
: = it was for class type (STR) in Python, (string, text)
== it was for class type (INT) in Python. (integer, number)
As I wanted text and not numbers I put: =. I did not understand anything. But good to know.
For the second problem, this is what I do not understand: Once the first If statement resolves, Etatbutton is set to 2ndclic AND it should not read the second since I return it to "startboucle" and as the rbutton is not presumed pressed at this time, nothing should be played (neither the first statement nor the 2nd statement).
Later when I press the rbutton, then the first if statement is read, but not played because etatbutton is "2nd click", and the second if statement is read AND PLAY because etatbutton is 2nd click. at the end of this statement Etatbutton is set to 2ndclic.
For the third point, you do not have to be surprised since it happens exactly what you predict lol And that I do not understand the logic! The Rbutton is not continually pressed THEN once returned to Departboucle(Start loop in english) so nothing should happen until I press Rbutton. Then as etatbutton alternately changes value, the reaction of the Rbutton should change alternately as well.
Do you understand the logic I tried to write with this code? Why does not it stop? What's wrong ?
In any case, a BIG thank you for your code that works very well and ESPECIALLY for your explanation that makes me progress! Thank you for taking the time to explain to me what's wrong!
Re: First clic = do something, (later) 2nd clic do something else
Hotkeys are labels, not if statements. They mark a point in code, they do not halt execution when reached. Only a return statement will do that. As an example, try this code:
You will notice that pressing Ctrl + X will only display "Second Message", and pressing Ctrl + C will only display "Third Message". But pressing Ctrl + Z will display "First Message" and then "Second Message" because there is no return statement.
Code: Select all
^z::
MsgBox First message!
^x::
MsgBox Second message!
return
^c::
MsgBox Third Message!
return
Re: First clic = do something, (later) 2nd clic do something else
ok, that's it. I think I understood. I thought that the "goto" would do the work of the "return" (which I did not know existed). But apparently the goto does not work in this case... If I replace with return : it works better.
Big syntax problem too! The forgetfulness of parenthesis after the "if",was a big problem. Finally, the: = and = as you explained it to me!
And yes, I should have to use the "Else". How I did not think about it instead of giving an "if" condition.
Big thanks to you MaxAstro, you learn me a lot !
swagfag, your code is too complicated to read for me (for now) the "%" and the "?" disturb me! I am going to dig! Because the optimization level ... you wrote in one line what I created for several lines lol we see the degree of expertise ... lol
I let the thread open. If you want to complete your lesson to me MaxAstro or if you want to explain to me your code swagfag... Anyway. Thank you so much. You guyz are awesome. It's my first contact with the autohotkey's community and you represent it well. I love this language and I love you
Big syntax problem too! The forgetfulness of parenthesis after the "if",was a big problem. Finally, the: = and = as you explained it to me!
And yes, I should have to use the "Else". How I did not think about it instead of giving an "if" condition.
Big thanks to you MaxAstro, you learn me a lot !
swagfag, your code is too complicated to read for me (for now) the "%" and the "?" disturb me! I am going to dig! Because the optimization level ... you wrote in one line what I created for several lines lol we see the degree of expertise ... lol
I let the thread open. If you want to complete your lesson to me MaxAstro or if you want to explain to me your code swagfag... Anyway. Thank you so much. You guyz are awesome. It's my first contact with the autohotkey's community and you represent it well. I love this language and I love you
Re: First clic = do something, (later) 2nd clic do something else
Code: Select all
RButton::
{
; uninitialized variable starts off blank, then we assign its logical negation to it.
; blank "" is considered as false, so the negation becomes true.
; the next time RButton is triggered, its state will be flipped, becoming false
; and so on and so on
shouldSendAlternate := !shouldSendAlternate ; the variable is now set to true
if (shouldSendAlternate) {
Send, n ; press and release
Send, {b Down} ; press
}
else {
Send, {b Up} ; release
}
return
}
Re: First clic = do something, (later) 2nd clic do something else
What swagfag used is called a ?: statement or a "ternary operator". It is basically a shorthand way of writing a simple if else statement. It is formatted like this:
( conditional expression ? code to execute if true : code to execute if false)
For an example, try the following script:
You will see that changing the value of X changes the messagebox that pops up.
The second thing swagfag used is the fairly advanced trick (which you actually accidentally included in your original code) of putting an assignment expression into an if statement. When you do that, the assignment is completed and THEN the if is evaluated. For example, in the following code:
You will notice that the messagebox DOES pop up, even though MyVar is initially set to false. This is because MyVar := true sets the variable to true, and THEN the if statement is checked. This is very useful for making toggles, because putting an ! in front of a variable resolves to the opposite of that variable. So if MyVar is true, then !MyVar is false. So look at this example:
Each time you right click, the if statement is evaluated, and MyVar := !MyVar causes MyVar to set to true if it was false, and false if it was true. The result of that is then used to evaluate the if statement. So the first time you right click, the messagebox says "Hello", the second time it says "World", and it alternates between the two.
Putting it all together, then, this line:
Reads "When you click the right mouse button, invert the value of shouldSendAlternate. Then, if shouldSendAlternate is true, send "n{b down}. Otherwise, send "{b up}".
( conditional expression ? code to execute if true : code to execute if false)
For an example, try the following script:
Code: Select all
X := 5
Msgbox % ( X < 10 ? "X is less than ten." : "X is ten or greater.")
return
The second thing swagfag used is the fairly advanced trick (which you actually accidentally included in your original code) of putting an assignment expression into an if statement. When you do that, the assignment is completed and THEN the if is evaluated. For example, in the following code:
Code: Select all
MyVar := false
if (MyVar := true)
MsgBox Hello!
Code: Select all
MyVar := false
Rbutton::
if (MyVar := !MyVar)
MsgBox Hello
else
MsgBox World
Putting it all together, then, this line:
Code: Select all
RButton::Send, % (shouldSendAlternate := !shouldSendAlternate) ? "n{b Down}" : "{b Up}"
Re: First clic = do something, (later) 2nd clic do something else
Thank you very much, I learned lots of new things from you both.
MaxAstro thank you for these detailed explanations, you are REALLY a big help.
I close the subject, I think we have seen everything. Once again thank you.
MaxAstro thank you for these detailed explanations, you are REALLY a big help.
I close the subject, I think we have seen everything. Once again thank you.
Who is online
Users browsing this forum: No registered users and 215 guests