+ If you don't click on a picture, but on the wallpaper background, or if you press Esc or if you press F12 again, Expose will fade out, and the previous active window will be activated
Still needed:
+ speedup
+ settings GUI
Code:
#SingleInstance force
#NoEnv
SetBatchLines -1
SetWinDelay 0
SetControlDelay 0
Process, Priority,, High
RegRead, wall_path, HKCU, Control Panel\Desktop, Wallpaper
Gui, 3:Destroy
Gui, 3:+AlwaysOnTop -Caption
Gui, 3:Add, Picture, gClickedOnWall x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
, %wall_path%
Gui, 3:Show, Hide x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%, ehm
OnExit handle_exit
; config
fade_delay = 0 ; msec to wait for next animation frame
fade_steps = 3 ;4 ; steps in animation, 2 = fast, 10 = slow (smooth)
fadeout_steps = 3 ;4
min_w = 110 ; min width of windows to be shown
min_h = 110 ; min height of windows to be shown (hides taskbar etc)
trans_color = #998877
translevel = 255 ; transparency of end of animation
translevel_start = 0 ; transparency of start of animation (see offscreen painting)
translevel_stop_solid= 0 ; 0/1 turn off transparency at end of fade_in to hide background
scale_thumb_space = 1
live_repaint = 1000 ;1000 ; msec repaint the windows in expose mode, 0 = off
;init values
gui_active = 0 ; gui is hidden at startup
pics_added = 0 ; onclicks are not yet registered
Return
+F12::
handle_exit:
Gosub destroy_gui
ExitApp
GuiEscape:
Goto destroy_gui
Return
!r::Reload
F12::
MButton::
If gui_active = 1 ; toggle off if already active
GoTo destroy_gui
WinGetTitle, prev_active_title, A
;WinGet prev_active_id, id, A
; msgbox % prev_active_id
gui_active = 1 ; show gui
GoSub calculate_sizes ; sets "cols" , "rows"
If (num_win = "" or num_win = 1) ; do nothing if no active windows
Return ; or only 1
Gui, 3:Show
; GoSub create_wall ; create bgwindow with current wallpaper
GoSub create_gui ; prepare gui to draw onto it
GoSub draw_thumbnails
GoSub fade_in
SetTimer draw_thumbnails, %live_repaint%
Return
create_wall:
RegRead, wall_path, HKCU, Control Panel\Desktop, Wallpaper
Gui, 2:Destroy
Gui, 2:+AlwaysOnTop -Caption
Gui, 2:Add, Picture, gClickedOnWall x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
, %wall_path%
Gui, 2:Show, Hide NA x0 y0 w%A_ScreenWidth% h%A_ScreenHeight%
Return
calculate_sizes:
num_win := get_wins()
cols := ceil( sqrt( num_win ))
rows := ceil( sqrt( num_win ))
If (cols * (rows-1) >= num_win )
rows--
thumb_w := A_ScreenWidth // cols
thumb_h := A_ScreenHeight // rows
ratio_of_screen := A_ScreenWidth / A_ScreenHeight * rows / cols
Return
draw_thumbnails:
pos_x := 0
pos_y := 0
win_now := 0
task_ids =
Loop %ids% ; ids has been set up in calculate_sizes
task_ids := task_ids "," ids%a_index%
Sort task_ids, D, ; keep positions of thumbnails
Loop Parse, task_ids, `,
{
task_id = %A_LoopField%
WinGetTitle title, ahk_id %task_id%
WinGetPos,,, w, h, ahk_id %task_id%
If (!is_excluded_win() ) { ; small windows not shown (eg taskbar)
win_now++
task_ids_%win_now% := task_id ; for activation
if !pics_added
Gui 1:Add, Pic, gActivateWin x%pos_x% y%pos_y% w%thumb_w% h%thumb_h% vPic%win_now% ; register "onclick"
sleep 10 ; prevent missing windows
pwin := DllCall("PrintWindow", UInt,task_id, UInt,hdc_buffer, UInt,0)
ratio_of_win := w / h
if ( scale_thumb_space ) {
if ( ratio_of_win < ratio_of_screen ) { ; tall window
thumb_h2 := thumb_h
thumb_w2 := thumb_w * ratio_of_win / ratio_of_screen
} Else { ; wide window
thumb_w2 := thumb_w
thumb_h2 := thumb_h / ratio_of_win * ratio_of_screen
}
}
x1 := pos_x + (thumb_w - thumb_w2 ) / 2
y1 := pos_y + (thumb_h - thumb_h2 ) / 2
DllCall("gdi32.dll\StretchBlt"
, UInt, hdc_frame
, Int, x1
, Int, y1
, Int, thumb_w2
, Int, thumb_h2
, UInt, hdc_buffer
, Int, 0
, Int, 0
, Int, w
, Int, h
, UInt, 0xCC0020) ; SRCCOPY
pos_x += thumb_w
if ( pos_x >= A_ScreenWidth ) {
pos_x :=0
pos_y += thumb_h
}
} ; If !excluded
} ; Loop task_ids
pics_added := 1
Return
is_excluded_win() {
Global
Return w < min_w or h < min_h or title ="Expose" or title =""
}
fade_in:
Loop %fade_steps% {
intrans := A_Index * translevel / fade_steps
WinSet, TransColor, %trans_color% %intrans%, ahk_id %hw_frame%
Sleep %fade_delay%
}
If translevel_stop_solid
WinSet Transparent, off
intrans =
Return
fade_out:
Loop %fadeout_steps% {
outtrans := translevel - A_Index * translevel / fadeout_steps
WinSet, TransColor, %trans_color% %outtrans%, ahk_id %hw_frame%
Sleep %fade_delay%
}
outtrans =
Return
get_wins() {
Local x
WinGet ids, list,,,Program Manager ; all active windows-tasks (processes)
Loop %ids% {
task_id := ids%a_index% ; id of this window
WinGetTitle title, ahk_id %task_id%
WinGetPos,,, w, h, ahk_id %task_id%
If !is_excluded_win() ; small windows not shown (eg taskbar)
x++
}
Return x
}
; *** Create Expose Gui
create_gui:
Gui 1:Destroy ; clear old stuff if expose hotkey is running in background
Gui 1:+AlwaysOnTop +LastFound
Gui 1:Color, %trans_color%
WinSet, TransColor, %trans_color%
Gui 1:-Caption
WinSet, Transparent, %translevel_start%
Gui 1: Show, w%A_ScreenWidth% h%A_ScreenHeight% x0 y0, Expose
WinGet hw_frame, id, Expose
hdc_frame := DllCall( "GetDC"
, UInt, hw_frame )
DllCall( "gdi32.dll\SetStretchBltMode"
, "uint", hdc_frame
, "int", 4 ) ; Halftone better quality with stretch
hdc_buffer := DllCall("gdi32.dll\CreateCompatibleDC"
, UInt, hdc_frame) ; buffer
hbm_buffer := DllCall("gdi32.dll\CreateCompatibleBitmap"
, UInt,hdc_frame
, Int,A_ScreenWidth
, Int,A_ScreenHeight)
DllCall( "gdi32.dll\SelectObject"
, UInt,hdc_buffer
, UInt,hbm_buffer)
pics_added := 0
Return
; *** Actions on selection made
; on click on picture
ActivateWin:
StringReplace pos, A_GuiControl, Pic ; find the clicked pic-id
clicked_on_pic_id := task_ids_%pos%
clicked_on_pic = true
; -- continue
; on click on wallpaper
ClickedOnWall:
WinActivate, ahk_id %hw_frame%
; -- continue
; fade out
destroy_gui:
SetTimer draw_thumbnails, OFF
GoSub fade_out
Gui, 3:Hide ; fixed background GUI
Gui, 2:Destroy ; wallpaper background GUI
Gui, 1:Destroy ; Expose GUI
gui_active := 0
pics_added := 0
DllCall("gdi32.dll\DeleteObject", UInt,hbm_buffer)
DllCall("gdi32.dll\DeleteDC", UInt,hdc_frame )
DllCall("gdi32.dll\DeleteDC", UInt,hdc_buffer)
If clicked_on_pic = true
WinActivate ahk_id %clicked_on_pic_id%
Else
WinActivate, %prev_active_title%
clicked_on_pic_id =
clicked_on_pic = false
prev_active_id =
Return
; /*** Actions on selection made