All credits goes to holomind and his incredible script:
http://www.autohotkey.com/forum/viewtopic.php?t=13001
So, what's different:
- complete rewrite, mainly for easy integration into your own script ,
- stripped down script's size ,
- whenever possible, turns labels into functions, in order to have a maximum of local variables ,
- removed all unecessary stuff (animation, etc) ,
- changed the way "not shown windows" are checked ,
- no more screen blinking on script launch ,
- take care of desktop's background changes ,
- cpu usage optimisation.
Code:
#NoEnv
#SingleInstance, Force
SetBatchLines, -1
SetKeyDelay, 0
SetWinDelay, 0
OnExit, CleanExit
; settings
Expose_MaxWin := 20 ; maximum number of windows to handle
Expose_Border := 8 ; border between thumbs
; GUI init
Gui, +AlwaysOnTop -Caption +Toolwindow +Owner +LastFound
Gui, Show, Hide w%A_ScreenWidth% h%A_ScreenHeight% x0 y0 , »Expose«
WinGet, Expose_ID , ID
; hotkeys
Hotkey, MButton , Expose_Show ,AboveNormal
Hotkey, IfWinActive, ahk_id %Expose_ID%
Hotkey, LButton, Expose_Hide
; global variables
Loop, %Expose_MaxWin%
Expose_WIN%A_Index% := true
hdc_frontbuffer := GetDC( Expose_ID )
hdc_printwindow := CreateCompatibleDC( hdc_frontbuffer )
hbm_printwindow := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
hbm_old := SelectObject( hdc_printwindow, hbm_printwindow)
hdc_thumbnails := CreateCompatibleDC( hdc_frontbuffer )
hbm_thumbnails := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
hbm_old := SelectObject( hdc_thumbnails, hbm_thumbnails )
hdc_backbuffer := CreateCompatibleDC( hdc_frontbuffer )
hbm_backbuffer := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
hbm_old := SelectObject( hdc_backbuffer, hbm_backbuffer)
hdc_desktop := CreateCompatibleDC( hdc_frontbuffer )
hbm_desktop := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
hbm_old := SelectObject( hdc_desktop, hbm_desktop )
; other global variables:
;
; Expose_ID
; Expose_Cols
; Expose_Rows
; Expose_WIN0
; Expose_Border
; win_id
; x
; y
Return
CleanExit:
Gui, Destroy
ReleaseDC( Expose_ID, hdc_frontbuffer )
ReleaseDC( Expose_ID, hdc_copy )
DeleteObject( hbm_printwindow )
DeleteDC( hdc_printwindow )
DeleteObject( hbm_window )
DeleteDC( hdc_window )
DeleteObject( hbm_backbuffer )
DeleteDC( hdc_backbuffer )
DeleteObject( hbm_desktop )
DeleteDC( hdc_desktop )
ExitApp
Expose_Show:
if Expose_ListWin() { ; show thumbs only if there's at least one window
SetStretchBltMode( hdc_thumbnails, 4 )
Gui Show
if Wallpaper_IsNew() { ; updates GUI if wallpaper has changed
PaintDesktop( hdc_frontbuffer )
BitBlt( hdc_desktop, 0, 0, A_ScreenWidth, A_ScreenHeight, hdc_frontbuffer, 0, 0, 0xCC0020 )
}
Expose_ShowWin()
}
Return
Wallpaper_IsNew()
{
Static wallpaper_last
RegRead, wallpaper, HKEY_CURRENT_USER, Control Panel\Desktop, Wallpaper
if (wallpaper <> wallpaper_last) {
wallpaper_last := wallpaper
return true
}
}
Expose_ListWin()
{
Global Expose_ID
WinGet id, list
win_list :=
Loop %id% {
win_id := id%A_Index%
WinGet, style, Style, ahk_id %win_id% ; ignore windows without title bar
WinGet, state, MinMax, ahk_id %win_id% ; ignore minimized windows
if ( style & 0xC00000 ) and ( state <> "-1" ) and ( win_id <> Expose_ID )
win_list := win_list . win_id . ","
}
StringTrimRight win_list, win_list, 1
Sort win_list, D, ; keep positions of thumbnails
Return win_list
}
Expose_ShowWin()
{
Global Expose_ID
, Expose_Cols
, Expose_Rows
, Expose_WIN0
, Expose_Border
, hdc_frontbuffer
, hdc_printwindow
, hdc_thumbnails
, hdc_desktop
win_list := Expose_ListWin() ; get list of windows' id
StringSplit, num_win, win_list, `,
num_win := num_win0 ; count windows
Expose_Cols := ceil(sqrt(num_win))
Expose_Rows := ceil(num_win / Expose_Cols)
thumb_w := A_ScreenWidth // Expose_Cols
thumb_h := A_ScreenHeight // Expose_Rows
screen_ratio := A_ScreenWidth / A_ScreenHeight * Expose_Rows / Expose_Cols
Loop Parse, win_list, `,
{
Expose_WIN%A_Index% := A_LoopField ; store window's id
WinGetPos,,, w%A_Index%, h%A_Index%, ahk_id %A_LoopField%
win_ratio := w%A_Index% / h%A_Index%
If (win_ratio < screen_ratio) { ; tall window
thumb_h%A_Index% := thumb_h - 2*Expose_Border
thumb_w%A_Index% := Floor(thumb_w * win_ratio / screen_ratio) - 2*Expose_Border
}
Else { ; wide window
thumb_w%A_Index% := thumb_w - 2*Expose_Border
thumb_h%A_Index% := Floor(thumb_h * screen_ratio / win_ratio) - 2*Expose_Border
}
if ( thumb_w%A_Index% > w%A_Index% or thumb_h%A_Index% > h%A_Index% ) {
thumb_w%A_Index% := w%A_Index%
thumb_h%A_Index% := h%A_Index%
}
}
BitBlt( hdc_thumbnails, 0, 0, A_ScreenWidth, A_ScreenHeight, hdc_desktop, 0, 0 , 0xCC0020)
Loop %num_win% {
pos_x := thumb_w * Mod(A_Index-1,Expose_Cols)
pos_y := thumb_h * ((A_Index-1)//Expose_Cols)
PrintWindow( Expose_WIN%A_Index%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
hdc_target := hdc_thumbnails
StretchBlt( hdc_target , pos_x + ( thumb_w - thumb_w%A_Index% ) // 2
, pos_y + ( thumb_h - thumb_h%A_Index% ) // 2
, thumb_w%A_Index%
, thumb_h%A_Index%
,hdc_printwindow, 0, 0, w%A_Index%, h%A_Index% ,0xCC0020) ; SRCCOPY
BitBlt( hdc_frontbuffer, 0 , 0 , A_ScreenWidth, A_ScreenHeight ,hdc_thumbnails, 0 , 0 , 0xCC0020) ; flip
}
}
Expose_Hide:
MouseGetPos x, y
Gui, Hide
win_id := 1 + x*Expose_Cols//A_ScreenWidth + y*Expose_Rows//A_ScreenHeight * Expose_Cols
win_id := Expose_WIN%win_id%
WinActivate,ahk_id %win_id%
; WinGetPos,,, x, y, A
; MouseMove, x/2, y/2
Return
; --------------------------------------------------------------------------------------------------
; Library: no need to modify below
; Libary (could be put in extra file )
; #include <GDI.ahk>
; for documentation of commands see: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/wingdistart_9ezp.asp
; -- highlevel not direct dllcall mapping , simplifiers
CreateDCBuffer(ByRef hdc_from, ByRef hdc_to, ByRef hbm_to, w ,h ) {
; does not work, something wrong with ByRef and global
hdc_to := CreateCompatibleDC(hdc_from) ; buffer
hbm_to := CreateCompatibleBitmap(hdc_from,w,h)
old := SelectObject(hdc_to,hbm_to)
}
; -- mfc wrapper
GetDC( hw ) {
return DLLCall("GetDC", UInt, hw )
}
CreateDC( driver,device,output,mode ) {
return DLLCall("GetDC", UInt, driver, UInt, device, UInt, output, UInt, mode )
}
SetStretchBltMode( hdc , value ) {
return DllCall("gdi32.dll\SetStretchBltMode", UInt,hdc, "int",value)
}
CreateCompatibleDC( hdc ) {
return DllCall("gdi32.dll\CreateCompatibleDC", UInt,hdc)
}
CreateCompatibleBitmap( hdc , w, h ) {
return DllCall("gdi32.dll\CreateCompatibleBitmap", UInt,hdc, Int,w, Int,h)
}
SelectObject( hdc , hbm ) {
return DllCall("gdi32.dll\SelectObject", UInt,hdc, UInt,hbm)
}
DeleteObject( hbm ) {
return DllCall("gdi32.dll\DeleteObject", UInt,hbm)
}
DeleteDC( hdc ) {
return DllCall("gdi32.dll\DeleteDC", UInt,hdc )
}
ReleaseDC( hwnd, hdc ) {
return DllCall("gdi32.dll\ReleaseDC", UInt,hwnd,UInt,hdc )
}
PrintWindow( window_id , hdc , mode ) {
return DllCall("PrintWindow", UInt, window_id , UInt,hdc, UInt, mode)
}
StretchBlt( hdc_dest , x1, y1, w1, h1, hdc_source , x2, y2, w2, h2 , mode) {
return DllCall("gdi32.dll\StretchBlt"
, UInt,hdc_dest , Int,x1, Int,y1, Int,w1, Int,h1
, UInt,hdc_source, Int,x2, Int,y2, Int,w2, Int,h2
, UInt,mode)
}
BitBlt( hdc_dest, x1, y1, w1, h1 , hdc_source, x2, y2 , mode ) {
return DllCall("gdi32.dll\BitBlt"
, UInt,hdc_dest , Int, x1, Int, y1, Int, w1, Int, h1
, UInt,hdc_source , Int, x2, Int, y2
, UInt, mode)
}
PaintDesktop( hdc ) {
return DllCall("PaintDesktop", UInt, hdc )
}
; constants
; see: http://www.adaptiveintelligence.net/Developers/Reference/Win32API/GDIConstants.aspx
; #SRCCOPY = 0xCC0020
Have fun