AutoHotkey Community

It is currently May 26th, 2012, 9:42 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 292 posts ]  Go to page Previous  1 ... 16, 17, 18, 19, 20  Next

Would you like to see this script rewritten and easy to understand ?
No, I dont care, i just use the executable
Yes, as this script is popular some may learn from it
You may select 1 option

View results
Author Message
 Post subject:
PostPosted: September 15th, 2009, 2:51 pm 
Offline

Joined: March 11th, 2006, 12:44 pm
Posts: 341
Location: Munich, Germany
kli6891 wrote:
Is your website down? I can't download from your website.
I used a wrong filename, it works now.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 15th, 2009, 2:57 pm 
Offline

Joined: March 11th, 2006, 12:44 pm
Posts: 341
Location: Munich, Germany
kli6891 wrote:
If I have a minimized window, and try switch to it via expose, it doesn't work, since the previously active window will take it over

Perhaps you can try to fix it. Maybe the problem is that now all windows the ahk_group minimized%minimized_counter% minimizes all minimized windows to the original state. if the active one is inside it will be falsely minimized and the last active will then become the active one.
A simple fix could be to Activate (perhaps first WinRestore) the Chosen Window after the minimizing of all. (Maybe in ahk_id ActiveID ?) Then its minimized, but Restored shortly after. The effect is not too bad. as it in fact was a minimized window. and choosing it with expose will call the unminimize animation.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Nice!
PostPosted: September 15th, 2009, 4:15 pm 
Offline

Joined: September 15th, 2009, 3:52 pm
Posts: 2
Hi!

Can I use your Expose code in my ShortCut! project?
ShortCut! gives screen corners different actions like ShowDesktop and ShortcutWindow. It hasn't got that many features (yet) but over time it will get more and more.

Download a copy and check it out:
http://www.mediafire.com/?nm0il4mzizt


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re: Nice!
PostPosted: September 15th, 2009, 5:18 pm 
Offline

Joined: March 11th, 2006, 12:44 pm
Posts: 341
Location: Munich, Germany
Frants wrote:
Can I use your Expose code in my ShortCut! project?

Yes, its free to use and integrate, nice to see the script spread and somebody finds it useful. i am also amazed you managed to integrate all this scripts without sideeffects. maybe it would be better to use the original scripts and call them from your script or (#include ..) them , so you can update them more easy if a new version of one of your integrated scripts is available.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Re: Nice!
PostPosted: September 15th, 2009, 6:20 pm 
Offline

Joined: September 15th, 2009, 3:52 pm
Posts: 2
Thanks! :)

I thought of that but found my solution was the best one. Your script didn't need that much of modification as you maybe already saw. Some search-and-replace GUI stuff and a couple of copy-paste Gosubs and it works.

I'm sure there is a good utility somewhere that could create a generic make-vanilla-expose-ahk-work-with-shortcut!.patch. It could be useful if I someday would find my copy-pasting and search-and-replacing too ineffective ;)

Now I shall try to fix the MButton Window_Close only works one time bug..


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 15th, 2009, 10:36 pm 
Offline

Joined: August 1st, 2009, 12:24 pm
Posts: 46
holomind wrote:
kli6891 wrote:
If I have a minimized window, and try switch to it via expose, it doesn't work, since the previously active window will take it over

Perhaps you can try to fix it. Maybe the problem is that now all windows the ahk_group minimized%minimized_counter% minimizes all minimized windows to the original state. if the active one is inside it will be falsely minimized and the last active will then become the active one.
A simple fix could be to Activate (perhaps first WinRestore) the Chosen Window after the minimizing of all. (Maybe in ahk_id ActiveID ?) Then its minimized, but Restored shortly after. The effect is not too bad. as it in fact was a minimized window. and choosing it with expose will call the unminimize animation.


If you take a look @ my original branch, i had something like that. The restore position subroutine will first get the ID of the activated window, then proceed to minimize every window in the minized window list UNLESS the id matches.

I'll take a look @ yours and try to fix it.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 15th, 2009, 10:41 pm 
Offline

Joined: August 1st, 2009, 12:24 pm
Posts: 46
Ok, I fixed it.

You had that WinActivate in there, but commented out. Perhaps there's something I'm missing?


Code:
;v1.20090914 -- expose.ahk - Thumbnails of windows over the working area, active thumbnails when no zoom,                                            ;zoomed window means redraw only zoomed window
; new minimized windows

OnExit handle_exit
#SingleInstance Force
#NoEnv
SetBatchLines -1
SetWinDelay 0               ; larger values also fail under heavy load, changing windows
Process Priority,,Above Normal
CoordMode Mouse, Relative

Main:
  Gosub, Read_Keymapping
  Gosub, Read_Config
  Gosub, Detect_Screensize
  Gosub, Create_Gui
  Gosub, Create_Buffers
  ; wait for key/mouse
Return

Read_Keymapping:
  Hotkey, #TAB    ,      Window_Choose
  Hotkey, ^q ,     Window_Choose
  Hotkey, IfWinActive , »Expose«
  Hotkey, #TAB    ,      Window_Activate
  Hotkey, MButton ,     Window_Activate
  Hotkey, LButton ,      Window_Activate
  HotKey, RButton ,     Window_Preview
  Hotkey, Esc     ,        hide_gui
  Hotkey, WheelUp ,    Handle_Zoom
  Hotkey, WheelDown, Handle_Zoom
  Hotkey, +MButton ,   handle_exit ; panik-key
  Hotkey, #F12 ,          Debug_Info
Return

Read_Config:
  min_w                        = 110  ; min width of windows to be shown
  min_h                        = 110  ; min height of windows to be shown (hides taskbar etc)
  scale_thumb_space    = 1    ; scale thumbnails to best fit to box?
  live_redraw                 = 1   ; 1/0 = Yes/No
  time_gap                   = 100   ; ms, time left for others after each thumbnail draw
  thumb_border             = 1   ; 1 for gap between thumbnail  s
  animate_in_delay       = 5
  animate_in_steps       = 5
  animate_out_delay     = 5
  animate_out_steps     = 5
  show_taskbar             = 1
  main_monitor   = 1 ; or 2 or 3 if you like
  ;fade_in_steps           = 5
  ;fade_in_delay           = 5
  ;fade_out_steps         = 5
  ;fade_out_delay         = 50
  quality_low                = 3 ; allowed: 1 (terrible) , 3 (accepatable) 4 (good = slow)
  quality_high               = 4 ; allowed: 1 (terrible) , 3 (accepatable) 4 (good = slow)
  BackGroundColor       = 004E98
  count := 0
  counter := 0
  zoom_preview = 0.8
  zoom_maximized = 1 ; // 1=on ; 0=off ; allow to zoom more than real size
  do_zoom := 0  ; // off at first
  old_ids_count =  -1 ;
  show_minimized := 1 ;
  minimized_counter := 0 ;
Return

Debug_Info:
ListLines

Window_Hidden() {
   global
   Return w < min_w or h < min_h or title ="»Expose«" or title =""
}

Handle_Zoom:
   If (do_zoom = 0 and ( A_ThisHotKey = "WheelUp" or A_ThisHotKey = "^+Up" ))
   {
      zoom_preview = 0 ; start at 100% to make it look seemless
      gosub Window_Preview ; activate Preview by Scrolling , eg. zooming
   }

   If (do_zoom = 1 and zoom_preview =0 and ( A_ThisHotKey = "WheelDown" or A_ThisHotKey = "^+Down" ))
      gosub Window_Preview ; deactivate zoom


   If (zoom_preview < 4 and ( A_ThisHotKey = "WheelUp" or A_ThisHotKey = "^+Up" ))
      zoom_preview += 0.05         ; sqrt(sqrt(2))
   If (zoom_preview >  0 and ( A_ThisHotKey = "WheelDown" or A_ThisHotKey = "^+Down" ))
      zoom_preview -= 0.05
   TrayTip,,% "Zoom = " Round(100*(1+zoom_preview)) "%"
Return

In(x,a,b) {                      ; closest number to x in [a,b]
   IfLess x,%a%, Return a
   IfLess b,%x%, Return b
   Return x
}


Detect_ScreenSize:

    ; Copy bounds of all monitors to an array.
    SysGet, mc, MonitorCount
    Loop, %mc%
        SysGet, mon%A_Index%, MonitorWorkArea, %A_Index%
   
  Th=0
  Tw=0
  Ty=0
  Tx=0

 
  if show_taskbar and mc = 1
  {   
   WinGetPos,Tx,Ty,Tw,Th,ahk_class Shell_TrayWnd,,,
  }
   ; Default
   WorkArea_Top    :=      ( Tw > Th  and  Tx = 0  and  Ty = 0) * Th
   WorkArea_Left   :=      ( Tw < Th  and  Tx = 0  and  Ty = 0) * Tw
   WorkArea_Height := A_ScreenHeight - ( Tw > Th  ) * Th
   WorkArea_Width  := A_ScreenWidth  - ( Tw < Th  ) * Tw
 
  if show_taskbar and mc > 1
  {   
    md := main_monitor ; // change this where you want to show your thumbnails Number of Monitor
    ; fix for dual monitor
    WorkArea_Top    := mon%md%Top
    WorkArea_Left   := mon%md%Left
    WorkArea_Width  := mon%md%Right - mon%md%Left
    WorkArea_Height := mon%md%Bottom - mon%md%Top
  }

 
 ; TrayTip,,% "Taskbar = " Tx " " Ty " " Tw " " Th " " A_ScreenWidth " " A_ScreenHeight " mc: " mc
  ; if Ty > A_ScreenHeight then Taskbar is "below" mon1
  ; if Ty < 0 Tastbar is above mon1

Return

Create_Gui:
  Gui +AlwaysOnTop -Caption  +Toolwindow +Owner +LastFound
  ;Gui Color, %BackGroundColor%
 
  ; create blank screens for non-main monitor
  ; SysGet, mc, MonitorCount
  ;   Loop, %mc%
  ;  {   
  ;    SysGet, mon%A_Index%, MonitorWorkArea, %A_Index%
  ;    md := A_Index
  ;    WorkArea_Top    := mon%md%Top
  ;    WorkArea_Left   := mon%md%Left
  ;    WorkArea_Width  := mon%md%Right - mon%md%Left
  ;    WorkArea_Height := mon%md%Bottom - mon%md%Top
  ; 
  ;    Gui +AlwaysOnTop -Caption  +Toolwindow +Owner +LastFound
  ;    Gui Color, %BackGroundColor%
  ;    Gui Show,  Hide w%WorkArea_Width% h%WorkArea_Height% x%WorkArea_Left% y%WorkArea_Top%, »Expose%A_Index%«
  ;  }

   ; Last
   Gui Show, Hide  w%WorkArea_Width% h%WorkArea_Height% x%WorkArea_Left% y%WorkArea_Top%, »Expose«

  ;Gui, Add, Pic, x0 y0 w%WorkArea_Width% h%WorkArea_Height%, c:\test.bmp
  DetectHiddenWindows ON
  WinGet Expose_ID , ID, »Expose«
  WinGet Desktop_ID, ID, Program Manager
  DetectHiddenWindows OFF
Return

Create_Buffers:
  hdc_frontbuffer  := GetDC( Expose_ID )

  hdc_printwindow := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_printwindow := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_printwindow,hbm_printwindow)

  hdc_thumbnails  := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_thumbnails  := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_thumbnails,hbm_thumbnails)

  hdc_backbuffer  := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_backbuffer  := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_backbuffer,hbm_backbuffer)

  hdc_desktop     := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_desktop     := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_desktop,hbm_desktop)

  Gui Show
  PaintDesktop( hdc_frontbuffer ) ; 0=window, 1=Child(no toolbars)
  BitBlt(hdc_desktop     , 0, 0, WorkArea_Width, WorkArea_Height
      ,  hdc_frontbuffer , 0, 0 ,0xCC0020) ; SRCCOPY
  BitBlt(hdc_thumbnails  , 0, 0, WorkArea_Width, WorkArea_Height
      ,  hdc_frontbuffer , 0, 0 ,0xCC0020) ; SRCCOPY
  Gui Hide

