Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Auto-raise / mouse hover


  • Please log in to reply
96 replies to this topic
..:: Free Radical ::..
  • Members
  • 74 posts
  • Last active: May 30 2015 12:13 PM
  • Joined: 20 Sep 2006

WinMinimizeAllUndo doesn't work on my comp, so Send #d is the more solid way to go.


Try this
PostMessage, 0x111, 416, 0,, ahk_class Shell_TrayWnd


CyricPL
  • Guests
  • Last active:
  • Joined: --
Not sure if this helps (as I don't fully understand this thread as a total noob :) ), but there is an actual keyboard shortcut for Aero Peek built into Win 7, #space.

But there does seem to be some problem with that. I tried this:

Capslock::#space

And while it does work perfectly fine, for some reason the Win key never releases when Caps Lock is released, so using that I'm stuck in Aero Peek until I Alt-Tab to another window.

MasterFocus
  • Moderators
  • 4323 posts
  • Last active: Jan 28 2016 01:38 AM
  • Joined: 08 Apr 2009

I tried this:

Capslock::#space

Try this:
Capslock::Send, #{SPACE}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Antonio Fran├ža -- git.io -- github.com -- ahk4.net -- sites.google.com -- ahkscript.org

Member of the AHK community since 08/Apr/2009. Moderator since mid-2012.


CyricPL
  • Members
  • 3 posts
  • Last active: Nov 06 2009 10:19 PM
  • Joined: 03 Nov 2009
Thanks, but that has the same result.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I'm also interested in getting this to work on windows 7.
I've investigated a bit, it seems that ToolbarWindow32 has been replaced with MSTaskListWClass, which doesn't seem to support the TB_HITTEST message.

That's about as far as I am though :(
I searched through msdn for a while, but only found stuff about how applications can use new features of the taskbar (jump lists, overlay icons etc).

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
fragman, MSTaskListWClass was already there, but as a parent of the ToolbarWindow32. Obviously the Windows 7 taskbar is far from a standard toolbar, so won't respond to standard toolbar messages anymore. There might be some other way to detect hover, such as detecting the thumbnail window which pops up (ahk_class TaskListThumbnailWnd). Figuring out which button is being hovered over would probably be much more difficult.

CyricPL,
*Capslock::
    Send {LWin down}{Space}
    KeyWait Capslock
    Send {LWin up}
return
(Not that it's directly relevant to this thread...)

CyricPL
  • Members
  • 3 posts
  • Last active: Nov 06 2009 10:19 PM
  • Joined: 03 Nov 2009
Lexikos,

Thank you so much for the help with that. I know it wasn't entirely relevant, I had only posted about the built-in shortcut since it seemed like people were trying to find a way to incorporate Aero Peek.

Anyway, thanks again. For real.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009

fragman, MSTaskListWClass was already there, but as a parent of the ToolbarWindow32. Obviously the Windows 7 taskbar is far from a standard toolbar, so won't respond to standard toolbar messages anymore. There might be some other way to detect hover, such as detecting the thumbnail window which pops up (ahk_class TaskListThumbnailWnd). Figuring out which button is being hovered over would probably be much more difficult.

CyricPL,

*Capslock::
    Send {LWin down}{Space}
    KeyWait Capslock
    Send {LWin up}
return
(Not that it's directly relevant to this thread...)


Oh good to know. Is there a tool that shows more detailed info than the windows spy utility that came with ahk?

It seems like there isn't any documentation from MS about detecting this kind of stuff, all they talk about is how to use the new UI features the taskbar offers.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Microsoft Active Accessibility can do it. Try accExplorer, for instance. See also ACC.ahk.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I wrote a script that is able to detect what type of control on the taskbar is clicked. It can differentiate between start button, single-window buttons, multi-window buttons, empty space on the taskbar, tray area, clock and show desktop button. I don't have support for quicklaunch integrated yet as I don't have it activated, if it's there it would probably break it but it should be easy to add support.
It can probably also be tweaked a bit to save some lines, but atleast it works ;)
I also have a function in there that enables the first window of a multibutton when you click it, instead of activating the thumbnail windows which already activate by hovering, uncomment it if you want to.
;Register a shell hook to get messages when windows get activated, closed etc
Gui +LastFound 
hWnd := WinExist() 
DllCall( "RegisterShellHookWindow", UInt,hWnd ) 
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" ) 
OnMessage( MsgNum, "ShellMessage" ) 

TaskbarClicked()
{
	ControlGetPos , TrayX, , TrayWidth, , ToolbarWindow321, ahk_class Shell_TrayWnd
	ControlGetPos , ClockX, , ClockWidth, , TrayClockWClass1, ahk_class Shell_TrayWnd
	ControlGetPos , ShowDesktopX, , ShowDesktopWidth, , TrayShowDesktopButtonWClass1, ahk_class Shell_TrayWnd
	ControlGetPos , TaskListX, , TaskListWidth, , MSTaskListWClass1, ahk_class Shell_TrayWnd	
	CoordMode, Mouse , Screen
	MouseGetPos,x
	
	;outputdebug TrayX: %trayx% Tray Width: %traywidth% mouse x: %x%
	WinGetClass classname, A
	;outputdebug ActiveWindow: %classname%
	if (x<TaskListX)
	{
		OutputDebug taskbutton clicked
	}
	else if (x<TaskListX+TaskListWidth)
	{
		if WinActive("ahk_class TaskListThumbnailWnd")
		{
			;activate those lines to make clicks on multi buttons activate the first window
			;OutputDebug multibutton clicked
			;Send {Up}
			;Sleep is probably not needed
			;Sleep 100
			;Send {Enter}
		}	
		else if WinActive("ahk_class Shell_TrayWnd")
		{
			OutputDebug empty space clicked
		}
		else
		{
			OutputDebug Single button clicked
		}
	}
	else if (x<trayx+traywidth)
	{
			OutputDebug, Tray clicked
	}
	else if (x<ClockX+ClockWidth)
	{
		 OutputDebug Clock clicked
	}
	else if (x<ShowDesktopX+ShowDesktopWidth)
	{
			OutputDebug Show desktop clicked
	}	
}
ShellMessage( wParam,lParam ) 
{
	global listening
	; Execute a command based on wParam and lParam 
	if(wParam=4)
	{
		;outputdebug windows activated shell msg
		if(listening){
		;outputdebug and listening
			listening:=false
			TaskbarClicked()
		}
	}	
}
~LButton::		
	;OutputDebug click
	WinGetPos, , , , Height, ahk_class Shell_TrayWnd
	CoordMode, Mouse , Screen
	MouseGetPos,, y
	;outputdebug mousey:%y% taskbarheight:%height%
	if(y>A_ScreenHeight-Height)
	{
		;Outputdebug taskbar clicked
		listening:=1
		SetTimer, CheckShellMessage , 1000
	}
	return
CheckShellMessage:
	SetTimer, CheckShellMessage , off
	;outputdebug timer
	If(listening)
	{
		;outputdebug and listening
		listening:=false
		TaskbarClicked()
	}
	return


painstaking
  • Guests
  • Last active:
  • Joined: --
so then what is the fully compiled code for this aero peek imitation? i'm confused.

kakarukeys
  • Members
  • 86 posts
  • Last active: Jul 18 2010 03:10 PM
  • Joined: 28 Sep 2009

so then what is the fully compiled code for this aero peek imitation? i'm confused.


Hi,

Here's my AutoRaise code with Aero Peek simulation. There are a few more ways to do it. Check the posts above.


#Persistent
SetTitleMatchMode, RegEx

peeking = 0

hover_task_buttons  = 1 ; hover over taskbar button to activate window
  hover_task_group  = 1 ; 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       = 1 ; minimize or maximize by hovering over the min/max buttons
hover_any_window    = 0 ; 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       = 500 ; 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)
    {   ; hovering over taskbar button.
        if (GetMouseTaskButton(win))
        {
            if (win)
            {
                if (hover_task_min_info)
                {
                    WinGet, min_max, MinMax, ahk_id %win%
                    if (min_max = -1)
                    {
                        WinGetTitle, ti, ahk_id %win%
                        ToolTip, %ti% (minimized)
                        remove_ttip_on_move := true
                        return
                    }
                }
                if (hover_keep_zorder)
                {
                    JustActivate(win)
                    return
                }
                WinActivate, ahk_id %win%
            }
            ; May be a group button ("Group similar taskbar buttons")
            else
                Click
            return
        }
        else if (hover_task_group && WinActive("ahk_class Shell_TrayWnd"))
        {   ; Check if we are hovering over a toolbar window,
            ; possibly a list of grouped buttons/windows.
            MouseGetPos,,, win, ctl, 2
            ctl_parent := DllCall("GetParent", "uint", ctl) ; get control parent
            WinGetClass, ctl, ahk_id %ctl%                  ; get control class
            WinGetClass, ctl_parent, ahk_id %ctl_parent%    ; get parent class
            WinGetClass, win, ahk_id %win%                  ; get window class
            if (win="BaseBar"                       ; probably a button group menu
                || (win="Shell_TrayWnd"             ; taskbar
                 && ctl_parent="MSTaskSwWClass"))   ; task buttons
                Click
            ; (The win="BaseBar" check excludes the system notification area.)
            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_VISTA" && (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%
        }
    }

; Aero Peek simulation
;MouseGetPos,,,, ctl
;if (ctl = "TrayClockWClass1") {
;	Send #d
;	peeking = 1
;	return
;} else if (peeking = 1) {
;	Send #d
;	peeking = 0
;	return
;}
MouseGetPos,,,, ctl
if (ctl = "TrayClockWClass1") {
	Send #d
	return
}

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
}

