zx81
zx81

Reputation: 41838

Simple conditional pass through

Wondering if I might be missing something basic in AHK: Is there a way to do a simple conditional pass-through for any mouse or keyboard action, so that if the conditions fail, the action just passes through?

Something like:

LButton::
if(WinActive("ahk_class Notepad")) {
    ; Do something cool
    }
else { 
     ; Pass through
     }

What is giving me particular trouble is a case where a LButton must be passed through. The "cleanest" technique seems to fail (see the non-working script at the bottom) when the left click is the start of a dragging action. I have a workaround, but it is verbose.

What I have tried

I have a working solution, but it's rather verbose. Below, I've adapted it to a simple Notepad example for demo purposes. What the demo script does:

I have also tried an approach with the $ modifier that is not working (please see at the bottom).

Notes

Working Script

#NoEnv  ; Recommended for all scripts. Avoids checking empty variables to see if they are environment variables.

LButton::
if(WinActive("ahk_class Notepad")) {
    MouseGetPos, x, y, ovw, control
    if(control = "Edit1") {
      SplashTextOn 300, 100, AutoHotkey Message, You can play with the menus`,`nbut not the text box. 
      Sleep 3000 
      SplashTextOff
      }
   else { ; pass the click through
        ; The reason we Click down is that a plain Click doesn't work
        ; for actions where hold the button down in order to drag.
        Click down
       }
   }
 else { 
      Click down
      }
Return

; The LButton section holds the down state, so we need to allow it Up
LButton Up::Click up  

Non-Working Script using $

This approach is not working because the Notepad window can no longer be resized: the "pass-through" seems to click, rather than clicking down when that is the need (dragging action).

#NoEnv  ; Recommended for all scripts. Avoids checking empty variables to see if they are environment variables.
#IfWinActive ahk_class Notepad
$LButton::
MouseGetPos, x, y, ovw, control
    if(control = "Edit1") {
        SplashTextOn 300, 100, AutoHotkey Message, You can play with the menus`,`nbut not the text box. 
        Sleep 3000 
        SplashTextOff
      }
     else {  ; pass the click through
             Send {LButton}
          }
Return
#IfWinActive

Upvotes: 3

Views: 479

Answers (1)

MCL
MCL

Reputation: 4065

#If... directives are used to make a hotkey only trigger under certain conditions. This of course means: If the given condition is not met, the hotkey routine will not be called and the keys will pass through (and they will pass through like native key events at that).

Your example:

; $ prevents the hotkey from triggering itself
$LButton::
  if(WinActive("ahk_class Notepad")) {
      ; Do something cool
  } else { 
      ; Pass through
      Send, LButton
  }
return

Can easily be written as:

#IfWinActive, ahk_class Notepad
LButton::
   ; Only the cool stuff goes here
return
#IfWinActive

More specific to your problem, you can also use #If in conjunction with an expression in order to determine a combination of arbritrary conditions, namely to check if the user is trying to click into the text box in a Notepad window:

#If WinActive("ahk_class Notepad") && MouseOver() = "Edit1"
LButton::
    SplashTextOn 300, 100, AutoHotkey Message, You can play with the menus`,`nbut not the text box. 
    Sleep 3000 
    SplashTextOff
Return
#If

MouseOver() {
    MouseGetPos, , , , curControl
    return curControl
}

Upvotes: 3

Related Questions