Windows Volume Control Using Your Mouse Wheel and the AutoHotkey #If Directive (Beginning Hotkeys Part 6)

The AutoHotkey #If Expression Directive and Hotkey, If (Expression) Command Make Hotkeys Expression-Sensitive, Plus a Simple No-Click Volume Control Script

Volume Control
The mouse wheel controls volume while hovering the cursor over the Taskbar in Windows. (This is a Windows 10 example).

The AutoHotkey documentation for the #If expression directive includes a short script at the bottom of the page which is perfect for demonstrating how to use the Hotkey, If (Expression) command and its interdependence on the #If expression directive. It’s a cool little app because it reduces Windows volume control to simply scrolling the mouse wheel up or down while hovering the mouse cursor over the Windows taskbar—no click required!

*         *          *

This beginning Hotkey blog builds upon the discussions in the previous parts. If you find any of the information too confusing, then reviewing earlier blogs may be worthwhile.

New to AutoHotkey? See “Introduction to AutoHotkey: A Review and Guide for Beginners.”

*          *          *

The #If Expression Directive

 

hotkeycover200
This blog on Windows volume control is now Chapter Six in the AutoHotkey Hotkey Techniques book.

The #IfWinActive directive restricts Hotkeys to particular program windows. However, there are many times when expressions are useful for determining whether or not to activate a Hotkey. For example, suppose you want a Hotkey working only when the mouse cursor hovers over a certain portion of the Windows screen—in this case, the Taskbar. The following script does just that by implementing an #If expression directive which checks the mouse cursor location:

 

#If MouseIsOver("ahk_class Shell_TrayWnd")
   WheelUp::Send {Volume_Up}
   WheelDown::Send {Volume_Down}
#If

MouseIsOver(WinTitle)
{  MouseGetPos,,, Win
   Return WinExist(WinTitle . " ahk_id " . Win)
}

There are two parts to this snippet of code. The first is the #If expression directive which creates the conditional Hotkeys (mouse WheelUp and WheelDown) during the initial scan of the loading AutoHotkey file. The second part—the function MouseIsOver(WinTitle) (also loaded before running any AutoHotkey commands)—determines the mouse cursor location.

The #If expression directive is similar in form and function to the #IfWinActive directive discussed in this previous blog, except that it can respond to any AutoHotkey expression rather than merely active/non-active windows and existing/non-existing windows. (The #If expression directive is positional, just like #IfWinActive, affecting all Hotkeys and Hotstrings following it in the script until encountering another #If expression or #IfWinActive directive.) The #If expression directive used in the above snippet activates the mouse wheel Hotkeys whenever the mouse cursor hovers over the Windows Taskbar (ahk_class Shell_TrayWnd)—as detected by the MouseIsOver(WinTitle) function.

The MouseIsOver(WinTitle) function returns true (WinExist(WinTitle . ” ahk_id ” . Win)) whenever the MouseGetPos command retrieves the Windows Taskbar’s unique ID (Win) for the Taskbar. Since the Windows Taskbar always exists, using only the window title in the WinExist() function won’t do the job. The MouseGetPos command must be implemented to determine if the cursor is actually over the Taskbar by grabbing its unique ID.

If this is all that you want to do while hovering the cursor over the Taskbar, then using the #Directives and standard double-colon Hotkey definitions is probably your best bet. However, if you want to make changes to the initial setup or add more capabilities after the script loads, then the Hotkey, If (expression) command is in order. Even then, the script requires the inclusion of at least the first #If expression directive (#If MouseIsOver(“ahk_class Shell_TrayWnd”)) to work.

The Hotkey, If (Expression) Command

By using the #If expression directive, the conditional is embedded in the script. Once loaded, the only way to change it is with the Hotkey, If (expression) command. However, the Hotkey, If (expression) command cannot work without a previously loaded #If expression directive. For example, if I want to modify the previous Hotkeys with the Hotkey, If (expression) command, the line:

#If MouseIsOver("ahk_class Shell_TrayWnd")

must appear somewhere in the script—preferably at the end where it will not affect anything else in the file. Without a corresponding #If expression directive, the Hotkey, If (expression) command will not work.

The following is an example of how to implement the same Taskbar no-click volume control using the Hotkey, If (expression) command:

Hotkey, If, MouseIsOver("ahk_class Shell_TrayWnd")
  Hotkey, WheelUp, VolUp
  Hotkey, WheelDown, VolDown
Hotkey, If
VolUp:
  Send {Volume_Up}
Return
 
VolDown:
  Send {Volume_Down}
Return
MouseIsOver(WinTitle) 
{
  MouseGetPos,,, Win
  Return WinExist(WinTitle . " ahk_id " . Win)
}
#If MouseIsOver("ahk_class Shell_TrayWnd")   ;required

This script essentially completes the same action as the first example. On the downside, this Hotkey command approach requires twice as many lines of code. Since the Hotkey command cannot directly use commands, each newly created (or modified) Hotkey requires a new Label subroutine (VolUp and VolDown). Plus, the corresponding #If expression directive (at the end of the script) must be included in order for the Hotkey command to work at all. For these reasons alone I would tend to stick with the first approach using only #Directives and double-colon Hotkey definitions. However, if later you want to add more capabilities when the mouse cursor hovers over the Windows Taskbar, then all that’s needed is the matching Hotkey, If (expression) command. The next example adds another Hotkey feature to the original Taskbar hovering event.