TypingAid autocompletion program made with AHK.

kakarukeys
  • Members
  • 86 posts
  • Last active: Jul 18 2010 03:10 PM
  • Joined: 28 Sep 2009

Not sure if this helps (as I don't fully understand this thread as a total noob :) ), but there is an actual keyboard shortcut for Aero Peek built into Win 7, #space.

But there does seem to be some problem with that. I tried this:

Capslock::#space

And while it does work perfectly fine, for some reason the Win key never releases when Caps Lock is released, so using that I'm stuck in Aero Peek until I Alt-Tab to another window.


Hi, the point is there's no Aero Peek in Win XP and Vista. So we use AHK to simulate it. You don't have to do it in 7.
TypingAid autocompletion program made with AHK.

woebtz
  • Guests
  • Last active:
  • Joined: --
This was my reason for installing AHK and it's made a huge difference in my computer'ing life.

BTW, I'm using hover_any_window and a modified "hovering:" to click/activate Notepad++ tabs. I'm also using an option in the Tab Mix Plus Firefox extension to activate tabs on mouse over.

hovering:

...

; hover over notepad++ tab to focus:
MouseGetPos,,,,outCtl
if (outCtl = "SysTabControl325")
{
  Click
  return
}


DeWild1
  • Members
  • 369 posts
  • Last active: Feb 28 2014 08:15 PM
  • Joined: 30 Apr 2006

so then what is the fully compiled code for this aero peek imitation? i'm confused.


Hi,

Here's my AutoRaise code with Aero Peek simulation. There are a few more ways to do it. Check the posts above.


#Persistent
SetTitleMatchMode, RegEx

peeking = 0

hover_task_buttons  = 1 ; hover over taskbar button to activate window
  hover_task_group  = 1 ; 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       = 1 ; minimize or maximize by hovering over the min/max buttons
hover_any_window    = 0 ; 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       = 500 ; 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)
    {   ; hovering over taskbar button.
        if (GetMouseTaskButton(win))
        {
            if (win)
            {
                if (hover_task_min_info)
                {
                    WinGet, min_max, MinMax, ahk_id %win%
                    if (min_max = -1)
                    {
                        WinGetTitle, ti, ahk_id %win%
                        ToolTip, %ti% (minimized)
                        remove_ttip_on_move := true
                        return
                    }
                }
                if (hover_keep_zorder)
                {
                    JustActivate(win)
                    return
                }
                WinActivate, ahk_id %win%
            }
            ; May be a group button ("Group similar taskbar buttons")
            else
                Click
            return
        }
        else if (hover_task_group && WinActive("ahk_class Shell_TrayWnd"))
        {   ; Check if we are hovering over a toolbar window,
            ; possibly a list of grouped buttons/windows.
            MouseGetPos,,, win, ctl, 2
            ctl_parent := DllCall("GetParent", "uint", ctl) ; get control parent
            WinGetClass, ctl, ahk_id %ctl%                  ; get control class
            WinGetClass, ctl_parent, ahk_id %ctl_parent%    ; get parent class
            WinGetClass, win, ahk_id %win%                  ; get window class
            if (win="BaseBar"                       ; probably a button group menu
                || (win="Shell_TrayWnd"             ; taskbar
                 && ctl_parent="MSTaskSwWClass"))   ; task buttons
                Click
            ; (The win="BaseBar" check excludes the system notification area.)
            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_VISTA" && (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%
        }
    }

; Aero Peek simulation
;MouseGetPos,,,, ctl
;if (ctl = "TrayClockWClass1") {
;	Send #d
;	peeking = 1
;	return
;} else if (peeking = 1) {
;	Send #d
;	peeking = 0
;	return
;}
MouseGetPos,,,, ctl
if (ctl = "TrayClockWClass1") {
	Send #d
	return
}

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
}


Damn, is there any way to get a big preview window?
This is still hella cool 8)