Return

Window_Choose:
   WinGet ActiveID, ID, A

    if ( show_minimized)
      gosub fill_mini_List

   SetTimer Window_Choose_Thread, 0       ; new thread to make thumbnail draws interruptible
Return

Window_Choose_Thread:
   Stop_Drawing  =
   yield         := time_gap        ; yield time to other tasks after each thumbnail drawn
   SetTimer Window_Choose_Thread, OFF     ; run once
   GoSub Window_Info           ; list window IDs, sizes, etc.
   Gosub Animate_In

  GoSub Draw_Thumbnails
Return

Window_Activate:
   Stop_Drawing = 1
   MouseGetPos X, Y
   pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols
   task_id := task_ids_%pos%

 If (pos <= num_win and X >= 0 and X <= WorkArea_Width and Y >= 0 and Y <= WorkArea_Height)
   {
      Gosub Animate_Out
         WinActivate(task_id)                 ; activate selected window
      Gosub fade_out
   }

 if ( show_minimized)
      gosub restore_position

Gui_Hide()

Return

WinActivate(ID) {
   WinGet ,ActiveID2, ID, A
   if ActiveID2 <> ID
       WinActivate ahk_id %ID%
}

Window_Info:
   WinGet ids, list,,,Program Manager      ; all active windows-tasks (processes)
   task_info =
   num_win = 0
   Loop %ids% {
      task_id := ids%A_Index%              ; id of this window
      WinGetClass class, ahk_id %task_id%
      WinGetTitle title, ahk_id %task_id%
      WinGetPos,,, w, h, ahk_id %task_id%
      If Window_Hidden()                 ; small windows not shown (e.g. taskbar)
         Continue
      num_win++
      task_info := task_info class "|" ids%A_Index% "|" w "|" h ","
TrayTip, task_info
   }
   StringTrimRight task_info, task_info, 1 ; remove last comma
   Sort task_info, D,                      ; keep positions of thumbnails
   cols := ceil(sqrt(num_win))
   rows := ceil(sqrt(num_win))
   If (cols*(rows-1) >= num_win)           ; minimize table size
       rows--
   
   thumb_w := WorkArea_Width  // cols
   thumb_h := WorkArea_Height // rows
   ratio_of_screen := WorkArea_Width / WorkArea_Height * rows / cols
   Loop Parse, task_info, `,               ; task_info has been set up in get_wins()
   {
      StringSplit z, A_LoopField, |        ; separate ID, w, h
      task_ids_%A_Index% := z2             ; needed for activation
      if ( z2 = ActiveID )
      pos = %A_Index%
     w%A_Index% := z3                     ; w
      h%A_Index% := z4                     ; h
      ratio_of_win := z3 / z4              ; w/h
      If ( scale_thumb_space  )  {
         If (ratio_of_win < ratio_of_screen) { ; tall window
            thumb_h%A_Index% := thumb_h - thumb_border
            thumb_w%A_Index% := Floor(thumb_w * ratio_of_win / ratio_of_screen) - thumb_border
         } Else {                              ; wide window
            thumb_w%A_Index% := thumb_w - thumb_border
            thumb_h%A_Index% := Floor(thumb_h * ratio_of_screen / ratio_of_win) - thumb_border
         }
      } Else {
         thumb_w%A_Index% := z3//cols - 2*thumb_border
         thumb_h%A_Index% := z4//cols - 2*thumb_border  ; cols >= rows, keep aspect ratio of window
      }
   
     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%
      }
   }
Return

Draw_Thumbnails:

   
    If ( Stop_Drawing )
   {
      tooltip,
           Return
   }

   
   SetStretchBltMode(hdc_thumbnails,quality_high) ; 3: Lower quality at 1st draw
 
   WinGet ids_count, list,,,Program Manager      ; all active windows-tasks (processes)
   if ( old_ids_count <> ids_count )
      gosub Window_Info   ; detect if windows were added in expose mode
   
   ; layout changed full refresh (start with empty desktop)
   if ( cols <> old_cols or rows <> old_rows)
       BitBlt( hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
           , hdc_desktop, 0, 0 , 0xCC0020) ; SRCCOPY
       BitBlt( hdc_thumbnails, 0, 0, WorkArea_Width, WorkArea_Height
           , hdc_desktop, 0, 0 , 0xCC0020) ; SRCCOPY
   
   ; clear "now empty" places , only needed when less, more are filled automatically
   gaps := old_num_win - num_win
    if ( gaps )
   {
     loop %gaps%
     {
        a_index2 := num_win + gaps
       pos_x := thumb_w * Mod(A_Index2-1,cols)
       pos_y := thumb_h * ((A_Index2-1)//cols)
 
       BitBlt( hdc_thumbnails, pos_x, pos_y, thumb_w, thumb_h
              , hdc_desktop,    pos_x, pos_y ,0xCC0020) ;
   
        BitBlt( hdc_frontbuffer, pos_x, pos_y, thumb_w, thumb_h
              , hdc_thumbnails,  pos_x, pos_y ,0xCC0020) ;
      }   
   }

    old_ids_count := ids_count
    old_rows := rows
    old_cols := cols
   old_num_win := num_win

    Loop %num_win%  {                       ; task_ids, dims have been set up in win_list
     ;  Sleep %yield%                        ; CPU cycles to other tasks @ frequent redraw
      If Stop_Drawing
         Break
   
      pos_x := thumb_w * Mod(A_Index-1,cols)
      pos_y := thumb_h * ((A_Index-1)//cols)
     
      PrintWindow( task_ids_%A_Index%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
   
      BitBlt( hdc_thumbnails, pos_x , pos_y, thumb_w, thumb_h
            , hdc_desktop   , pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
   
      ; prevent flicker with backbuffer , store it in hdc_thumbnails for later reuse!
      StretchBlt( hdc_thumbnails , 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, pos_x , pos_y , thumb_w, thumb_h
             ,hdc_thumbnails,  pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
   }

 
   MouseGetPos X, Y
      pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols
 
   if pos > 0 ; dual monitor !
     winid := task_ids_%pos%
   
   WinGetTitle title, ahk_id %winid%

   tooltip, %title% ; + %old_pos2% + %pos%

   ; force Gui to foreground, maybe some windows have been opened or closed
 ; Gui_Show()
     
    If live_redraw
    {
       Gosub draw_active
       Return
      }
Return

Window_Preview:

   do_zoom := 1 - do_zoom ; toggle state
   BitBlt(hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
             ,  hdc_thumbnails, 0, 0 ,0xCC0020) ; SRCCOPY
   
return

draw_active:

  ; are gui windows also showing up and make a wrong ids_count ?
   WinGet ids_count, list,,,Program Manager      ; all active windows-tasks (processes)
   if ( old_ids_count <> ids_count ) {
      gosub,  Window_Info   ; detect if windows were added in expose mode
      gosub,  Draw_Thumbnails ;
      return
  }
  ; we need to check here if there are new windows, or windows missing and refresh the whole
  ; thing accordingly. maybe brutforce, destroy gui and paint as we have clicked "Window_Choose"
  ; only skip animation

  zoom :=  zoom_preview

  sleep %yield%                        ; CPU cycles to other tasks @ frequent redraw
       If ( Stop_Drawing )
   {
      tooltip,
           Return
   }
      MouseGetPos X, Y
      pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols
 
      if pos > 0
       winid := task_ids_%pos%

      pos_x := thumb_w * Mod(pos -1,cols)
      pos_y := thumb_h * ((pos -1)//cols)

      A_Index2 = 0

      if pos > 0 
         A_Index2 := pos

       task_id := task_ids_%A_Index2%
   
   diff_x := WorkArea_Left
   diff_y := WorkArea_Top
   diff_w := WorkArea_Width
   diff_h := WorkArea_Height


   WinGetPos, diff_x, diff_y, diff_w, diff_h , ahk_id %task_id%
   diff_x := X - diff_w // 2 ; -  ( WorkArea_Width - WorkArea_Left ) // 2

   diff_y := Y - diff_h // 2 ; - ( WorkArea_Height - WorkArea_Top ) // 2
   



   diff_x := diff_x - ( pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 ) - WorkArea_Left
   diff_y := diff_y - ( pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 ) - WorkArea_Top
   diff_w := diff_w - ( thumb_w%A_Index2% )
   diff_h := diff_h - ( thumb_h%A_Index2% )

   
      ; you can comment this line to get bit speed, acceptable
      BitBlt( hdc_backbuffer, 0, 0, WorkArea_Width, WorkArea_Height
              , hdc_thumbnails, 0, 0, 0xCC0020) ; SRCCOPY
      PrintWindow( task_ids_%A_Index2%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
      SetStretchBltMode(hdc_backbuffer,quality_high) ; 3: Lower quality at 1st draw
      SetStretchBltMode(hdc_frontbuffer,quality_high) ; 3: Lower quality at 1st draw
   
     ; counter for debugging
     counter := counter +1

     if ( do_zoom = 1 ) {   
  ;   tooltip , Drawing Zoomed window %counter%

      x0 := pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 - ( diff_w * zoom  ) // 2
      y0 := pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 - ( diff_h * zoom  ) // 2
      w  := thumb_w%A_Index2% + diff_w * zoom
      h  := thumb_h%A_Index2% + diff_h * zoom

      if ( zoom_maximized ) {
   WinGetPos,,, w_temp, h_temp, ahk_id %task_id%
           
    if ( w > w_temp or h > h_temp )
         {
          w := w_temp
          h := h_temp
          zoom_preview1 := w / ( thumb_w%A_Index2% + diff_w ) - 0.05
          zoom_preview  := h / ( thumb_h%A_Index2% + diff_h ) - 0.05
          if (zoom_preview1 > zoom_preview)
            zoom_preview = zoom_preview1 ; use minimum
         }
      
          ; refresh, prevent flicker
          zoom := zoom_preview
     x0 := pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 - ( diff_w * zoom  ) // 2
           y0 := pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 - ( diff_h * zoom  ) // 2
           w  := thumb_w%A_Index2% + diff_w * zoom
          h  := thumb_h%A_Index2% + diff_h * zoom

        }

      ; if bottom/right of zoomed thumb is out move it back into view
      if x0 + w > WorkArea_Width
        x0 := WorkArea_Width - w

      if y0 + h > WorkArea_Height
        y0 := WorkArea_Height - h

      ; if top/left is out, move it back into view, can lead to clipping of bottom or right !
      if x0 < 0
   x0 := 0 ; // overflow

      if y0 < 0
        y0 := 0 ; // overflow


      StretchBlt( hdc_backbuffer
            , x0
                           , y0
                           , w
                           , h
                           , hdc_printwindow, 0, 0, w%A_Index2%, h%A_Index2% ,0xCC0020) ; SRCCOPY
      BitBlt(hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
               ,  hdc_backbuffer, 0, 0 ,0xCC0020) ; SRCCOPY
   
   }
else  {

     Loop %num_win%  {                       ; task_ids, dims have been set up in win_list
     ;  Sleep %yield%                        ; CPU cycles to other tasks @ frequent redraw
      If Stop_Drawing
         Break
   
      pos_x := thumb_w * Mod(A_Index-1,cols)
      pos_y := thumb_h * ((A_Index-1)//cols)
     
      PrintWindow( task_ids_%A_Index%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
   
      BitBlt( hdc_thumbnails, pos_x , pos_y, thumb_w, thumb_h
            , hdc_desktop   , pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
   
      ; prevent flicker with backbuffer , store it in hdc_thumbnails for later reuse!
      StretchBlt( hdc_thumbnails , 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, pos_x , pos_y , thumb_w, thumb_h
             ,hdc_thumbnails,  pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
     }
}

   
   MouseGetPos X, Y

   pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols

   if ( pos > 0 )
     winid := task_ids_%pos%

   if ( pos < 0 )
     tooltip, %pos%

   WinGetTitle title, ahk_id %winid%

   if ( pos > 0 )
      tooltip, %title% ;  + %old_pos2% + %pos%

   

   If live_redraw
   {
      Gosub draw_active
      Return
   }

return

Animate_In:
    if !animate_in_steps
        return

    SetStretchBltMode(hdc_backbuffer, quality_low) ; 3: Lower quality at 1st draw
   
     A_index2 := pos
    pos_x := thumb_w * Mod(A_Index2-1,cols)
    pos_y := thumb_h * ((A_Index2-1)//cols)
 
    PrintWindow(task_ids_%A_Index2%,hdc_printwindow,0)
 
    task_id := task_ids_%A_Index2%
   WinGetPos, diff_x, diff_y, diff_w, diff_h , ahk_id %task_id%

    diff_x := diff_x - ( pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 ) - WorkArea_Left
    diff_y := diff_y - ( pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 ) - WorkArea_Top
    diff_w := diff_w - ( thumb_w%A_Index2% )
    diff_h := diff_h - ( thumb_h%A_Index2% )
   
   Loop %animate_in_steps%
   {
       sleep %animate_in_delay%
       zoom := 1 - ( A_Index / animate_in_steps )
     
        BitBlt( hdc_backbuffer, 0, 0, WorkArea_Width, WorkArea_Height
                 , hdc_thumbnails, 0, 0 , 0xCC0020) ; SRCCOPY
   
      if ( zoom = 0 )
         SetStretchBltMode(hdc_backbuffer, quality_high) ; 3: Lower quality at 1st draw
         StretchBlt( hdc_backbuffer , pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 + diff_x * zoom     
                           , pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 + diff_y * zoom     
                           , thumb_w%A_Index2% + diff_w * zoom   
                           , thumb_h%A_Index2% + diff_h * zoom
                           , hdc_printwindow, 0, 0, w%A_Index2%, h%A_Index2% ,0xCC0020) ; SRCCOPY
     
       if ( zoom = 0 )
         SetStretchBltMode(hdc_backbuffer, quality_low) ; 3: Lower quality at 1st draw
         Gui_Show()
         BitBlt(hdc_frontbuffer, 0, 0 ,WorkArea_Width ,WorkArea_Height
                 ,hdc_backbuffer , 0, 0 ,0xCC0020) ; SRCCOPY
   }

   old_cols := cols ; prevent full refresh on next draw
   old_rows := rows

Return

; should be reverse of animate in ? combine them ...
Animate_Out:
   
   if !animate_out_steps
         return

   A_index2 := pos
    pos_x := thumb_w * Mod(A_Index2-1,cols)
    pos_y := thumb_h * ((A_Index2-1)//cols)
 
    If (!(pos <= num_win and X >= 0 and X <= WorkArea_Width and Y >= 0 and Y <= WorkArea_Height))
       return

   ;SetStretchBltMode(hdc_frontbuffer,quality_low) ;
    PrintWindow( task_ids_%A_Index2%, hdc_printwindow ,0) ; get selected window
   
   ; clear
     BitBlt( hdc_backbuffer, pos_x, pos_y, thumb_w, thumb_h
              , hdc_desktop   , pos_x, pos_y, 0xCC0020) ; clear with desktopimage

   task_id := task_ids_%A_Index2%
   WinGetPos, diff_x, diff_y, diff_w, diff_h , ahk_id %task_id%

   diff_x := diff_x - ( pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 ) - WorkArea_Left
   diff_y := diff_y - ( pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 ) - WorkArea_Top
   diff_w := diff_w - ( thumb_w%A_Index2% )
   diff_h := diff_h - ( thumb_h%A_Index2% )

   SetStretchBltMode(hdc_backbuffer,quality_low) ; 3: Lower quality at 1st draw
    Loop %animate_out_steps%
   {
       sleep %animate_out_delay%
          zoom := ( A_Index / animate_out_steps )
       
      ; you can comment this line to get bit speed, acceptable
      BitBlt( hdc_backbuffer, 0, 0, WorkArea_Width, WorkArea_Height
              , hdc_thumbnails, 0, 0, 0xCC0020) ; SRCCOPY
     
      StretchBlt( hdc_backbuffer, pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 + diff_x * zoom
                           , pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 + diff_y * zoom
                           , thumb_w%A_Index2% + diff_w * zoom
                           , thumb_h%A_Index2% + diff_h * zoom
                           ,hdc_printwindow, 0, 0, w%A_Index2%, h%A_Index2% ,0xCC0020) ; SRCCOPY
   
       BitBlt(hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
                ,  hdc_backbuffer, 0, 0 ,0xCC0020) ; SRCCOPY
     }
   
Return

fade_in:
   ; not used ?
Return

fade_out:
   ; fade last animate_out with real desktop
Return


; subroutines by kli6891 to show minimized windows


; generate an array of minimized windows
fill_mini_List:

   minimized_counter := minimized_counter + 1 ; simulate "cleaning" groupadd

   miniList =
   miniCount = 0
   WinGet, listOfWindows, list,,, Program Manager
   Loop %listOfWindows%
   {
      currentWindowID := listOfWindows%A_Index%
      WinGetTitle, title, ahk_id %currentWindowID%
      if (title != "start" && title != "")
      {
         Winget, isMinimize, MinMax, ahk_id %currentWindowID%
         if (isMinimize == -1)
         {
            GroupAdd , mini%minimized_counter% , ahk_id %currentWindowID%
         }
      }
   }
   minAnimation(0)
   WinRestore, ahk_group mini%minimized_counter%
return

; minimize all windows that were previously captured by fill_mini_list
; except if the window is currently active
restore_position:
   WinGet ActiveID, ID, A

   WinMinimize, ahk_group mini%minimized_counter%
   WinActivate ahk_id %ActiveID%
   minAnimation(1)
return


minAnimation(set="")
{
   VarSetCapacity(AnimationInfo, 8,0)
   cbSize := VarSetCapacity(AnimationInfo)
   NumPut(cbSize, AnimationInfo, 0, "UInt")

   if set =
   {
      DllCall("SystemParametersInfo", UInt, 0x48, UInt, cbSize, "UInt", &AnimationInfo, UInt, 1 )
      return NumGet(AnimationInfo,4)
   }
   
   if (set = 0 || set = 1)
   {
      NumPut(cbSize, AnimationInfo, 0, "UInt")
      NumPut(set, AnimationInfo, 4, "Int")
     
      DllCall("SystemParametersInfo", UInt, 0x49, UInt, cbSize, "UInt", &AnimationInfo, UInt, 1 )
      return 1
   }
   return 0
}


Gui_Show() {
   global
   if Shown
      return

  ; SysGet, mc, MonitorCount
  ; Loop, %mc%
  ;     Gui, %A_Index%:Show
    Gui, Show
   Shown = 1
}

Gui_Hide() {
   global
   tooltip,
   if !Shown
     return
   
  ; SysGet, mc, MonitorCount
  ; Loop, %mc% + 1
  ;     Gui, %A_Index%:Hide
   
   Gui, Hide 
   Shown =
}

hide_gui:
   Stop_Drawing = 1
   Gui_Hide()
   WinActivate(ActiveID)                   ; activate last active window
Return

handle_exit:
   Gui Destroy
   ReleaseDC(hw_frame,hdc_frontbuffer)     ; free lock?
   DeleteObject( hbm_printwindow)
   DeleteDC(     hdc_printwindow)
   DeleteObject( hbm_window)
   DeleteDC(     hdc_window)
   DeleteObject( hbm_backbuffer)
   DeleteDC(     hdc_backbuffer)
 ;  WinActivate ahk_id %ActiveID%    ; activate last active window
ExitApp

; --------------------------------------------------------------------------------------------------
; 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





Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 16th, 2009, 1:29 am 
Offline

Joined: August 1st, 2009, 12:24 pm
Posts: 46
OK, another update. I added in an new hotkey that doesn't show minimized windows. (I changed the controls to Ctrl+Q = all windows, Ctrl+Alt+Q = only non-minimized windows)


Code:
;v1.20090914 -- expose.ahk - Thumbnails of windows over the working area, active thumbnails when no zoom,                                            ;zoomed window means redraw only zoomed window
; new minimized windows

OnExit handle_exit
#SingleInstance Force
#NoEnv
SetBatchLines -1
SetWinDelay 0               ; larger values also fail under heavy load, changing windows
Process Priority,,Above Normal
CoordMode Mouse, Relative

Main:
  Gosub, Read_Keymapping
  Gosub, Read_Config
  Gosub, Detect_Screensize
  Gosub, Create_Gui
  Gosub, Create_Buffers
  ; wait for key/mouse
Return

Read_Keymapping:
   Hotkey, #TAB,      Window_Choose
   Hotkey, ^q,     Window_Choose
   ;Hotkey, ^+q,   Current_App_Choose
   Hotkey ^!q,   Window_Choose_No_Minimize
   ;Hotkey ^!+q,   Current_App_No_Minimize

   Hotkey, IfWinActive, »Expose«
      Hotkey, #TAB    ,      Window_Activate
      Hotkey, MButton ,     Window_Activate
      Hotkey, LButton ,      Window_Activate
      HotKey, RButton ,     Window_Preview
      Hotkey, Esc     ,        hide_gui
      Hotkey, WheelUp ,    Handle_Zoom
      Hotkey, WheelDown, Handle_Zoom
      Hotkey, +MButton ,   handle_exit ; panik-key
      Hotkey, #F12 ,          Debug_Info
Return

Read_Config:
   min_w                        = 110  ; min width of windows to be shown
   min_h                        = 110  ; min height of windows to be shown (hides taskbar etc)
   scale_thumb_space    = 1    ; scale thumbnails to best fit to box?
   live_redraw                 = 1   ; 1/0 = Yes/No
   time_gap                   = 100   ; ms, time left for others after each thumbnail draw
   thumb_border             = 1   ; 1 for gap between thumbnail  s
   animate_in_delay       = 5
   animate_in_steps       = 5
   animate_out_delay     = 5
   animate_out_steps     = 5
   show_taskbar             = 1
   main_monitor   = 1 ; or 2 or 3 if you like
   ;fade_in_steps           = 5
   ;fade_in_delay           = 5
   ;fade_out_steps         = 5
   ;fade_out_delay         = 50
   quality_low                = 3 ; allowed: 1 (terrible) , 3 (accepatable) 4 (good = slow)
   quality_high               = 4 ; allowed: 1 (terrible) , 3 (accepatable) 4 (good = slow)
   BackGroundColor       = 004E98
   count := 0
   counter := 0
   zoom_preview = 0.8
   zoom_maximized = 1 ; // 1=on ; 0=off ; allow to zoom more than real size
   do_zoom := 0  ; // off at first
   old_ids_count =  -1 ;
   show_minimized := 1 ;
   minimized_counter := 0 ;
Return

Debug_Info:
ListLines

Window_Hidden() {
   global
   Return w < min_w or h < min_h or title ="»Expose«" or title =""
}

Handle_Zoom:
   If (do_zoom = 0 and ( A_ThisHotKey = "WheelUp" or A_ThisHotKey = "^+Up" ))
   {
      zoom_preview = 0 ; start at 100% to make it look seemless
      gosub Window_Preview ; activate Preview by Scrolling , eg. zooming
   }

   If (do_zoom = 1 and zoom_preview =0 and ( A_ThisHotKey = "WheelDown" or A_ThisHotKey = "^+Down" ))
      gosub Window_Preview ; deactivate zoom


   If (zoom_preview < 4 and ( A_ThisHotKey = "WheelUp" or A_ThisHotKey = "^+Up" ))
      zoom_preview += 0.05         ; sqrt(sqrt(2))
   If (zoom_preview >  0 and ( A_ThisHotKey = "WheelDown" or A_ThisHotKey = "^+Down" ))
      zoom_preview -= 0.05
   TrayTip,,% "Zoom = " Round(100*(1+zoom_preview)) "%"
Return

In(x,a,b) {                      ; closest number to x in [a,b]
   IfLess x,%a%, Return a
   IfLess b,%x%, Return b
   Return x
}


Detect_ScreenSize:

    ; Copy bounds of all monitors to an array.
    SysGet, mc, MonitorCount
    Loop, %mc%
        SysGet, mon%A_Index%, MonitorWorkArea, %A_Index%
   
  Th=0
  Tw=0
  Ty=0
  Tx=0

 
  if show_taskbar and mc = 1
  {   
   WinGetPos,Tx,Ty,Tw,Th,ahk_class Shell_TrayWnd,,,
  }
   ; Default
   WorkArea_Top    :=      ( Tw > Th  and  Tx = 0  and  Ty = 0) * Th
   WorkArea_Left   :=      ( Tw < Th  and  Tx = 0  and  Ty = 0) * Tw
   WorkArea_Height := A_ScreenHeight - ( Tw > Th  ) * Th
   WorkArea_Width  := A_ScreenWidth  - ( Tw < Th  ) * Tw
 
  if show_taskbar and mc > 1
  {   
    md := main_monitor ; // change this where you want to show your thumbnails Number of Monitor
    ; fix for dual monitor
    WorkArea_Top    := mon%md%Top
    WorkArea_Left   := mon%md%Left
    WorkArea_Width  := mon%md%Right - mon%md%Left
    WorkArea_Height := mon%md%Bottom - mon%md%Top
  }

 
 ; TrayTip,,% "Taskbar = " Tx " " Ty " " Tw " " Th " " A_ScreenWidth " " A_ScreenHeight " mc: " mc
  ; if Ty > A_ScreenHeight then Taskbar is "below" mon1
  ; if Ty < 0 Tastbar is above mon1
Return

Create_Gui:
  Gui +AlwaysOnTop -Caption  +Toolwindow +Owner +LastFound
  ;Gui Color, %BackGroundColor%
 
  ; create blank screens for non-main monitor
  ; SysGet, mc, MonitorCount
  ;   Loop, %mc%
  ;  {   
  ;    SysGet, mon%A_Index%, MonitorWorkArea, %A_Index%
  ;    md := A_Index
  ;    WorkArea_Top    := mon%md%Top
  ;    WorkArea_Left   := mon%md%Left
  ;    WorkArea_Width  := mon%md%Right - mon%md%Left
  ;    WorkArea_Height := mon%md%Bottom - mon%md%Top
  ; 
  ;    Gui +AlwaysOnTop -Caption  +Toolwindow +Owner +LastFound
  ;    Gui Color, %BackGroundColor%
  ;    Gui Show,  Hide w%WorkArea_Width% h%WorkArea_Height% x%WorkArea_Left% y%WorkArea_Top%, »Expose%A_Index%«
  ;  }

   ; Last
   Gui Show, Hide  w%WorkArea_Width% h%WorkArea_Height% x%WorkArea_Left% y%WorkArea_Top%, »Expose«

  ;Gui, Add, Pic, x0 y0 w%WorkArea_Width% h%WorkArea_Height%, c:\test.bmp
  DetectHiddenWindows ON
  WinGet Expose_ID , ID, »Expose«
  WinGet Desktop_ID, ID, Program Manager
  DetectHiddenWindows OFF
Return

Create_Buffers:
  hdc_frontbuffer  := GetDC( Expose_ID )

  hdc_printwindow := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_printwindow := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_printwindow,hbm_printwindow)

  hdc_thumbnails  := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_thumbnails  := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_thumbnails,hbm_thumbnails)

  hdc_backbuffer  := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_backbuffer  := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_backbuffer,hbm_backbuffer)

  hdc_desktop     := CreateCompatibleDC(    hdc_frontbuffer)
  hbm_desktop     := CreateCompatibleBitmap(hdc_frontbuffer,WorkArea_Width,WorkArea_Height)
  hbm_old         := SelectObject(          hdc_desktop,hbm_desktop)

  Gui Show
  PaintDesktop( hdc_frontbuffer ) ; 0=window, 1=Child(no toolbars)
  BitBlt(hdc_desktop     , 0, 0, WorkArea_Width, WorkArea_Height
      ,  hdc_frontbuffer , 0, 0 ,0xCC0020) ; SRCCOPY
  BitBlt(hdc_thumbnails  , 0, 0, WorkArea_Width, WorkArea_Height
      ,  hdc_frontbuffer , 0, 0 ,0xCC0020) ; SRCCOPY
  Gui Hide

Return

Window_Choose:
   WinGet ActiveID, ID, A
   show_minimized := 1
   gosub fill_mini_List

   SetTimer Window_Choose_Thread, 0       ; new thread to make thumbnail draws interruptible
Return

Window_Choose_No_Minimize:
   WinGet ActiveID, ID, A
   show_minimized := 0

   SetTimer Window_Choose_Thread, 0       ; new thread to make thumbnail draws interruptible
Return

;Current_App_Choose:
;   WinGet, activeProcessName, ProcessName, A
;   show_minimized := 1
;   gosub fill_mini_list_current         ; I'm sure there's an easier way, but too lazy and unskilled :P
;   
;   SetTimer Window_Choose_Thread, 0       ; new thread to make thumbnail draws interruptible
;return

Window_Choose_Thread:
   Stop_Drawing  =
   yield         := time_gap        ; yield time to other tasks after each thumbnail drawn
   SetTimer Window_Choose_Thread, OFF     ; run once
   GoSub Window_Info           ; list window IDs, sizes, etc.
   Gosub Animate_In

  GoSub Draw_Thumbnails
Return

Window_Activate:
   Stop_Drawing = 1
   MouseGetPos X, Y
   pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols
   task_id := task_ids_%pos%

   If (pos <= num_win and X >= 0 and X <= WorkArea_Width and Y >= 0 and Y <= WorkArea_Height)
   {
      Gosub Animate_Out
      WinActivate(task_id)                 ; activate selected window
      Gosub fade_out
   }

   if ( show_minimized)
      gosub restore_position

   Gui_Hide()
Return

WinActivate(ID) {
   WinGet ,ActiveID2, ID, A
   if ActiveID2 <> ID
       WinActivate ahk_id %ID%
}

Window_Info:
   WinGet ids, list,,,Program Manager      ; all active windows-tasks (processes)
   task_info =
   num_win = 0
 
   Loop %ids%
   {
   task_id := ids%A_Index%              ; id of this window
   WinGetClass class, ahk_id %task_id%
   WinGetTitle title, ahk_id %task_id%
   WinGetPos,,, w, h, ahk_id %task_id%
   If Window_Hidden()                 ; small windows not shown (e.g. taskbar)
      Continue
   num_win++
   task_info := task_info class "|" ids%A_Index% "|" w "|" h ","
   TrayTip, task_info
   }
   
   StringTrimRight task_info, task_info, 1 ; remove last comma
   Sort task_info, D,                      ; keep positions of thumbnails
   cols := ceil(sqrt(num_win))
   rows := ceil(sqrt(num_win))
 
   If (cols*(rows-1) >= num_win)           ; minimize table size
       rows--
   
   thumb_w := WorkArea_Width  // cols
   thumb_h := WorkArea_Height // rows
   ratio_of_screen := WorkArea_Width / WorkArea_Height * rows / cols
 
   Loop Parse, task_info, `,               ; task_info has been set up in get_wins()
   {
      StringSplit z, A_LoopField, |        ; separate ID, w, h
      task_ids_%A_Index% := z2             ; needed for activation
      if ( z2 = ActiveID )
      pos = %A_Index%
     w%A_Index% := z3                     ; w
      h%A_Index% := z4                     ; h
      ratio_of_win := z3 / z4              ; w/h
      If ( scale_thumb_space  )  {
         If (ratio_of_win < ratio_of_screen) { ; tall window
            thumb_h%A_Index% := thumb_h - thumb_border
            thumb_w%A_Index% := Floor(thumb_w * ratio_of_win / ratio_of_screen) - thumb_border
         } Else {                              ; wide window
            thumb_w%A_Index% := thumb_w - thumb_border
            thumb_h%A_Index% := Floor(thumb_h * ratio_of_screen / ratio_of_win) - thumb_border
         }
      } Else {
         thumb_w%A_Index% := z3//cols - 2*thumb_border
         thumb_h%A_Index% := z4//cols - 2*thumb_border  ; cols >= rows, keep aspect ratio of window
      }
   
     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%
      }
   }
