Code: Select all
#singleinstance force
OutputDebug DBGVIEWCLEAR
RunAsTask()
CoordMode, Mouse, Screen
;~ Gui, Add, Edit, w500 h400 hwndhText
;~ Gui, Show, x0 y0
return
~*WheelUp::
DoSwitch(1)
return
~*WheelDown::
DoSwitch(-1)
return
GuiClose:
ExitApp
DoSwitch(dir){
global hText
hwnd := WinExist("A")
;~ str := "hwnd: " hwnd "`n"
;~ str .= "IsWindowFullScreen: " IsWindowFullScreen(hwnd) "`n"
;~ str .= "`nMatching Windows: `n"
if (GetKeyState("LALT", "P")){
alternate_mode := 1
} else {
alternate_mode := 0
}
; Only proceeed if alternate mode is on or the mouse is at edge of screen
if ( !(alternate_mode || IsMouseAtEdgeOfMonitor()) )
return
windows := GetMatchingWindows(hwnd, alternate_mode)
windows := FilterWindowsOnThisMonitor(windows)
;windows := SortWindowsByHwnd(windows)
windows := SortWindowsByTitle(windows)
;~ Loop % windows.length(){
;~ WinGetTitle, title, % "ahk_id " windows[A_Index]
;~ WinGetPos, x, y, w, h, % "ahk_id " windows[A_Index]
;~ str .= windows[A_Index] " - " title " (x: " x ",y: " y ")`n"
;~ }
new_window := GetNextWindow(hwnd, windows, dir)
WinGetTitle, title, % "ahk_id " new_window
str .= "Switching to: " new_window " (" title ")`n"
OutputDebug % "AHK| " str
WinActivate, % "ahk_id " new_window
;~ GuiControl, , % hText, % str
}
; Returns true if the specified HWND is either fullscreen or maximized
IsWindowFullScreen( hwnd ) {
;checks if the specified window is full screen
If ( !WinExist("ahk_id " hwnd) )
Return false
WinGet style, Style, % "ahk_id " hwnd
if (style & 0x01000000)
return 1
WinGetPos ,,,winW,winH, % "ahk_id " hwnd
; 0x800000 is WS_BORDER.
; 0x20000000 is WS_MINIMIZE.
; no border and not minimized
Return (style & 0x20800000 || winH < A_ScreenHeight || winW < A_ScreenWidth) ? false : true
}
; Returns an array of HWNDs that "Match" the current window
; If alternate_mode is off, will only return windows of the same process name...
GetMatchingWindows(hwnd, alternate_mode := 0){
if (alternate_mode){
windows := []
WinGet, l, list
debug := 1
} else {
; Get Window Class and EXE
WinGet, ProcessName, ProcessName, % "ahk_id " hwnd
WinGetClass, cls, % "ahk_id " hwnd
; Get list of windows matching the Class and EXE
windows := []
WinGet, l, list, % "ahk_exe " ProcessName " ahk_class " cls
}
Loop, %l%
{
w := l%A_Index%
;if (alternate_mode || !alternate_mode && IsMouseAtEdgeOfMonitor()){
windows.push(w)
;}
}
return windows
}
; Filters a window array for only items on the same monitor as the mouse
FilterWindowsOnThisMonitor(windows){
ExcludeList := {"Program Manager": 1, "BBar": 1, "Sticky Notes": 1}
current_mon := WhichMonitorIsMouseOn()
;~ if (!current_mon)
;~ return
_windows := []
Loop % windows.length(){
WinGetTitle, title, % "ahk_id " windows[A_Index]
if (title && !ObjHasKey(ExcludeList, title) && IsWindowOnMonitor(windows[A_Index], current_mon)){
;WinGetPos, x, y, w, h, % "ahk_id " windows[A_Index]
;if (x >= monAreaLeft && x <= monAreaRight && y >= monAreaTop && y <= monAreaBottom){
_windows.push(windows[A_Index])
}
}
return _windows
}
; Decides if an individual window is on the same monitor as the mouse
IsWindowOnMonitor(hwnd, monitor){
WinGetPos, x, y, w, h, % "ahk_id " hwnd
mx := x + (w/2), my := y + (h/2)
SysGet, monArea, Monitor, % monitor
if (mx >= monAreaLeft && mx <= monAreaRight && my >= monAreaTop && my <= monAreaBottom){
return 1
}
return 0
}
; Finds the window after the current one in a windows array
GetNextWindow(hwnd, windows, dir){
; Find the current window in the list
this_index := 0
max := windows.length()
Loop % max {
if (windows[A_Index] == hwnd){
this_index := A_Index
break
}
}
if (!this_index)
return 0
found := 0
ct := 0
new_index := this_index
while (!found && (ct <= max)){
ct++
new_index += dir
if (new_index < 1)
new_index := max
if (new_index > max)
new_index := 1
if windows[new_index] is number {
;OutputDebug % "AHK| Found Window #" windows[new_index]
found := 1
}
}
if (found)
return windows[new_index]
else
return 0
}
; Sorts a windows array by HWND
SortWindowsByHwnd(array){
for k, v in array {
sorted .= v "`n"
}
StringTrimRight,sorted,sorted,1
Sort,sorted, D
out := []
Loop, Parse, sorted, `n
{
out.push(A_LoopField)
}
return out
}
; Sorts a windows array by Window Title
SortWindowsByTitle(array){
for k, v in array {
WinGetTitle, title, % "ahk_id " v
str := title "|ws|" v "`n"
;OutputDebug % "AHK| SortWindowsByTitle: " str
sorted .= str
}
StringTrimRight,sorted,sorted,1
Sort,sorted, D
out := []
Loop, Parse, sorted, `n
{
hwnd := StrSplit(A_LoopField, "|ws|")
hwnd := hwnd[2]
out.push(hwnd)
}
return out
}
; Is the mouse at the edge of the monitor?
IsMouseAtEdgeOfMonitor(){
MouseGetPos, mx, my
mon := WhichMonitorIsMouseOn()
SysGet, monArea, Monitor, % mon
if ( (mx >= monAreaLeft && mx <= monAreaLeft + 10) || (mx <= monAreaRight && mx >= monAreaRight - 10) || (my >= monAreaTop && my <= monAreaTop + 10) || (my <= monAreaBottom && my >= monAreaBottom - 10))
return 1
}
; Does the window encompass the mouse cursor?
DoesWindowEncompassMouse( hwnd ) {
WinGetPos ,winX,winY,winW,winH, % "ahk_id " hwnd
MouseGetPos, mX, mY
return ( (winX >= mX <= (winX + winW)) && (winY >= mY <= (winY + winH)) )
}
; Which monitor is the mouse on?
WhichMonitorIsMouseOn(){
MouseGetPos, mx, my
SysGet, mc, MonitorCount
Loop % mc {
SysGet, monArea, Monitor, % A_Index
if (mx >= monAreaLeft && mx <= monAreaRight && my >= monAreaTop && my <= monAreaBottom){
return A_Index
}
}
return 0
}
/*
_ _ _ __ __ _ _ _ _
| |__ | |_ | |_ _ __ _ / // /__ _ | |__ | | __ ___ ___ _ __ (_) _ __ | |_ ___ _ __ __ _
| '_ \ | __|| __|| '_ \(_) / // // _` || '_ \ | |/ // __| / __|| '__|| || '_ \ | __| / _ \ | '__|/ _` |
| | | || |_ | |_ | |_) |_ / // /| (_| || | | || < \__ \| (__ | | | || |_) || |_ _| (_) || | | (_| |
|_| |_| \__| \__|| .__/(_)_//_/ \__,_||_| |_||_|\_\|___/ \___||_| |_|| .__/ \__|(_)\___/ |_| \__, |
|_| |_| |___/
RunAsTask() - Auto-elevates script without UAC prompt | http://ahkscript.org/boards/viewtopic.php?t=4334
_________________________________________________________________________________________________________
*/
RunAsTask() { ; By SKAN, http://goo.gl/yG6A1F, CD:19/Aug/2014 | MD:22/Aug/2014
Local CmdLine, TaskName, TaskExists, XML, TaskSchd, TaskRoot, RunAsTask
Local TASK_CREATE := 0x2, TASK_LOGON_INTERACTIVE_TOKEN := 3
Try TaskSchd := ComObjCreate( "Schedule.Service" ), TaskSchd.Connect()
, TaskRoot := TaskSchd.GetFolder( "\" )
Catch
Return "", ErrorLevel := 1
CmdLine := ( A_IsCompiled ? "" : """" A_AhkPath """" ) A_Space ( """" A_ScriptFullpath """" )
TaskName := "[RunAsTask] " A_ScriptName " @" SubStr( "000000000" DllCall( "NTDLL\RtlComputeCrc32"
, "Int",0, "WStr",CmdLine, "UInt",StrLen( CmdLine ) * 2, "UInt" ), -9 )
Try RunAsTask := TaskRoot.GetTask( TaskName )
TaskExists := ! A_LastError
If ( not A_IsAdmin and TaskExists ) {
RunAsTask.Run( "" )
ExitApp
}
If ( not A_IsAdmin and not TaskExists ) {
Run *RunAs %CmdLine%, %A_ScriptDir%, UseErrorLevel
ExitApp
}
If ( A_IsAdmin and not TaskExists ) {
XML := "
( LTrim Join
<?xml version=""1.0"" ?><Task xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task""><Regi
strationInfo /><Triggers /><Principals><Principal id=""Author""><LogonType>InteractiveToken</LogonT
ype><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><MultipleInstancesPolic
y>Parallel</MultipleInstancesPolicy><DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries><
StopIfGoingOnBatteries>false</StopIfGoingOnBatteries><AllowHardTerminate>false</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable><RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAva
ilable><IdleSettings><StopOnIdleEnd>true</StopOnIdleEnd><RestartOnIdle>false</RestartOnIdle></IdleS
ettings><AllowStartOnDemand>true</AllowStartOnDemand><Enabled>true</Enabled><Hidden>false</Hidden><
RunOnlyIfIdle>false</RunOnlyIfIdle><DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteApp
Session><UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine><WakeToRun>false</WakeToRun><
ExecutionTimeLimit>PT0S</ExecutionTimeLimit></Settings><Actions Context=""Author""><Exec>
<Command>" ( A_IsCompiled ? A_ScriptFullpath : A_AhkPath ) "</Command>
<Arguments>" ( !A_IsCompiled ? """" A_ScriptFullpath """" : "" ) "</Arguments>
<WorkingDirectory>" A_ScriptDir "</WorkingDirectory></Exec></Actions></Task>
)"
TaskRoot.RegisterTask( TaskName, XML, TASK_CREATE, "", "", TASK_LOGON_INTERACTIVE_TOKEN )
}
Return TaskName, ErrorLevel := 0
} ; _____________________________________________________________________________________________________