Code: Select all
;MouseGesture:
m_GestureKey = RButton ; Gesture key.
m_GestureKey2 = ; Alternate gesture key.
m_Interval = 20 ; How long to sleep between each iteration of the gesture-recognition loop.
m_LowThreshold = 50 ; Minimum distance to register as a gesture "stroke."
m_HighThreshold = 0 ; Maximum total gesture length. Exceeding this cancels the gesture.
m_Timeout = 500 ; Maximum time in milliseconds between the last mouse movement and release of the gesture key/button.
m_InitialTimeout = 250 ; Maximum time in milliseconds that the mouse can remain in its initial position before gesture-recognition is cancelled. This makes it easier to click and drag with the gesture button.
m_ActiveTimeout = 0 ; Maximum time in milliseconds that the mouse can remain in any one position before gesture-recognition is cancelled. 0 means forever.
m_ActiveTimeoutMode = 0 ; 0: cancel. 1: cancel & perform default action. 2: complete gesture.
m_DefaultOnTimeout = 0 ; If true, default action is performed whenever m_Timeout is applied.
m_Tolerance = 100 ; Maximum percent of deviance from "zone center" that will be tolerated. If there are 4 zones, 100 percent = 45 degrees.
m_ZoneCount = 4 ; The number of zones.
m_InitialZoneCount = ; If set, defines the number of zones allowed for the *first* stroke.
m_DisableDing = 0
m_GesturePrefix = Gesture ; Default prefix for gesture variables/labels.
m_KeylessPrefix = ; Prefix for keyless gestures, or blank to disable.
m_Delimiter = _
m_EnabledIcon =
m_DisabledIcon =
m_EnabledSound =
m_DisabledSound =
m_PenWidth = 3 ; Width of the pen to draw trails with.
m_NodePenWidth = ; Radius of "nodes" on the trails, indicating where each stroke begins.
m_PenColor = 00FF00 ; Colour of trails and nodes. http://www.autohotkey.com/docs/commands/Progress.htm#colors
m_TransTrail = 1 ; Make trail window transparent (recommended if DWM/Aero theme is enabled).
;Basic global init
#NoEnv
#SingleInstance Force ; Never allow more than one instance of this script.
CoordMode, Mouse, Screen ; Let mouse commands use absolute/screen co-ordinates.
SendMode Input ; Set recommended send-mode.
SetTitleMatchMode, 2 ; Match anywhere in window title.
SetWorkingDir %A_ScriptDir% ; Set working directory to script's directory for consistency.
SetBatchLines, -1 ; May improve responsiveness. Shouldn't negatively affect other apps as the script sleeps every %m_Interval% ms while active.
;Set text labels to be used in other areas
; Zone labels used when four zones are active:
c_Zone4_0 = R
c_Zone4_1 = D
c_Zone4_2 = L
c_Zone4_3 = U
; Zone labels used when eight zones are active:
c_Zone8_0 = R
c_Zone8_1 = DR
c_Zone8_2 = D
c_Zone8_3 = DL
c_Zone8_4 = L
c_Zone8_5 = UL
c_Zone8_6 = U
c_Zone8_7 = UR
/*
* Load configuration
*/
; Run "auto-execute" sections of "Define gesture", in that order.
gosub DefaultGestures
gosub Gestures
/*
* Initialize script - don't mess with this unless you know what you're doing
*/
G_SetTrayIcon(true) ; Set custom tray icon (also called by ToggleGestureSuspend).
; Hook "Suspend Hotkeys" messages to update the tray icon.
; Note: This has the odd side-effect of "disabling" the tray menu
; if the script is paused from the tray menu.
OnMessage(0x111, "WM_COMMAND")
; Set tooltip for tray icon.
Menu, Tray, Tip, Mouse Gestures
; Setup custom tray menu.
Menu, Tray, NoStandard
Menu, Tray, Add, &Open , TrayMenu_Open
Menu, Tray, Add, &Help , TrayMenu_Help
Menu, Tray, Add
Menu, Tray, Add, &Reload , TrayMenu_Reload
Menu, Tray, Add, &Suspend , TrayMenu_Suspend
Menu, Tray, Add
Menu, Tray, Add, Edit &Gestures.ahk , TrayMenu_Edit
Menu, Tray, Add, Edit Gestures_&Default.ahk , TrayMenu_Edit
Menu, Tray, Add, Edit Gestures_&User.ahk , TrayMenu_Edit
Menu, Tray, Add
Menu, Tray, Add, E&xit , TrayMenu_Exit
Menu, Tray, Default, &Open
; Create a group for easy identification of Windows Explorer windows.
GroupAdd, Explorer, ahk_class CabinetWClass
GroupAdd, Explorer, ahk_class ExploreWClass
; Some code relies on m_InitialZoneCount being set.
if m_InitialZoneCount < 2
m_InitialZoneCount := m_ZoneCount
; The following are relied on by the script and should not be changed:
c_PI := 3.141592653589793, c_Degrees := 180/c_PI
m_WaitForRelease := false ; Are we waiting for the gesture key to be released? Not yet.
m_PassKeyUp := false ; Should GestureKey_Up pass key-release to the active window? Not yet.
m_ClosingWindow := 0 ; We aren't about to close any window.
; Set up the canvas for mouse-trails, if configured.
if m_PenWidth
{
; Set default trail colour or convert RRGGBB to 0xBBGGRR.
if m_PenColor =
m_PenColor := 0
else
m_PenColor := "0x" . SubStr(m_PenColor,5,2) . SubStr(m_PenColor,3,2) . SubStr(m_PenColor,1,2)
m_PenColor &= 0xffffff
; Use any other colour as the trail-Gui background.
m_TransColor := m_PenColor ? "000000" : "FFFFFF"
; Create the Gui if not already created, and set it as the Last Found Window.
Gui, +LastFound
if m_TransTrail
{
; Make the Gui background transparent.
Gui, Color, %m_TransColor%
WinSet, TransColor, %m_TransColor%
}
else
{
; Prevent the GUI background from being painted, giving the illusion of transparency.
OnMessage(0x14, "G_DisableEraseBkgnd")
G_DisableEraseBkgnd() {
return 1
}
}
; Remove the caption and borders, and hide the Gui from the taskbar.
Gui, -Caption +ToolWindow +AlwaysOnTop
; Get the HWND and HDC of the Last Found Window (the Gui).
hw_canvas := WinExist()
hdc_canvas := DllCall("GetDC", "uint", hw_canvas)
; Create the pen, if not already created.
pen := DllCall("CreatePen", "int", 0, "int", m_PenWidth, "uint", m_PenColor)
; Select the pen and store a handle to the previously selected pen (common GDI practice).
old_pen := DllCall("SelectObject", "uint", hdc_canvas, "uint", pen)
; Create a brush for erasing the Gui background.
brush := DllCall("CreateSolidBrush", "uint", "0x" m_TransColor)
brush2 := DllCall("CreateSolidBrush", "uint", m_PenColor)
old_brush := DllCall("SelectObject", "uint", hdc_canvas, "uint", brush2)
}
; Register hotkeys.
Hotkey, %m_GestureKey%, GestureKey_Down
Hotkey, #%m_GestureKey%, ToggleGestureSuspend
if m_GestureKey2 {
Hotkey, %m_GestureKey2%, GestureKey_Down
Hotkey, #%m_GestureKey2%, ToggleGestureSuspend
}
SoundPlay, %m_EnabledSound%
if m_KeylessPrefix {
if !m_ActiveTimeout
if m_Timeout
m_ActiveTimeout := m_Timeout
else
m_ActiveTimeout := 1000
SetTimer, GestureKeyless, %m_Interval% ; Won't run while in the gesture recognition loop.
}
/*
* END OF INIT SECTION
*/
return
; ↓ Define gestures ↓
DefaultGestures: ; Init section for default gestures.
; Default_D_R never closes these windows:
GroupAdd, CloseBlacklist, ahk_class Progman ; Desktop
GroupAdd, CloseBlacklist, ahk_class Shell_TrayWnd ; Taskbar
return
Default_L: ;Browser_Back or Undo
SetTitleMatchMode, RegEx
if ( WinActive("ahk_group ^Explorer$") OR WinActive("XYplorer ahk_class ThunderRT6FormDC"))
Sendinput !{Left}
else if WinActive("- (Microsoft )?Visual C\+\+")
Sendinput ^-
else if WinActive("ahk_class ^#32770$") && G_ControlExist("SHELLDLL_DefView1") ; Possibly a File dialog, so try sending "Back" command.
SendMessage, 0x111, 0xA00B ; WM_COMMAND, ID
else if ( WinActive("Word") OR WinActive("Excel") OR WinActive("Microsoft"))
Sendplay, ^z
else if( WinActive("ahk_class MediaPlayerClassicW"))
Sendinput {Media_Prev}
else
Sendinput {Browser_Back}
return
Default_R: ;Browser_Forward or Redo
SetTitleMatchMode, RegEx
if ( WinActive("ahk_group ^Explorer$") OR WinActive("XYplorer ahk_class ThunderRT6FormDC") )
Sendinput !{Right}
else if WinActive("- (Microsoft )?Visual C\+\+")
Sendinput ^+-
else if ( WinActive("Word ahk_class OpusApp") OR WinActive("Excel ahk_class XLMAIN") OR WinActive("Microsoft"))
Sendplay, ^y
else if( WinActive("ahk_class MediaPlayerClassicW"))
Sendinput {Media_Next}
else
Sendinput {Browser_Forward}
return
; Close Application (or Firefox tab) - down, then right
Default_D_R:
ifWinNotActive, ahk_group CloseBlacklist
{
MouseGetPos, x, y, hWnd
PostMessage, 0x112, 0xF060,,, ahk_id %hWnd% ; 0x112 = WM_SYSCOMMAND, 0xF060 = SC_CLOSE
}
return
;Default_R_D_L_U: ; Reload the Script.
Default_L_D_R_U: ; Edit script/config.
; Menu, EditFile, Add, Edit &Gestures.ahk , TrayMenu_Edit
; Menu, EditFile, Add, Edit Gestures_&Default.ahk , TrayMenu_Edit
; Menu, EditFile, Add, Edit Gestures_&User.ahk , TrayMenu_Edit
; Menu, EditFile, Show
; Menu, EditFile, Delete
;return
Default_D: ; Minimize
;G_MinimizeActiveWindow() ;Normal minimize
settitlematchmode, 2
ifwinactive, Outlook ahk_class rctrl_renwnd32
WinMinimize
else
ifwinactive, ahk_class BaseWindow_RootWnd
{
Sendinput {Shift Down}{Alt Down}m
sleep 500
Sendinput {Shift Up}{Alt Up}
}
else
run WinmintoTray.ahk
return
Default_U: ; Toggle Maximize
WinGet MX, MinMax, A
If MX
WinRestore A
Else WinMaximize A
return
Default_R_L: ; Toggle Maximize
Tooltip, Reloading...
run script.ahk
return
Default_L_R: ;Reload
Tooltip, Reloading...
sleep 200
Reload
return
; Toggle Maximize:
;WinGet MX, MinMax, A
;If MX
; WinRestore A
; Else WinMaximize A
; return
Default_L_D_U:
Default_U_L_D_U: ; <-- compensate for bad habit
if WinExist(G_GetLastMinimizedWindow())
PostMessage, 0x112, 0xF120
return
Default_R_L_R_L:
Default_L_R_L_R:
; WinActive("A")
; WinGet, mm, MinMax
; if mm
; SendMessage, 0x112, 0xF120 ; WM_SYSCOMMAND, SC_RESTORE
; PostMessage, 0x112, 0xF010 ; WM_SYSCOMMAND, SC_MOVE
; Sendinput {Left}{Right}
return
Gestures: ;User-defined gestures
Gesture_WheelUp = ^{Tab} ;Modifier key + WheelUp = Ctrl Tab
Gesture_WheelDown = ^+{Tab}
return
/*
* Tray menu subroutines
*/
TrayMenu_Open:
DetectHiddenWindows, On
Process, Exist
PostMessage, 0x111, 65300,,, ahk_class AutoHotkey ahk_pid %ErrorLevel%
return
TrayMenu_Help:
MsgBox, Sorry, feature not implemented!
return
TrayMenu_Reload:
Reload
return
TrayMenu_Suspend:
gosub ToggleGestureSuspend
return
TrayMenu_Edit:
G_EditFile(A_ScriptDir "\" RegExReplace(A_ThisMenuItem,"^Edit |&"))
return
TrayMenu_Exit:
ExitApp
/*
* Gesture recognition and hotkeys
*/
ToggleGestureSuspend:
Suspend, Toggle
G_SetTrayIcon(!A_IsSuspended)
if A_IsSuspended {
Menu, Tray, Check, &Suspend
SoundPlay, %m_DisabledSound%
} else {
Menu, Tray, Uncheck, &Suspend
SoundPlay, %m_EnabledSound%
}
return
CancelGesture:
Hotkey, *Escape, CancelGesture, Off
m_ExitLoop := true
return
GestureKey_Up:
Hotkey, %A_ThisHotkey%, Off
MouseGetPos, m_EndX, m_EndY
G_ExitGesture()
if m_PassKeyUp
{
Sendinput {Blind}{%m_LastGestureKey% Up}
m_PassKeyUp := false
}
return
GestureKey_Down:
if m_WaitForRelease && m_LastGestureKey ; Key pressed while loop was running for the other key.
return
Thread, NoTimers ; Disable keyless timer for the duration of this subroutine.
m_LastGestureKey := A_ThisHotkey
Hotkey, *%m_LastGestureKey% Up, GestureKey_Up, On
Hotkey, *Escape, CancelGesture, On
if (%m_GesturePrefix%_WheelUp!="" || IsLabel(m_GesturePrefix "_WheelUp"))
Hotkey, *WheelUp, GestureWheelUp, On
if (%m_GesturePrefix%_WheelDown!="" || IsLabel(m_GesturePrefix "_WheelDown"))
Hotkey, *WheelDown, GestureWheelDown, On
GestureKeyless:
; If the keyless timer started this thread, the gesture loop mustn't be active since
; a) the keyed entry-point above disables timers and b) no timer can execute its
; subroutine again until the previous instance returns. We don't want to register
; any hotkeys since they wouldn't work intuitively with the keyless method.
; Increase interval between message checks so that any interruption will happen during
; 'Sleep' rather than at any random point. Interruption happens if a keyless loop
; is running when the user presses a gesture key; when it happens, we want to recognize
; the "explicit" gesture and exit the keyless loop's thread as soon as it resumes.
; This must be done because of the use of global variables in the gesture loop.
if A_ThisLabel=GestureKeyless
{
Critical % 100+m_Interval ; Add m_Interval in case it is reasonably high/long.
m_LastGestureKey := ""
}
m_WaitForRelease := true ; Legacy naming: true while running the loop (even if its not really waiting for key-up).
m_ExitLoop := false ; Only overridden by scrolling/pressing Escape.
m_ScrolledWheel := false ;
beginTimeout := A_TickCount
startX := -1
startY := -1
totalDistance := 0
lastZone := -1
m_Gesture := ""
m_GestureLength := 0
; get starting mouse position
MouseGetPos, lastX, lastY
; record for later use
m_EndX := m_StartX := lastX
m_EndY := m_StartY := lastY
if hdc_canvas && m_LastGestureKey
{
SysGet, XVirtualScreen, 76
SysGet, YVirtualScreen, 77
SysGet, CXVirtualScreen, 78
SysGet, CYVirtualScreen, 79
; Set origin to top-left of primary screen (since mouse co-ords are relative to this).
DllCall("SetViewportOrgEx", "uint", hdc_canvas, "int", -XVirtualScreen, "int", -YVirtualScreen, "uint", 0)
; Show the trail canvas over the entire virtual screen (all monitors).
Gui, Show, X-30000 Y-30000 W%CXVirtualScreen% H%CYVirtualScreen% NA
; Showing the Gui initially off-screen may help reduce "screen flash".
Gui, Show, X%XVirtualScreen% Y%YVirtualScreen% NA
; Set the initial position, where the first line will begin.
DllCall("MoveToEx", "uint", hdc_canvas, "int", m_StartX, "int", m_StartY, "uint", 0)
}
Loop
{
; Logic below requires that only keyless mode enables 'Critical'.
if (A_ThisLabel="GestureKeyless" && m_wasCritical := A_IsCritical)
Critical Off ; Allow interruption temporarily.
; wait for mouse to move
Sleep, m_Interval
if (A_ThisLabel="GestureKeyless" && m_wasCritical)
{ ; If a gesture key was pressed, the globals this instance was using
; have probably been overwritten, so just break out of the loop.
if m_LastGestureKey
return
Critical %m_wasCritical%
}
if m_ExitLoop
{
if m_ScrolledWheel
KeyWait, %m_LastGestureKey%
G_ExitGesture()
return
}
if !m_WaitForRelease
{ ; use location mouse was released at
x := m_EndX
y := m_EndY
}
else ; get current mouse position
MouseGetPos, x, y
offsetX := x - lastX
offsetY := y - lastY
; Check if mouse has moved.
if (offsetX!=0 || offsetY!=0)
{
if hdc_canvas
; Draw a line to the current mouse position, from the starting position or end of the previous line.
DllCall("LineTo", "uint", hdc_canvas, "int", x, "int", y)
; Calculate distance and angle from origin.
; Note origin changes only when a new stroke is detected, so distance will continue
; to increase while the mouse contiues to move in the same approximate direction.
distance := Sqrt(offsetX*offsetX + offsetY*offsetY)
if (distance > m_LowThreshold)
{
angle := G_GetAngle(offsetX, offsetY)
lastX := x
lastY := y
; Allow the initial stroke to be more or less specific than subsequent strokes,
; ensuring the initial stroke can be extended according to m_InitialZoneCount.
if ( m_GestureLength = 0
|| m_GestureLength = 1 && G_GetZone(angle, m_InitialZoneCount, m_Tolerance) = lastZone )
zoneCount := m_InitialZoneCount
else zoneCount := m_ZoneCount
zone := G_GetZone(angle, zoneCount, m_Tolerance)
if zone =
{
; Error, or gesture stroke exceeded zone tolerance (m_Tolerance).
if !m_DisableDing
SoundPlay, *-1
G_ExitGesture()
return
}
if (lastZone != zone)
{
if (hdc_canvas && m_NodePenWidth && lastZone != zone && lastZone != -1)
DllCall( "Ellipse", "uint", hdc_canvas
, "int", lastZoneEndX-m_NodePenWidth
, "int", lastZoneEndY-m_NodePenWidth
, "int", lastZoneEndX+m_NodePenWidth
, "int", lastZoneEndY+m_NodePenWidth )
; Record length of this stroke.
totalDistance := distance
; Remember zone index for subsequent iterations.
lastZone := zone
; Record this stroke.
m_Gesture .= m_Delimiter . zone
m_GestureLength += 1
}
else
{
; Extend length of this stroke.
totalDistance += distance
}
; Reset timeout.
beginTimeout := A_TickCount
lastZoneEndX := x
lastZoneEndY := y
if (m_HighThreshold > 0 && totalDistance > m_HighThreshold)
{
; Gesture stroke exceeded maximum stroke length (m_HighThreshold).
if !m_DisableDing
SoundPlay, *-1
G_ExitGesture()
Sleep, 150
if !m_DisableDing
SoundPlay, *-1
return
}
}
}
timeout := m_Gesture="" ? m_InitialTimeout : m_ActiveTimeout
if (timeout && A_TickCount-beginTimeout > timeout)
{
; Timed out.
if (m_Gesture!="" && (m_ActiveTimeoutMode=2 || !m_LastGestureKey))
{
; Complete gesture. Circumvent m_Timeout.
beginTimeout := A_TickCount
m_WaitForRelease := false
break
}
if !m_DisableDing && m_LastGestureKey
SoundPlay, *64
; G_ExitGesture attempts default function of gesture key if the first parameter is true.
G_ExitGesture(m_Gesture="" || m_ActiveTimeoutMode=1)
return
}
; End loop when gesture key is released.
if !m_WaitForRelease
break
}
; Cancel gesture if the mouse was immobile for too long after the last stroke.
if (m_Timeout && A_TickCount-beginTimeout > m_Timeout)
{
; Gesture timed out.
if !m_DisableDing && m_LastGestureKey
SoundPlay, *64
G_ExitGesture(m_DefaultOnTimeout && m_LastGestureKey)
return
}
if m_Gesture !=
{
if !G_PerformAction(m_Gesture) && !m_DisableDing && m_LastGestureKey
SoundPlay, *48
}
else
G_ExitGesture(true)
return
GestureWheelUp:
GestureWheelDown:
m_ScrolledWheel := true
m_ExitLoop := true
G_PerformAction(m_Delimiter . SubStr(A_ThisLabel,8))
return
G_PerformAction(action_name)
{
local action, params, final_name
, list := m_LastGestureKey ? m_GesturePrefix ",Default" : m_KeylessPrefix
Loop, Parse, list, `,
{
final_name = %A_LoopField%%action_name%
if IsLabel(final_name)
gosub % final_name
else if %final_name% !=
Sendinput % %final_name%
else
continue
return true
}
return false
}
G_ExitGesture(sendkey=false)
{
local btn
Hotkey, *Escape, CancelGesture, Off
Hotkey, *WheelUp, GestureWheelUp, Off
Hotkey, *WheelDown, GestureWheelDown, Off
if hdc_canvas ; Hide the mouse-trail canvas.
{
if m_TransTrail
{
; Clear the canvas before hiding it. Otherwise, the next time the window is shown,
; the previous gesture can be shown for a brief moment before the window updates.
VarSetCapacity(rect, 16, 0)
NumPut(CYVirtualScreen + YVirtualScreen, NumPut(CXVirtualScreen + XVirtualScreen
, NumPut(YVirtualScreen, NumPut(XVirtualScreen, rect, 0))))
DllCall("FillRect", "uint", hdc_canvas, "int", &rect, "uint", brush)
}
Gui, Hide
}
if !(sendkey && m_LastGestureKey)
{
m_WaitForRelease := false
return
}
if m_LastGestureKey in LButton,MButton,RButton
{
; Try to leave mouse button functionality intact.
StringLeft, btn, m_LastGestureKey, 1
if m_WaitForRelease
MouseGetPos, m_EndX, m_EndY
; Move to point where gesture started, then press and hold button.
MouseClick, %btn%, m_StartX, m_StartY,, 1, D
; Move back into place. Release if button has been physically released.
if m_WaitForRelease
MouseMove, m_EndX, m_EndY
else
MouseClick, %btn%, m_EndX, m_EndY,,, U
}
else
{
if m_WaitForRelease
Sendinput {Blind}{%m_LastGestureKey% Down}
else
Sendinput {Blind}{%m_LastGestureKey%}
}
; Pass through gesture button release to active window if applicable.
m_PassKeyUp := m_WaitForRelease
m_WaitForRelease := false
}
; Get angle (in degrees) of {x,y} relative to {0,0} -> {1,0}.
G_GetAngle(x, y)
{
if (x != 0) {
deg := ATan(y/x) * 57.295779513082323 ; deg := rad * 180/PI
if x < 0
return deg + 180
else ; x > 0
if y < 0
return deg + 360
; x > 0 && y >= 0
return deg
} else ; x = 0
if y > 0
return 90.0
else if y < 0
return 270.0 ;-90
; else no return value.
}
; Get the zone of an angle
; angle: Angle in degrees, between 0.0 and 360.0 inclusive.
; zoneCount: Number of zones.
; tolerance: Allowed deviance from centre of zone.
; If positive, specifies percentage of zone (between 1 and 100).
; If negative, absolute value specifies tolerance in degrees.
G_GetZone(angle, zoneCount, tolerance)
{
local degPerZone
local zone
if zoneCount < 2
return ; ERROR.
; Calculate zone size.
degPerZone := 360/zoneCount
; Calculate nearest zone integer.
zone := Mod(Round(angle/degPerZone),zoneCount)
; Calculate tolerance.
if tolerance < 0
tolerance := Abs(tolerance) ; -n : must not exceed n degrees.
else
tolerance := degPerZone/2 * tolerance/100 ; n : must not exceed n percent.
if (zone = 0 && angle > 180)
angle -= 360
; Check if within tolerated distance from centre of zone.
if (Abs(angle-(zone*degPerZone)) > tolerance)
return
; Resolve to text form if available.
if c_Zone%zoneCount%_%zone% !=
return c_Zone%zoneCount%_%zone%
return zone
}
/*
* Tray icon maintenance
*/
G_SetTrayIcon(is_enabled)
{
local icon := is_enabled ? m_EnabledIcon : m_DisabledIcon
if icon !=
{
ifExist, %icon%
Menu, Tray, Icon, %icon%,, 1
else Menu, Tray, Icon, *
Menu, Tray, Icon
}
else
Menu, Tray, NoIcon
%m_OnUpdateIcon%(icon, is_enabled)
}
WM_COMMAND(wParam, lParam, msg, hwnd)
{
static IsPaused, IsSuspended
Critical
id := wParam & 0xFFFF
if id in 65305,65404,65306,65403
{ ; "Suspend Hotkeys" or "Pause Script" - either A_IsPaused or A_IsSuspended is about to be toggled.
if id in 65306,65403
IsPaused := ! A_IsPaused
else
IsSuspended := ! A_IsSuspended
G_SetTrayIcon(!(IsPaused or IsSuspended))
}
}
/*
* Helper functions
*/
G_EditFile(file)
{
Run edit %file%,, UseErrorLevel
if ErrorLevel = ERROR
Run, notepad "%file%"
}
G_MinimizeActiveWindow()
{
global
lastMinTime := A_TickCount
lastMinID := WinExist("A")
; unlike WinMinimize, using WM_SYSCOMMAND, SC_MINIMIZE
; causes the system-wide "Minimize" sound to be played
PostMessage, 0x112, 0xF020
}
G_GetLastMinimizedWindow()
{
WinGet, w, List
Loop %w%
{
wi := w%A_Index%
WinGet, m, MinMax, ahk_id %wi%
if m = -1 ; minimized
{
lastFound := wi
break
}
}
return "ahk_id " . (lastFound ? lastFound : 0)
}
G_ControlExist(Control, WinTitle="")
{
ControlGet, temp, HWND, , %Control%, %WinTitle%
return temp
}
Save as *.ahk, then download and open this .ahk file with http://ahkscript.org/download/
Hold down Right mouse and drag left = Alt+Left (which is assign as "go back" to XYplorer)
Hold down Right mouse and drag right = Alt+Right...
This script can manipulates all kind of window, not just XYplorer, example:
Code: Select all
else if( WinActive("ahk_class MediaPlayerClassicW"))
Sendinput {Media_Next}
You can change various settings in the first few lines of the script.
Actions are defined below these lines:
Default_L
Default_R
Default_D_R
...
^ means Ctrl
! means Alt
+ means Shift
(If you don't want to modify this script, then use the pre-compiled script I attached below)