Return

Draw_Thumbnails:

   
    If ( Stop_Drawing )
   {
      tooltip,
           Return
   }

   
   SetStretchBltMode(hdc_thumbnails,quality_high) ; 3: Lower quality at 1st draw
 
   WinGet ids_count, list,,,Program Manager      ; all active windows-tasks (processes)
   if ( old_ids_count <> ids_count )
      gosub Window_Info   ; detect if windows were added in expose mode
   
   ; layout changed full refresh (start with empty desktop)
   if ( cols <> old_cols or rows <> old_rows)
       BitBlt( hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
           , hdc_desktop, 0, 0 , 0xCC0020) ; SRCCOPY
       BitBlt( hdc_thumbnails, 0, 0, WorkArea_Width, WorkArea_Height
           , hdc_desktop, 0, 0 , 0xCC0020) ; SRCCOPY
   
   ; clear "now empty" places , only needed when less, more are filled automatically
   gaps := old_num_win - num_win
    if ( gaps )
   {
     loop %gaps%
     {
        a_index2 := num_win + gaps
       pos_x := thumb_w * Mod(A_Index2-1,cols)
       pos_y := thumb_h * ((A_Index2-1)//cols)
 
       BitBlt( hdc_thumbnails, pos_x, pos_y, thumb_w, thumb_h
              , hdc_desktop,    pos_x, pos_y ,0xCC0020) ;
   
        BitBlt( hdc_frontbuffer, pos_x, pos_y, thumb_w, thumb_h
              , hdc_thumbnails,  pos_x, pos_y ,0xCC0020) ;
      }   
   }

    old_ids_count := ids_count
    old_rows := rows
    old_cols := cols
   old_num_win := num_win

    Loop %num_win%  {                       ; task_ids, dims have been set up in win_list
     ;  Sleep %yield%                        ; CPU cycles to other tasks @ frequent redraw
      If Stop_Drawing
         Break
   
      pos_x := thumb_w * Mod(A_Index-1,cols)
      pos_y := thumb_h * ((A_Index-1)//cols)
     
      PrintWindow( task_ids_%A_Index%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
   
      BitBlt( hdc_thumbnails, pos_x , pos_y, thumb_w, thumb_h
            , hdc_desktop   , pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
   
      ; prevent flicker with backbuffer , store it in hdc_thumbnails for later reuse!
      StretchBlt( hdc_thumbnails , 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, pos_x , pos_y , thumb_w, thumb_h
             ,hdc_thumbnails,  pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
   }

 
   MouseGetPos X, Y
      pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols
 
   if pos > 0 ; dual monitor !
     winid := task_ids_%pos%
   
   WinGetTitle title, ahk_id %winid%

   tooltip, %title% ; + %old_pos2% + %pos%

   ; force Gui to foreground, maybe some windows have been opened or closed
 ; Gui_Show()
     
    If live_redraw
    {
       Gosub draw_active
       Return
      }
Return

Window_Preview:

   do_zoom := 1 - do_zoom ; toggle state
   BitBlt(hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
             ,  hdc_thumbnails, 0, 0 ,0xCC0020) ; SRCCOPY
   
return

draw_active:

  ; are gui windows also showing up and make a wrong ids_count ?
   WinGet ids_count, list,,,Program Manager      ; all active windows-tasks (processes)
   if ( old_ids_count <> ids_count ) {
      gosub,  Window_Info   ; detect if windows were added in expose mode
      gosub,  Draw_Thumbnails ;
      return
  }
  ; we need to check here if there are new windows, or windows missing and refresh the whole
  ; thing accordingly. maybe brutforce, destroy gui and paint as we have clicked "Window_Choose"
  ; only skip animation

  zoom :=  zoom_preview

  sleep %yield%                        ; CPU cycles to other tasks @ frequent redraw
       If ( Stop_Drawing )
   {
      tooltip,
           Return
   }
      MouseGetPos X, Y
      pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols
 
      if pos > 0
       winid := task_ids_%pos%

      pos_x := thumb_w * Mod(pos -1,cols)
      pos_y := thumb_h * ((pos -1)//cols)

      A_Index2 = 0

      if pos > 0 
         A_Index2 := pos

       task_id := task_ids_%A_Index2%
   
   diff_x := WorkArea_Left
   diff_y := WorkArea_Top
   diff_w := WorkArea_Width
   diff_h := WorkArea_Height


   WinGetPos, diff_x, diff_y, diff_w, diff_h , ahk_id %task_id%
   diff_x := X - diff_w // 2 ; -  ( WorkArea_Width - WorkArea_Left ) // 2

   diff_y := Y - diff_h // 2 ; - ( WorkArea_Height - WorkArea_Top ) // 2
   



   diff_x := diff_x - ( pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 ) - WorkArea_Left
   diff_y := diff_y - ( pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 ) - WorkArea_Top
   diff_w := diff_w - ( thumb_w%A_Index2% )
   diff_h := diff_h - ( thumb_h%A_Index2% )

   
      ; you can comment this line to get bit speed, acceptable
      BitBlt( hdc_backbuffer, 0, 0, WorkArea_Width, WorkArea_Height
              , hdc_thumbnails, 0, 0, 0xCC0020) ; SRCCOPY
      PrintWindow( task_ids_%A_Index2%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
      SetStretchBltMode(hdc_backbuffer,quality_high) ; 3: Lower quality at 1st draw
      SetStretchBltMode(hdc_frontbuffer,quality_high) ; 3: Lower quality at 1st draw
   
     ; counter for debugging
     counter := counter +1

     if ( do_zoom = 1 ) {   
  ;   tooltip , Drawing Zoomed window %counter%

      x0 := pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 - ( diff_w * zoom  ) // 2
      y0 := pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 - ( diff_h * zoom  ) // 2
      w  := thumb_w%A_Index2% + diff_w * zoom
      h  := thumb_h%A_Index2% + diff_h * zoom

      if ( zoom_maximized ) {
   WinGetPos,,, w_temp, h_temp, ahk_id %task_id%
           
    if ( w > w_temp or h > h_temp )
         {
          w := w_temp
          h := h_temp
          zoom_preview1 := w / ( thumb_w%A_Index2% + diff_w ) - 0.05
          zoom_preview  := h / ( thumb_h%A_Index2% + diff_h ) - 0.05
          if (zoom_preview1 > zoom_preview)
            zoom_preview = zoom_preview1 ; use minimum
         }
      
          ; refresh, prevent flicker
          zoom := zoom_preview
     x0 := pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 - ( diff_w * zoom  ) // 2
           y0 := pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 - ( diff_h * zoom  ) // 2
           w  := thumb_w%A_Index2% + diff_w * zoom
          h  := thumb_h%A_Index2% + diff_h * zoom

        }

      ; if bottom/right of zoomed thumb is out move it back into view
      if x0 + w > WorkArea_Width
        x0 := WorkArea_Width - w

      if y0 + h > WorkArea_Height
        y0 := WorkArea_Height - h

      ; if top/left is out, move it back into view, can lead to clipping of bottom or right !
      if x0 < 0
   x0 := 0 ; // overflow

      if y0 < 0
        y0 := 0 ; // overflow


      StretchBlt( hdc_backbuffer
            , x0
                           , y0
                           , w
                           , h
                           , hdc_printwindow, 0, 0, w%A_Index2%, h%A_Index2% ,0xCC0020) ; SRCCOPY
      BitBlt(hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
               ,  hdc_backbuffer, 0, 0 ,0xCC0020) ; SRCCOPY
   
   }
else  {

     Loop %num_win%  {                       ; task_ids, dims have been set up in win_list
     ;  Sleep %yield%                        ; CPU cycles to other tasks @ frequent redraw
      If Stop_Drawing
         Break
   
      pos_x := thumb_w * Mod(A_Index-1,cols)
      pos_y := thumb_h * ((A_Index-1)//cols)
     
      PrintWindow( task_ids_%A_Index%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
   
      BitBlt( hdc_thumbnails, pos_x , pos_y, thumb_w, thumb_h
            , hdc_desktop   , pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
   
      ; prevent flicker with backbuffer , store it in hdc_thumbnails for later reuse!
      StretchBlt( hdc_thumbnails , 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, pos_x , pos_y , thumb_w, thumb_h
             ,hdc_thumbnails,  pos_x , pos_y ,0xCC0020) ; Clear slot . (could load Image here ?)
     }
}

   
   MouseGetPos X, Y

   pos := 1 + X*cols//WorkArea_Width + Y*rows//WorkArea_Height * cols

   if ( pos > 0 )
     winid := task_ids_%pos%

   if ( pos < 0 )
     tooltip, %pos%

   WinGetTitle title, ahk_id %winid%

   if ( pos > 0 )
      tooltip, %title% ;  + %old_pos2% + %pos%

   

   If live_redraw
   {
      Gosub draw_active
      Return
   }

return

Animate_In:
    if !animate_in_steps
        return

    SetStretchBltMode(hdc_backbuffer, quality_low) ; 3: Lower quality at 1st draw
   
     A_index2 := pos
    pos_x := thumb_w * Mod(A_Index2-1,cols)
    pos_y := thumb_h * ((A_Index2-1)//cols)
 
    PrintWindow(task_ids_%A_Index2%,hdc_printwindow,0)
 
    task_id := task_ids_%A_Index2%
   WinGetPos, diff_x, diff_y, diff_w, diff_h , ahk_id %task_id%

    diff_x := diff_x - ( pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 ) - WorkArea_Left
    diff_y := diff_y - ( pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 ) - WorkArea_Top
    diff_w := diff_w - ( thumb_w%A_Index2% )
    diff_h := diff_h - ( thumb_h%A_Index2% )
   
   Loop %animate_in_steps%
   {
       sleep %animate_in_delay%
       zoom := 1 - ( A_Index / animate_in_steps )
     
        BitBlt( hdc_backbuffer, 0, 0, WorkArea_Width, WorkArea_Height
                 , hdc_thumbnails, 0, 0 , 0xCC0020) ; SRCCOPY
   
      if ( zoom = 0 )
         SetStretchBltMode(hdc_backbuffer, quality_high) ; 3: Lower quality at 1st draw
         StretchBlt( hdc_backbuffer , pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 + diff_x * zoom     
                           , pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 + diff_y * zoom     
                           , thumb_w%A_Index2% + diff_w * zoom   
                           , thumb_h%A_Index2% + diff_h * zoom
                           , hdc_printwindow, 0, 0, w%A_Index2%, h%A_Index2% ,0xCC0020) ; SRCCOPY
     
       if ( zoom = 0 )
         SetStretchBltMode(hdc_backbuffer, quality_low) ; 3: Lower quality at 1st draw
         Gui_Show()
         BitBlt(hdc_frontbuffer, 0, 0 ,WorkArea_Width ,WorkArea_Height
                 ,hdc_backbuffer , 0, 0 ,0xCC0020) ; SRCCOPY
   }

   old_cols := cols ; prevent full refresh on next draw
   old_rows := rows

Return

; should be reverse of animate in ? combine them ...
Animate_Out:
   
   if !animate_out_steps
         return

   A_index2 := pos
    pos_x := thumb_w * Mod(A_Index2-1,cols)
    pos_y := thumb_h * ((A_Index2-1)//cols)
 
    If (!(pos <= num_win and X >= 0 and X <= WorkArea_Width and Y >= 0 and Y <= WorkArea_Height))
       return

   ;SetStretchBltMode(hdc_frontbuffer,quality_low) ;
    PrintWindow( task_ids_%A_Index2%, hdc_printwindow ,0) ; get selected window
   
   ; clear
     BitBlt( hdc_backbuffer, pos_x, pos_y, thumb_w, thumb_h
              , hdc_desktop   , pos_x, pos_y, 0xCC0020) ; clear with desktopimage

   task_id := task_ids_%A_Index2%
   WinGetPos, diff_x, diff_y, diff_w, diff_h , ahk_id %task_id%

   diff_x := diff_x - ( pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 ) - WorkArea_Left
   diff_y := diff_y - ( pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 ) - WorkArea_Top
   diff_w := diff_w - ( thumb_w%A_Index2% )
   diff_h := diff_h - ( thumb_h%A_Index2% )

   SetStretchBltMode(hdc_backbuffer,quality_low) ; 3: Lower quality at 1st draw
    Loop %animate_out_steps%
   {
       sleep %animate_out_delay%
          zoom := ( A_Index / animate_out_steps )
       
      ; you can comment this line to get bit speed, acceptable
      BitBlt( hdc_backbuffer, 0, 0, WorkArea_Width, WorkArea_Height
              , hdc_thumbnails, 0, 0, 0xCC0020) ; SRCCOPY
     
      StretchBlt( hdc_backbuffer, pos_x + (thumb_w - thumb_w%A_Index2% ) // 2 + diff_x * zoom
                           , pos_y + (thumb_h - thumb_h%A_Index2% ) // 2 + diff_y * zoom
                           , thumb_w%A_Index2% + diff_w * zoom
                           , thumb_h%A_Index2% + diff_h * zoom
                           ,hdc_printwindow, 0, 0, w%A_Index2%, h%A_Index2% ,0xCC0020) ; SRCCOPY
   
       BitBlt(hdc_frontbuffer, 0, 0, WorkArea_Width, WorkArea_Height
                ,  hdc_backbuffer, 0, 0 ,0xCC0020) ; SRCCOPY
     }
   
Return

fade_in:
   ; not used ?
Return

fade_out:
   ; fade last animate_out with real desktop
Return


; subroutines by kli6891 to show minimized windows


; generate an array of minimized windows
fill_mini_List:

   minimized_counter := minimized_counter + 1 ; simulate "cleaning" groupadd

   miniList =
   miniCount = 0
   WinGet, listOfWindows, list,,, Program Manager
   Loop %listOfWindows%
   {
      currentWindowID := listOfWindows%A_Index%
      WinGetTitle, title, ahk_id %currentWindowID%
      if (title != "start" && title != "")
      {
         Winget, isMinimize, MinMax, ahk_id %currentWindowID%
         if (isMinimize == -1)
         {
            GroupAdd , mini%minimized_counter% , ahk_id %currentWindowID%
         }
      }
   }
   
   minAnimation(0)
   WinRestore, ahk_group mini%minimized_counter%
return

;generate group of the current process name NOT WORKING YET
;fill_mini_list_current:
;   minimized_counter := minimized_counter + 1 ; simulate "cleaning" groupadd
;
;   miniList =
;   miniCount = 0
;   WinGet, listOfWindows, list,,, Program Manager
;   Loop %listOfWindows%
;   {
;      currentWindowID := listOfWindows%A_Index%
;      WinGetTitle, title, ahk_id %currentWindowID%
;      WinGet, currentProcessName, ProcessName, hiahk_id %currentWindowID%
;      if (title != "start" && title != "")
;      {
;         Winget, isMinimize, MinMax, ahk_id %currentWindowID%
;         if (isMinimize == -1 && currentProcessName == activeProcessName)   ; only if the process name matches also
;         {
;            GroupAdd , mini%minimized_counter% , ahk_id %currentWindowID%
;         }
;      }
;   }
;   
;   minAnimation(0)
;   WinRestore, ahk_group mini%minimized_counter%
;return


; minimize all windows that were previously captured by fill_mini_list
; except if the window is currently active
restore_position:
   WinGet ActiveID, ID, A

   WinMinimize, ahk_group mini%minimized_counter%
   WinActivate ahk_id %ActiveID%
   minAnimation(1)
return


minAnimation(set="")
{
   VarSetCapacity(AnimationInfo, 8,0)
   cbSize := VarSetCapacity(AnimationInfo)
   NumPut(cbSize, AnimationInfo, 0, "UInt")

   if set =
   {
      DllCall("SystemParametersInfo", UInt, 0x48, UInt, cbSize, "UInt", &AnimationInfo, UInt, 1 )
      return NumGet(AnimationInfo,4)
   }
   
   if (set = 0 || set = 1)
   {
      NumPut(cbSize, AnimationInfo, 0, "UInt")
      NumPut(set, AnimationInfo, 4, "Int")
     
      DllCall("SystemParametersInfo", UInt, 0x49, UInt, cbSize, "UInt", &AnimationInfo, UInt, 1 )
      return 1
   }
   return 0
}


Gui_Show() {
   global
   if Shown
      return

  ; SysGet, mc, MonitorCount
  ; Loop, %mc%
  ;     Gui, %A_Index%:Show
    Gui, Show
   Shown = 1
}

Gui_Hide() {
   global
   tooltip,
   if !Shown
     return
   
  ; SysGet, mc, MonitorCount
  ; Loop, %mc% + 1
  ;     Gui, %A_Index%:Hide
   
   Gui, Hide 
   Shown =
}

hide_gui:
   Stop_Drawing = 1
   Gui_Hide()
   WinActivate(ActiveID)                   ; activate last active window
Return

handle_exit:
   Gui Destroy
   ReleaseDC(hw_frame,hdc_frontbuffer)     ; free lock?
   DeleteObject( hbm_printwindow)
   DeleteDC(     hdc_printwindow)
   DeleteObject( hbm_window)
   DeleteDC(     hdc_window)
   DeleteObject( hbm_backbuffer)
   DeleteDC(     hdc_backbuffer)
 ;  WinActivate ahk_id %ActiveID%    ; activate last active window
ExitApp


; --------------------------------------------------------------------------------------------------
; 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





Also, I have an idea on how to implement expos-ing only the current application window. We can minimize all windows, then restore only the windows with the current process name (see my commented section), then after selection, we restore windows back to their previous states.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 16th, 2009, 1:56 pm 
Offline

Joined: March 11th, 2006, 12:44 pm
Posts: 341
Location: Munich, Germany
@kli6891: i put your code in the first-post. also as new download expose-20090916.ahk.

i see in the poll, there is some interest in a rewrite of the script. maybe the old version expose2.ahk could be used as a template for a rewrite, at this point the script was still easy to understand. But instead of direct DLL-Calls i would use the Gdip.ahk include-file. First step would be to build the structure with the main functions and reimplement the features in more simple ways. (Actually there is only "Config, Animate-In, Draw-Display, Animate-Out, Activate-Chosen" ). maybe the temporary reading can be skipped and save as much code as possible. also the config should/could be put in a config.ini, and a little gui to do it on right-click in the tray-icon. Maybe use DeFocus.ahk as an example (for config + gui + icons).


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 17th, 2009, 2:06 am 
Offline

Joined: August 1st, 2009, 12:24 pm
Posts: 46
Just my opinion here, but the defocused script is really messy and hard to use, and might not be a good script to model after.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 17th, 2009, 2:42 am 
Offline

Joined: August 1st, 2009, 12:24 pm
Posts: 46
Another opinion:

I think that rather than rewriting the whole script, perhaps it would be more productive to write sections of the already existing script. That way other features won't be affected (?perhaps this is wrong?).

What I have in mind is that there should be a global array containing the IDs of windows that will be exposed, instead of the workaround now, which is to restore all minimized windows and go from there.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 17th, 2009, 1:22 pm 
the minimization function is really tiny part of the script, i dont mind so much how its implemented. but i am open to suggestions to optimize it.

the script evolved over a long time and new things were added, there are some inconsistency in naming variables. and some parts were hacked with bad copy/paste which works, but makes the script quite large.

also many temporary variables may be removed, because many could be done on-demand. as there is as stated before, always redraw all the time, so no need to optimize the buffers too much, and it should be more reactive to changing windows.

there will be a bufferwindow anyways to prevent flicker, but not more than that. of course the desktop like a blank-canvas with wallpaper will be stored in a buffer for fast bitblt.

also i learned more "tricks" with ahk, or understand the syntax and the language better and there are some parts which can be implemented in a more easy to understand way.

the defocus script was not meant to be as a template how to structure, as its even bigger then the expose script. but only it shows how to use save-able configuration and gui for changing the settings. but there are many others. maybe there is a project/script for nice guis created now, i need to research the scripts & functions a bit.

i will start to build a grid/structure of the new script only containing of functions and comments without code, so have the basics, and then reimplement the features, partly simply copying parts from the old script.

the script is now too big and confusing and refactoring it, means optimizing it in small steps would be much more effort than rewrite it on a weekend and have a nice clean code.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: September 17th, 2009, 2:30 pm 
Offline

Joined: March 11th, 2006, 12:44 pm
Posts: 341
Location: Munich, Germany
Here is the first Version / Structure of the ReWrite of the Script. I found out there are not too many Functions we can skip, if we want to keep nice effects like animation and prevent Flicker with Backbuffer. But the usage of Backbuffer and the Repaint-Routine can be greatly improved.

I Put in Many Comments which should help to understand how the script works, it itself makes it larger, but hopefully easier to understand.


Code:
; v.20090921 -- expose.ahk - Thumbnails of Windows. Clean Rewrite

OnExit Handle_Exit
#include Gdip.ahk ; in library folder or next to this script
#SingleInstance Force
#NoEnv
SetBatchLines -1
SetWinDelay 0               ; larger values also fail under heavy load, changing windows
Process Priority,,Above Normal
CoordMode Mouse, Relative

Main:
   Gosub, Config
   Gosub, Init_Gui
   ;Gosub, Repaint
   ; idle in background, wait for key (Window_Activate)
Return

Config:
   ; -- Keys to Start/Show Expose
   Hotkey, MButton, Window_Choose
   Hotkey, ESC, Handle_Exit
   ;
   ;

   ; -- Keys while in Gui-Mode
   Hotkey, IfWinActive, EXPOSE_GUI
      Hotkey, MButton , Window_Activate
      ;
      ;
      ;
      Hotkey, #F12 , Debug_Info
      Hotkey, ESC , Handle_Exit

   ; -- Predefined Variables and other Configs
   show_win_min_w = 110 ; min width of windows to be shown
   show_win_min_h = 110 ; min height of windows to be shown, hides Taskbar
   cpu_yield = 100 ; ms to wait
   gui_background = 333333
   do_zoom := 0 ;
   ; animate_delay  = 5 ;
   ; show_taskbar   = 1 ; Leave a gap so Taskbar is still visible
   ; main_monitor   = 1 ; (or 2,3,4,...)
   win_count_old := 0
   can_repaint := 1
   ;
   ;
   ;
   ;
Return

Debug_Info:
   ListLines
Return

Init_Gui:
   ; Detect Screensize, means where is the Taskbar, Is it Multi-Monitor ?
   ; ... Either very Short directly here or as a Helper-Function only Returning x0,y0,w,h ?

   ; Start gdi+ , we dont need it until we draw on surface with lines etc.
   if (0) {
      If !pToken := Gdip_Startup()
      {
         MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
         ExitApp
      }
   }
   
   ; Copy bounds of all monitors to an array.
   SysGet, mc, MonitorCount
   Loop, %mc% {
      if ( A_Index > 1 )
         continue
      
      SysGet, mon%A_Index%, MonitorWorkArea, %A_Index%
      md := A_Index
      WorkArea_Top    := mon%md%Top  ; + 50
      WorkArea_Left   := mon%md%Left ; + 50
       WorkArea_Width  := mon%md%Right - mon%md%Left ; - 50
       WorkArea_Height := mon%md%Bottom - mon%md%Top ; - 50
   
      ; create Gui For Each Monitor, because we want to hide them all

      Gui %A_Index%: +AlwaysOnTop -Caption  +Toolwindow +Owner +LastFound ; +OwnDialogs ; +E0x80000        
      Gui %A_Index%:Show,  Show w%WorkArea_Width% h%WorkArea_Height% x%WorkArea_Left% y%WorkArea_Top%, EXPOSE_GUI_%A_Index%
    ;   Gui %A_Index%:Color, %gui_background%
      
   ;   WinSet, TransColor, %gui_backgroundcolor% 128

         hwnd%A_Index% := WinExist() ; grab handle for this new gui-window for later use   
 
   }

   ; Create a Gui, but Hide it Immediately, so preparing in Background, we dont want to see
   ; ... whats going on
   ;Gui Show, Hide ..... , EXPOSE_GUI

   ; Create Buffers
   
   ; Buffer 1: Main-Display "frontbuffer" is the EXPOSE_GUI, the only thing which we SEE
   ; ... nothing to do here, its a real window ! we cannot paint directly on Desktop as
   ; ... we need to remove it when closing Expose. Also the window holds the old "state"
   md := 1 ; use monitor 1 (which should be main-monitor with taskbar by default)
   Width :=  ( mon%md%Right - mon%md%Left )
   Height:=  ( mon%md%Bottom - mon%md%Top )

   WinGet Expose_ID , ID, EXPOSE_GUI_1

   hdc_gui := GetDC( Expose_ID )

   ; Buffer 2: Print-Window; This is our Handle to Read the Current Look of one of the
   ; ... Application-Windows. Is it needed or can we read it directly ?
   hdc_thumb := CreateCompatibleDC(     hdc_gui )
   hbm_thumb := CreateCompatibleBitmap( hdc_gui, Width , Height )
   hdc_thumb_old := SelectObject(        hdc_thumb, hbm_thumb )

   ; Buffer 3: Backbuffer; This holds the Screen for Rendering Our "Scene", We do it in Background,
   ; ... so there is no flicker while Drawing, giving a nice View. This also prevents funny
   ; ... drawings when windows get reaaranged due to chaning of windows.
   ; ... Is it really needed or can we directly paint on the frontbuffer ?
   ; ... One Problem could be flicker, because we clear the "scene" in each round to paint the
   ; ... Desktop-Wallpaper. Done in Realtime will result in flicker as thumbs are hidden by wallpaper.
   ; visible Gui
   ; ???
   hdc_display := CreateCompatibleDC(     hdc_gui )
   hbm_display := CreateCompatibleBitmap( hdc_gui, Width , Height )
   hdc_display_old := SelectObject(        hdc_display, hbm_display )

   ; Buffer 4: Wallpaper; This holds the Wallpaper from Desktop and is the Base for Repaint
   ; ... On each Loop whe paint first the Wallpaper and then the Thumbnails.
   ; ... Optimization is not to clear all from Backbuffer, but draw over the Backbuffer all
   ; ... the time because only little is changing. If we have a Gap, or Window-Rearrangement
   ; ... then we need to copy "repair" this sections with the Wallpaper and the new Thumbnail
   hdc_desktop := CreateCompatibleDC(     hdc_gui )
   hbm_desktop := CreateCompatibleBitmap( hdc_gui, Width , Height )
   hdc_desktop_old := SelectObject(        hdc_desktop, hbm_desktop )
   

   SetStretchBltMode(hdc_thumb   ,4) ;
   SetStretchBltMode(hdc_gui     ,4) ;
   SetStretchBltMode(hdc_display ,4) ;
   SetStretchBltMode(hdc_desktop ,4) ;

   ; to front
   Gui ,Show
   PaintDesktop( hdc_gui ) ; Paint Desktop-Wallpaper on Top of GUI:1
   BitBlt( hdc_desktop , 0,0, Width, Height, hdc_gui , 0,0, 0xCC0020 ) ; Copy Surface of GUI:1 to Buffer:Desktop
   

   ; autostart on launch of expose ??
   Gosub, Window_Choose

   ;Gui 1:Hide
   ; Hide and wait for user to start

   ; Restore Minimized Windows here as we also want to show them in Expose mode
   ; ... Remember their State and Minimize them Later when needed. (When Hide, Close ExposeGUI !)
Return

Window_Hidden( w, h, title, class) {
   global
   Return w < show_min_w or h < show_min_h or InStr(title ,"EXPOSE_GUI_") or title ="" or class ="tooltips_class32"
}

Window_Choose:
   ; Open The Gui (with Animate_In-Effect )
   ; ... and Start Repainting the Thumbnail in a Loop
   ; ... Until User Activates a Window, or Closes/Hides the ExposeGUI
   ; ... Actually Hide/Close also Calls Window_Activate and Activates the old one
   ;Gui 1:Show
   Gui, Show
   Gosub, Repaint
Return

Window_Activate:
   ; Find the Window which is under the Mouse-Pointer (Hovered)
   ; ... And Zoom this Window out with "Animate_Out" and make it the Active One.
   Gui 1:Hide
   can_repaint := 0 ; stop repainting loop
Return

Repaint:
   ; Loop through all Active Tasks and Paint them with help of PrintWindow() to the
   ; ... Backbuffer. Then flip the Backbuffert to the Frontbuffer to show the updated Scene.
   ; ... BitBlt from Backbuffer to Frontbuffer is quite fast.
   ; ... But Update of the Thumbnails could be Painted to Frontbuffer Directly if we are
   ; ... Good in "Repairing" the Gaps etc.
   ; ... Maybe we use the Backbuffer only for one Tile (eg. one Thumbnail + Wallpaper as Background)
   ; ... and Minimize Repainting of screen but Prevent Flicker this way.
   ; ... If we Repaint less pixels with BitBlt (or Strechblt) then the App will be faster / smoother!

   Sleep %cpu_yield% ; give CPU some Rest otherwise Expose tries to grab 100% CPU, always updating windows
   
   ; count visible windows (windows we should paint)
      win_count_old := win_count ;
      win_count := 0
      WinGet task, list,,,Program Manager      ; all active windows-tasks (processes)
        Loop %task% {
         ; if needed Restore part of Wallpaper on this Tile to Backbuffer
         ; copy Applicationwindow to Backbuffer with Printwindow() using StrechBlt to Resize
         ; ... (Minimize it)
         ; ... is Gdip_Worldtransform a better alternative to StrechBlt, or is it internally the same ?
         ; copy Backbuffer to Frontbuffer
         id := task%A_Index%
         WinGetClass class, ahk_id %id%
         WinGetTitle title, ahk_id %id%
         WinGetPos ,,, w,h, ahk_id %id%

         if Window_Hidden(w,h,title,class)
            Continue
         win_count ++
      }
   


   if (do_zoom = 0 or force_refresh = 1) {
      Gui 1:Show
      ; refresh the canvas if number of windows changed, which changes layout !
      ; later only when layout changes (eg. rows and/or cols of thumbnail-grid !)
      if (1 or win_count <> win_count_old ) {
         BitBlt ( hdc_gui    , 0,0,Width,Height, hdc_desktop, 0,0,0xCC0020 ) ; Restore Wallpaper   
      ;   BitBlt ( hdc_display, 0,0,Width,Height, hdc_desktop, 0,0,0xCC0020 ) ; Restore Wallpaper   
      }   
      titles := ""
      win_nr := 0
      WinGet task, list,,,Program Manager      ; all active windows-tasks (processes)
        Loop %task% {
         ; if needed Restore part of Wallpaper on this Tile to Backbuffer
         ; copy Applicationwindow to Backbuffer with Printwindow() using StrechBlt to Resize
         ; ... (Minimize it)
         ; ... is Gdip_Worldtransform a better alternative to StrechBlt, or is it internally the same ?
         ; copy Backbuffer to Frontbuffer
         id := task%A_Index%
         WinGetClass class, ahk_id %id%
         WinGetTitle title, ahk_id %id%
         WinGetPos ,,, w,h, ahk_id %id%

         if Window_Hidden(w,h,title,class)
            Continue

         win_nr ++
         titles := titles "`n" A_Index ": " class ", " title  "(" w  "," h ")"
         
         PrintWindow( 0 , hdc_thumb , 0 )
         PrintWindow( id , hdc_thumb , 0 )

         ;Put the Painted window in
         MouseGetPos X, Y
         X=0
         Y=0
      ; Render into Display_Buffer
         StretchBlt( hdc_gui , (Width / win_count ) * (win_nr - 1 ) + X, 50+Y, w/win_count, w*Height/Width/win_count
                  ,  hdc_thumb ,  0 , 0, w, h,0xCC0020 ) ;
         ;sleep , 100
         BitBlt (hdc_gui, 50,50,300,300,hdc_thumb , 0,0,0xCC0020 ) ;
           BitBlt (hdc_gui , 0,0,Width,Height, hdc_display, 0,0,0xCC0020 ) ; show Display Buffer on Gui   
      }
      
   ;   tooltip, iff
   } else {
      ; Only Repaint the Hovered Window/Thumbnail
      ; ... Here Backbuffer comes Handy, as we keep the current State in Backbuffer
      ; ... and only Paint the Zoomed Thumbnail/Live-Window over the Backbuffer
      ; ... or we use another GUI-Window On-Top and let Windows do the Updating which
      ; ... holds the Zoomed Version
      
   ;   tooltip, elsee
   }
;   tooltip, aaa
   ; As an optimization, we could repaint all Thumbnails in low-priority even if in zoomed mode
   ; like every 10seconds, so we react correctly on changes in them and opened/closed windows.
   ;   MouseGetPos X, Y
   ;   if ( X>0 and Y>0 ) {
   ;      UpdateLayeredWindow(hwnd1, hdc, X, Y, Width, Height)
   ;   }
   ;tooltip , %titles% ,,1

   if ( can_repaint = 1 )
      Goto, Repaint ; call self in a loop
Return

Animate_In:
   ; Make Screenshot of Current Desktop or Active-Window and Un-Zoom it into Thumbnail - Possition
   ; .. This makes Expose MUCH more integrated. Small Animation , Big Effect
Return

Animate_Out:
   ; Simulate Zoom Back to Real size
Return

; I cant remember but there was some sense in using the "Shown" -Variable,
; ... maybe this is not used/needed anymore ?

Gui_Show() {
   ; prevent showing twice when active already
}

Gui_Hide() {
   ; hide only when visible
}

Handle_Exit:
   ; Clean Up all Resources so we dont get MemoryLeaks when Closing Expose
   ; for each monitor
    SysGet, mc, MonitorCount
   Loop, %mc% {
      Gui %A_Index%: Destroy
   }

;

   ReleaseDC(hw_frame,hdc_gui)

   SelectObject(hdc_display,hdc_display_old )
   DeleteObject(hbm_display)
   DeleteDC(    hdc_display)

   SelectObject(hdc_thumb,hdc_thumb_old)
   DeleteObject(hbm_thumb)
   DeleteDC(    hdc_thumb)

   SelectObject(hdc_desktop,hdc_desktop_old)
   DeleteObject(hbm_desktop)
   DeleteDC(    hdc_desktop)

   Gui Destroy

   Gdip_Shutdown(pToken)
ExitApp

; -- Library now will be #include Gdip.ahk
; vim:ts=3:sw=3:ft=c

; -- Missing in GDIP !!!
 
PaintDesktop(  hdc ) {
   return DllCall("PaintDesktop", UInt, hdc )
}

CreateCompatibleBitmap( hdc , w, h ) {
     return DllCall("gdi32.dll\CreateCompatibleBitmap", UInt,hdc, Int,w, Int,h)
}


SetStretchBltMode( hdc , value ) {
     return DllCall("gdi32.dll\SetStretchBltMode", UInt,hdc, "int",value)
}



Last edited by holomind on September 21st, 2009, 11:03 pm, edited 4 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 21st, 2009, 8:17 pm 
Offline

Joined: March 11th, 2006, 12:44 pm
Posts: 341
Location: Munich, Germany
Here is the first -new- version which uses Gdip.ahk, and only displays the current windows in a row. does not much yet. but basics are here. paints desktop to gui and copies windows with help of printwindow() to the gui.

You need Gdip.ahk in the same folder as the script

There are still bugs in it, but you can try and comment the code. If i am in the right direction. I compare the file with my 200909016.ahk version. but with the new one the buffers dont work as expected. but id dont know why. i am testing on the same machine, so it must be somewhere in the script.
the problem is, i write some data into hidden backbuffers hdc_thumb, hdc_display etc. but they dont respond as expected. eg. the hdc_desktop is not filled. ? seems i need to compare the scripts a bit more.

if if dont figure it out, i may just refactor the old script and try to simplify some of the routines. because as i figure out now, there are many vital parts which cannot be removed easily. but the main function for repaint can be improved a lot. because the temporary variables for ids_xxx is not needed. but can be read in realtime from the windows Loop %task%,....


Code:
; v.20090921 -- expose.ahk - Thumbnails of Windows. Clean Rewrite

OnExit Handle_Exit
#include Gdip.ahk ; in library folder or next to this script
#SingleInstance Force
#NoEnv
SetBatchLines -1
SetWinDelay 0               ; larger values also fail under heavy load, changing windows
Process Priority,,Above Normal
CoordMode Mouse, Relative

Main:
   Gosub, Config
   Gosub, Init_Gui
   ;Gosub, Repaint
   ; idle in background, wait for key (Window_Activate)
Return

Config:
   ; -- Keys to Start/Show Expose
   Hotkey, MButton, Window_Choose
   Hotkey, ESC, Handle_Exit
   ;
   ;

   ; -- Keys while in Gui-Mode
   Hotkey, IfWinActive, EXPOSE_GUI
      Hotkey, MButton , Window_Activate
      ;
      ;
      ;
      Hotkey, #F12 , Debug_Info
      Hotkey, ESC , Handle_Exit

   ; -- Predefined Variables and other Configs
   show_win_min_w = 110 ; min width of windows to be shown
   show_win_min_h = 110 ; min height of windows to be shown, hides Taskbar
   cpu_yield = 100 ; ms to wait
   gui_background = 333333
   do_zoom := 0 ;
   ; animate_delay  = 5 ;
   ; show_taskbar   = 1 ; Leave a gap so Taskbar is still visible
   ; main_monitor   = 1 ; (or 2,3,4,...)
   win_count_old := 0
   can_repaint := 1
   ;
   ;
   ;
   ;
Return

Debug_Info:
   ListLines
Return

Init_Gui:
   ; Detect Screensize, means where is the Taskbar, Is it Multi-Monitor ?
   ; ... Either very Short directly here or as a Helper-Function only Returning x0,y0,w,h ?

   ; Start gdi+ , we dont need it until we draw on surface with lines etc.
   if (0) {
      If !pToken := Gdip_Startup()
      {
         MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
         ExitApp
      }
   }
   
   ; Copy bounds of all monitors to an array.
   SysGet, mc, MonitorCount
   Loop, %mc% {
      if ( A_Index > 1 )
         continue
      
      SysGet, mon%A_Index%, MonitorWorkArea, %A_Index%
      md := A_Index
      WorkArea_Top    := mon%md%Top  ; + 50
      WorkArea_Left   := mon%md%Left ; + 50
       WorkArea_Width  := mon%md%Right - mon%md%Left ; - 50
       WorkArea_Height := mon%md%Bottom - mon%md%Top ; - 50
   
      ; create Gui For Each Monitor, because we want to hide them all

      Gui %A_Index%: +AlwaysOnTop -Caption  +Toolwindow +Owner +LastFound ; +OwnDialogs ; +E0x80000        
      Gui %A_Index%:Show,  Show w%WorkArea_Width% h%WorkArea_Height% x%WorkArea_Left% y%WorkArea_Top%, EXPOSE_GUI_%A_Index%
    ;   Gui %A_Index%:Color, %gui_background%
      
   ;   WinSet, TransColor, %gui_backgroundcolor% 128

         hwnd%A_Index% := WinExist() ; grab handle for this new gui-window for later use   
 
   }

   ; Create a Gui, but Hide it Immediately, so preparing in Background, we dont want to see
   ; ... whats going on
   ;Gui Show, Hide ..... , EXPOSE_GUI

   ; Create Buffers
   
   ; Buffer 1: Main-Display "frontbuffer" is the EXPOSE_GUI, the only thing which we SEE
   ; ... nothing to do here, its a real window ! we cannot paint directly on Desktop as
   ; ... we need to remove it when closing Expose. Also the window holds the old "state"
   md := 1 ; use monitor 1 (which should be main-monitor with taskbar by default)
   ;Width :=  ( mon%md%Right - mon%md%Left ) * 2
   ;Height:=  ( mon%md%Bottom - mon%md%Top ) * 2

   WinGet Expose_ID , ID, EXPOSE_GUI_1

   hdc_gui := GetDC( Expose_ID )

   ; Buffer 2: Print-Window; This is our Handle to Read the Current Look of one of the
   ; ... Application-Windows. Is it needed or can we read it directly ?
   hdc_thumb := CreateCompatibleDC(     hdc_gui )
   hbm_thumb := CreateCompatibleBitmap( hdc_gui, Width , Height )
   hdc_thumb_old := SelectObject(        hdc_thumb, hbm_thumb )

   ; Buffer 3: Backbuffer; This holds the Screen for Rendering Our "Scene", We do it in Background,
   ; ... so there is no flicker while Drawing, giving a nice View. This also prevents funny
   ; ... drawings when windows get reaaranged due to chaning of windows.
   ; ... Is it really needed or can we directly paint on the frontbuffer ?
   ; ... One Problem could be flicker, because we clear the "scene" in each round to paint the
   ; ... Desktop-Wallpaper. Done in Realtime will result in flicker as thumbs are hidden by wallpaper.
   ; visible Gui
   ; ???
   hdc_display := CreateCompatibleDC(     hdc_gui )
   hbm_display := CreateCompatibleBitmap( hdc_gui, Width , Height )
   hdc_display_old := SelectObject(        hdc_display, hbm_display )

   ; Buffer 4: Wallpaper; This holds the Wallpaper from Desktop and is the Base for Repaint
   ; ... On each Loop whe paint first the Wallpaper and then the Thumbnails.
   ; ... Optimization is not to clear all from Backbuffer, but draw over the Backbuffer all
   ; ... the time because only little is changing. If we have a Gap, or Window-Rearrangement
   ; ... then we need to copy "repair" this sections with the Wallpaper and the new Thumbnail
   hdc_desktop := CreateCompatibleDC(     hdc_gui )
   hbm_desktop := CreateCompatibleBitmap( hdc_gui, Width , Height )
   hdc_desktop_old := SelectObject(        hdc_desktop, hbm_desktop )
   

   SetStretchBltMode(hdc_thumb   ,4) ;
   SetStretchBltMode(hdc_gui     ,4) ;
   SetStretchBltMode(hdc_display ,4) ;
   SetStretchBltMode(hdc_desktop ,4) ;

   ; to front
   Gui ,Show
   PaintDesktop( hdc_gui ) ; Paint Desktop-Wallpaper on Top of GUI:1
   BitBlt( hdc_desktop , 0,0, Width, Height, hdc_gui , 0,0, 0xCC0020 ) ; Copy Surface of GUI:1 to Buffer:Desktop
   
   ;Height := Height / 2
   ;Width  := Width  / 2

   ; autostart on launch of expose ??
   Gosub, Window_Choose

   ;Gui 1:Hide
   ; Hide and wait for user to start

   ; Restore Minimized Windows here as we also want to show them in Expose mode
   ; ... Remember their State and Minimize them Later when needed. (When Hide, Close ExposeGUI !)
Return

Window_Hidden( w, h, title, class) {
   global
   Return w < show_min_w or h < show_min_h or InStr(title ,"EXPOSE_GUI_") or title ="" or class ="tooltips_class32"
}

Window_Choose:
   ; Open The Gui (with Animate_In-Effect )
   ; ... and Start Repainting the Thumbnail in a Loop
   ; ... Until User Activates a Window, or Closes/Hides the ExposeGUI
   ; ... Actually Hide/Close also Calls Window_Activate and Activates the old one
   ;Gui 1:Show
   Gui, Show
   Gosub, Repaint
Return

Window_Activate:
   ; Find the Window which is under the Mouse-Pointer (Hovered)
   ; ... And Zoom this Window out with "Animate_Out" and make it the Active One.
   Gui 1:Hide
   can_repaint := 0 ; stop repainting loop
Return

Repaint:
   ; Loop through all Active Tasks and Paint them with help of PrintWindow() to the
   ; ... Backbuffer. Then flip the Backbuffert to the Frontbuffer to show the updated Scene.
   ; ... BitBlt from Backbuffer to Frontbuffer is quite fast.
   ; ... But Update of the Thumbnails could be Painted to Frontbuffer Directly if we are
   ; ... Good in "Repairing" the Gaps etc.
   ; ... Maybe we use the Backbuffer only for one Tile (eg. one Thumbnail + Wallpaper as Background)
   ; ... and Minimize Repainting of screen but Prevent Flicker this way.
   ; ... If we Repaint less pixels with BitBlt (or Strechblt) then the App will be faster / smoother!

   Sleep %cpu_yield% ; give CPU some Rest otherwise Expose tries to grab 100% CPU, always updating windows
   
   ; count visible windows (windows we should paint)
      win_count_old := win_count ;
      win_count := 0
      WinGet task, list,,,Program Manager      ; all active windows-tasks (processes)
        Loop %task% {
         ; if needed Restore part of Wallpaper on this Tile to Backbuffer
         ; copy Applicationwindow to Backbuffer with Printwindow() using StrechBlt to Resize
         ; ... (Minimize it)
         ; ... is Gdip_Worldtransform a better alternative to StrechBlt, or is it internally the same ?
         ; copy Backbuffer to Frontbuffer
         id := task%A_Index%
         WinGetClass class, ahk_id %id%
         WinGetTitle title, ahk_id %id%
         WinGetPos ,,, w,h, ahk_id %id%

         if Window_Hidden(w,h,title,class)
            Continue
         win_count ++
      }
   


   if (do_zoom = 0 or force_refresh = 1) {
      Gui 1:Show
      ; refresh the canvas if number of windows changed, which changes layout !
      ; later only when layout changes (eg. rows and/or cols of thumbnail-grid !)
      if (1 or win_count <> win_count_old ) {
         BitBlt ( hdc_gui    , 0,0,Width,Height, hdc_desktop, 0,0,0xCC0020 ) ; Restore Wallpaper   
      ;   BitBlt ( hdc_display, 0,0,Width,Height, hdc_desktop, 0,0,0xCC0020 ) ; Restore Wallpaper   
      }   
      titles := ""
      win_nr := 0
      WinGet task, list,,,Program Manager      ; all active windows-tasks (processes)
        Loop %task% {
         ; if needed Restore part of Wallpaper on this Tile to Backbuffer
         ; copy Applicationwindow to Backbuffer with Printwindow() using StrechBlt to Resize
         ; ... (Minimize it)
         ; ... is Gdip_Worldtransform a better alternative to StrechBlt, or is it internally the same ?
         ; copy Backbuffer to Frontbuffer
         id := task%A_Index%
         WinGetClass class, ahk_id %id%
         WinGetTitle title, ahk_id %id%
         WinGetPos ,,, w,h, ahk_id %id%

         if Window_Hidden(w,h,title,class)
            Continue

         win_nr ++
         titles := titles "`n" A_Index ": " class ", " title  "(" w  "," h ")"
         
         PrintWindow( 0 , hdc_thumb , 0 )
         PrintWindow( id , hdc_thumb , 0 )

         ;Put the Painted window in
         MouseGetPos X, Y
         X=0
         Y=0
      ; Render into Display_Buffer
         StretchBlt( hdc_gui , (Width / win_count ) * (win_nr - 1 ) + X, 50+Y, w/win_count, w*Height/Width/win_count
                  ,  hdc_thumb ,  0 , 0, w, h,0xCC0020 ) ;
         ;sleep , 100
         BitBlt (hdc_gui, 50,50,300,300,hdc_thumb , 0,0,0xCC0020 ) ;
           BitBlt (hdc_gui , 0,0,Width,Height, hdc_display, 0,0,0xCC0020 ) ; show Display Buffer on Gui   
      }
      
   ;   tooltip, iff
   } else {
      ; Only Repaint the Hovered Window/Thumbnail
      ; ... Here Backbuffer comes Handy, as we keep the current State in Backbuffer
      ; ... and only Paint the Zoomed Thumbnail/Live-Window over the Backbuffer
      ; ... or we use another GUI-Window On-Top and let Windows do the Updating which
      ; ... holds the Zoomed Version
      
   ;   tooltip, elsee
   }
;   tooltip, aaa
   ; As an optimization, we could repaint all Thumbnails in low-priority even if in zoomed mode
   ; like every 10seconds, so we react correctly on changes in them and opened/closed windows.
   ;   MouseGetPos X, Y
   ;   if ( X>0 and Y>0 ) {
   ;      UpdateLayeredWindow(hwnd1, hdc, X, Y, Width, Height)
   ;   }
   ;tooltip , %titles% ,,1

   if ( can_repaint = 1 )
      Goto, Repaint ; call self in a loop
Return

Animate_In:
   ; Make Screenshot of Current Desktop or Active-Window and Un-Zoom it into Thumbnail - Possition
   ; .. This makes Expose MUCH more integrated. Small Animation , Big Effect
Return

Animate_Out:
   ; Simulate Zoom Back to Real size
Return

; I cant remember but there was some sense in using the "Shown" -Variable,
; ... maybe this is not used/needed anymore ?

Gui_Show() {
   ; prevent showing twice when active already
}

Gui_Hide() {
   ; hide only when visible
}

Handle_Exit:
   ; Clean Up all Resources so we dont get MemoryLeaks when Closing Expose
   ; for each monitor
    SysGet, mc, MonitorCount
   Loop, %mc% {
      Gui %A_Index%: Destroy
   }

;

   ReleaseDC(hw_frame,hdc_gui)

   SelectObject(hdc_display,hdc_display_old )
   DeleteObject(hbm_display)
   DeleteDC(    hdc_display)

   SelectObject(hdc_thumb,hdc_thumb_old)
   DeleteObject(hbm_thumb)
   DeleteDC(    hdc_thumb)

   SelectObject(hdc_desktop,hdc_desktop_old)
   DeleteObject(hbm_desktop)
   DeleteDC(    hdc_desktop)

   Gui Destroy

   Gdip_Shutdown(pToken)
ExitApp

; -- Library now will be #include Gdip.ahk
; vim:ts=3:sw=3:ft=c

; -- Missing in GDIP !!!
 
PaintDesktop(  hdc ) {
   return DllCall("PaintDesktop", UInt, hdc )
}

CreateCompatibleBitmap( hdc , w, h ) {
     return DllCall("gdi32.dll\CreateCompatibleBitmap", UInt,hdc, Int,w, Int,h)
}


SetStretchBltMode( hdc , value ) {
     return DllCall("gdi32.dll\SetStretchBltMode", UInt,hdc, "int",value)
}



Last edited by holomind on September 21st, 2009, 11:01 pm, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 21st, 2009, 10:19 pm 
Offline

Joined: August 1st, 2009, 12:24 pm
Posts: 46
^^ The above script doesn't seem to work.

Image


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 292 posts ]  Go to page Previous  1 ... 16, 17, 18, 19, 20  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: bekihito and 9 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group