Hi All,
I communicated with Lexikos and helped me fiddle with this script enough to get the autoraise to work on my Win 7 64 bit taskbar and windows orb. The hover any window still works too, but he said that the hover min max works intermittently and couldn't be updated (I would remove it from the script, but I don't know how without breaking the whole thing). I don't know if it works on grouped buttons, because I don't group my buttons.
#Persistent
hover_task_buttons = 1 ; hover over taskbar button to activate window
hover_task_group = 0 ; hover to select (or exit) from a window-group menu
; (for Windows' "Group similar taskbar buttons" feature)
hover_task_min_info = 0 ; only show info for minimized windows, don't activate
hover_start_button = 1 ; hover over start button to open start menu
hover_min_max = 0 ; minimize or maximize by hovering over the min/max buttons
hover_any_window = 1 ; activate any window by hovering (except the taskbar)
hover_no_buttons = 1 ; ignore hover if a mouse button is in the down state
hover_delay = 200 ; hover delay, from when the mouse stops moving
; WORKS, BUT NOT PERFECTLY: (brings the window forward, then puts it back in place)
hover_keep_zorder = 0 ; don't bring windows forward, only activate them
;
; DisableHover - since menus aren't usually truly "activated", if any
; window in the DisableHover group *EXISTS*, hover will be ignored.
;
GroupAdd, DisableHover, ahk_class #32768
; I'm not certain whether this class is used only for menus;
; if not, you may need to comment out this line.
GroupAdd, DisableHover, ahk_class MozillaDropShadowWindowClass
CoordMode, Mouse, Screen
SetTimer, hovercheck, 10
return
; Don't consider it hovering if the mouse was clicked.
; However, clicking and then moving a small amount will still trigger hover.
~LButton::
~RButton::
~MButton::
MouseGetPos, lastx, lasty
return
hovercheck:
MouseGetPos, x, y
if (x != lastx or y != lasty)
{
SetTimer, hovering, % -hover_delay
lastx := x
lasty := y
if (remove_ttip_on_move)
{
ToolTip
remove_ttip_on_move := false
}
}
return
hovering:
if (hover_no_buttons && (GetKeyState("LButton") or GetKeyState("RButton")))
return
if (WinExist("ahk_group DisableHover"))
return
; hover over taskbar button to activate window:
if (hover_task_buttons)
{
MouseGetPos,,, win, ctl
if (ctl="MSTaskListWClass1") {
Click
return
}
}
; hover over start button to open start menu:
if (hover_start_button && !WinActive("ahk_class DV2ControlHost")) ; Start Menu
{
MouseGetPos,,, win, ctl
WinGetTitle, ti, ahk_id %win%
WinGetClass, cl, ahk_id %win%
if (A_OSVersion = "WIN_7" && (cl = "Button" && ti = "Start"))
or (cl = "Shell_TrayWnd" && ctl = "Button1")
{
Click
return
}
}
; hover over minimize, maximize or help buttons on titlebar:
if (hover_min_max)
{
MouseGetPos, x, y, win, ctl, 2
SendMessage, 0x84,, (x & 0xFFFF) | (y & 0xFFFF) << 16,, % "ahk_id " (ctl ? ctl : win)
if ErrorLevel in 8,9 ; min,max (titlebar)
{
Click
return
}
}
; hover over any window to focus:
if (hover_any_window)
{
ifWinExist, ahk_id %win% ahk_class Shell_TrayWnd
return ; don't activate the taskbar
MouseGetPos,,, win
if (!WinActive("ahk_id " win)) {
if (hover_keep_zorder)
JustActivate(win)
else
WinActivate, ahk_id %win%
}
}
return
JustActivate(hwnd)
{
if (WinActive("ahk_id " hwnd))
return
; Get the window which hwnd is positioned after, so hwnd's position
; in the z-order can be restored after activation.
hwnd_prev := GetPrevWindow(hwnd)
; DllCall("GetWindow","uint",hwnd,"uint",3) would be simpler,
; but doesn't work right since it usually gets an invisible window
; which moves when we activate hwnd.
; Repositioning a window in the z-order sometimes sets AlwaysOnTop.
WinGet, OldExStyle, ExStyle, ahk_id %hwnd%
;WinActivate, ahk_id %hwnd% ; -- best to use SetWinDelay,-1 if using WinActivate.
DllCall("SetForegroundWindow", "uint", hwnd)
DllCall("SetWindowPos", "uint", hwnd, "uint", hwnd_prev
, "int", 0, "int", 0, "int", 0, "int", 0
, "uint", 0x13) ; NOSIZE|NOMOVE|NOACTIVATE (0x1|0x2|0x10)
; Note NOACTIVATE above: if this is not specified, SetWindowPos activates
; the window, bringing it forward (effectively ignoring hwnd_prev...)
; Check if AlwaysOnTop status changed.
WinGet, ExStyle, ExStyle, ahk_id %hwnd%
if (OldExStyle ^ ExStyle) & 0x8
WinSet, AlwaysOnTop, Toggle
}
; Like GetWindow(hwnd, GW_HWNDPREV), but ignores invisible windows.
GetPrevWindow(hwnd)
{
global GetPrevWindow_RetVal
static cb_EnumChildProc
if (!cb_EnumChildProc)
cb_EnumChildProc := RegisterCallback("GetPrevWindow_EnumChildProc","F")
; Set default in case enumeration fails.
GetPrevWindow_RetVal := DllCall("GetWindow", "uint", hwnd, "uint", 3)
; Enumerate all siblings of hwnd.
hwnd_parent := DllCall("GetParent", "uint", hwnd)
DllCall("EnumChildWindows", "uint", hwnd_parent, "uint", cb_EnumChildProc, "uint", hwnd)
; Return the last visible window before hwnd.
return GetPrevWindow_RetVal
}
GetPrevWindow_EnumChildProc(test_hwnd, hwnd)
{
global GetPrevWindow_RetVal
; Continue until hwnd is enumerated.
if (test_hwnd = hwnd)
return false
; Remember the last visible window before hwnd.
if (DllCall("IsWindowVisible", "uint", test_hwnd))
GetPrevWindow_RetVal := test_hwnd
return true
}
; Gets the index+1 of the taskbar button which the mouse is hovering over.
; Returns an empty string if the mouse is not over the taskbar's task toolbar.
;
; Some code and inspiration from Sean's TaskButton.ahk
GetMouseTaskButton(ByRef hwnd)
{
MouseGetPos, x, y, win, ctl, 2
; Check if hovering over taskbar.
WinGetClass, cl, ahk_id %win%
if (cl != "Shell_TrayWnd")
return
; Check if hovering over a Toolbar.
WinGetClass, cl, ahk_id %ctl%
if (cl != "ToolbarWindow32")
return
; Check if hovering over task-switching buttons (specific toolbar).
hParent := DllCall("GetParent", "Uint", ctl)
WinGetClass, cl, ahk_id %hParent%
if (cl != "MSTaskSwWClass")
return
WinGet, pidTaskbar, PID, ahk_class Shell_TrayWnd
hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
pRB := DllCall("VirtualAllocEx", "Uint", hProc
, "Uint", 0, "Uint", 20, "Uint", 0x1000, "Uint", 0x4)
VarSetCapacity(pt, 8, 0)
NumPut(x, pt, 0, "int")
NumPut(y, pt, 4, "int")
; Convert screen coords to toolbar-client-area coords.
DllCall("ScreenToClient", "uint", ctl, "uint", &pt)
; Write POINT into explorer.exe.
DllCall("WriteProcessMemory", "uint", hProc, "uint", pRB+0, "uint", &pt, "uint", 8, "uint", 0)
; SendMessage, 0x447,,,, ahk_id %ctl% ; TB_GETHOTITEM
SendMessage, 0x445, 0, pRB,, ahk_id %ctl% ; TB_HITTEST
btn_index := ErrorLevel
; Convert btn_index to a signed int, since result may be -1 if no 'hot' item.
if btn_index > 0x7FFFFFFF
btn_index := -(~btn_index) - 1
if (btn_index > -1)
{
; Get button info.
SendMessage, 0x417, btn_index, pRB,, ahk_id %ctl% ; TB_GETBUTTON
VarSetCapacity(btn, 20)
DllCall("ReadProcessMemory", "Uint", hProc
, "Uint", pRB, "Uint", &btn, "Uint", 20, "Uint", 0)
state := NumGet(btn, 8, "UChar") ; fsState
pdata := NumGet(btn, 12, "UInt") ; dwData
ret := DllCall("ReadProcessMemory", "Uint", hProc
, "Uint", pdata, "UintP", hwnd, "Uint", 4, "Uint", 0)
} else
hwnd = 0
DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pRB, "Uint", 0, "Uint", 0x8000)
DllCall("CloseHandle", "Uint", hProc)
; Negative values indicate seperator items. (abs(btn_index) is the index)
return btn_index > -1 ? btn_index+1 : 0
}