Making Better Use of the Caps Lock Key

In “Chapter Eight” of the book Digging Deeper into AutoHotkey, I discuss how to make better use of keys I consider virtually useless; in particular, the Caps Lock and Insert keys. The Caps Lock key is especially wasteful—unless you spend a great deal of time YELLING on the Internet. Even then a simple Hotkey can change all text to uppercase (lowercase or initial cap) as demonstrated in “Chapter Four” of A Beginner’s Guide to AutoHotkey. (Although, that discussion was confined to basic Hotkey definitions.) What if you want to make the Caps Lock key more useful in various ways in different situations?

In the following example, the previously created #If expression directive conditional for hovering over the Taskbar adds new functionality to the Caps Lock key. This technique can be applied to any number of other features you want to be included in your AutoHotkey scripts.

In this case, we block the Caps Lock function in all cases except when the mouse cursor hovers over the Windows Taskbar. It is assumed that both the MouseIsOver() function and #If expression directive is already loaded as shown:

MouseIsOver(WinTitle) 
{
  MouseGetPos,,, Win
  Return WinExist(WinTitle . " ahk_id " . Win)
}
#If MouseIsOver("ahk_class Shell_TrayWnd")

The following code setups the Caps  Lock key for opening the Windows calculator whenever the mouse cursor hovers over the Windows Taskbar:

Hotkey, If, MouseIsOver("ahk_class Shell_TrayWnd")
  Hotkey, CapsLock, Calc 
Hotkey, If
Hotkey, CapsLock, Block
Calc:
  IfWinExist Calculator
     WinActivate Calculator
  Else 
     Run, calc
Return
Block:
Return

The first Hotkey, If (expression) command assigns all following Hotkeys to the MouseIsOver(“ahk_class Shell_TrayWnd”) condition (i.e. whenever the mouse cursor hovers over the Windows Taskbar). Then, the Hotkey command (under the same MouseIsOver() condition) assigns the Caps Lock key (CapsLock) the Label subroutine Calc. The last Hotkey, If command (no expression included) stops the assignment of Hotkeys to the MouseIsOver() condition. The final Hotkey command (Hotkey, CapsLock, Block) assigns the Label subroutine Block to all non-conditional Caps Lock key actions.

The only remaining code of concern are the two Label subroutines (Calc and Block). The Block subroutine does nothing by simply returning to the script. This effectively prevents the Caps Lock key from doing anything in all conditions except when the mouse cursor hovers over the Windows Taskbar. The Calc subroutine is a little more complicated.

How to Only Open Unopened Windows

The technique used in the Calc subroutine is commonly employed whenever you want to either activate an open program window or (if no open window exists) launch a new window. Initially, people tend to use only the Run command (e.g. Run, calc), launching a new instance of the program each time. However, opening a new window may be undesirable when one is already available. For example, if we include only the Run command:

Calc:
  Run, calc
Return

each time we press the Caps Lock key, a new Windows Calculator window launches. Generally, we only want the same, previously-used calculator window—if open. To protect against this redundant window launching, AutoHotkey first checks for an open calculator window with the IfWinExist command:

IfWinExist Calculator

then activates the window if it exists with the WinActivate command:

WinActivate Calculator

or (Else) launches the calculator app with the Run command if the window does not exist:

Else 
   Run, calc

Note: If only one line of code follows an If or Else statement, then additional curly brackets are not required. However, any additional command lines demand the inclusion of the curly brackets marking the beginning and end of the code:

  IfWinExist Calculator
    {
      WinActivate Calculator
      MsgBox, Calculator Activated!
    }
  Else 
    {
      Run, calc
      MsgBox, Calculator Loaded!
    }

Adding More Hotkey Options

Once understood, it’s easy to see how many different possibilities are available for alternative use of any Hotkey depending upon this mouse cursor hovering (or, for that matter, any other expression). The primary script change needed for adding more features is a new #If expression directive for each option. For example, if I want to add another Hotkey action for the Caps Lock key when the mouse hovers over an open Notepad window, then another #If expression directive must be added to the script:

#If MouseIsOver("ahk_class Notepad")

Caution: You might think that a variable could be used in place of the class callout in the #If expression directive, but that won’t work because later changing the value of that variable will affect all directive conditionals which use that same variable name, thus defeating the purpose of using a variable at all.

The above line of code presents a number of possibilities. Maybe pressing the Caps Lock Hotkey inserts boilerplate text into the editing window whenever the mouse cursor hovers over an open Notepad window? Or, perhaps you copied text from a Web page that you want to insert into one of the open Notepad windows by hovering and pressing Caps Lock? I’ll leave this one for you to figure out.

Hint: Use the MouseGetPos command to identify the window. To send text to an open, but inactive, window use the ControlSend command as discussed in “Chapter Eighteen” of the book Digging Deeper into AutoHotkey.

Next time, we look at some editing tricks.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s