AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Exposé Mod

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Smurth



Joined: 13 Dec 2006
Posts: 11

PostPosted: Fri Feb 01, 2008 3:12 pm    Post subject: Exposé Mod Reply with quote

All credits goes to holomind and his incredible script:
http://www.autohotkey.com/forum/viewtopic.php?t=13001

So, what's different:
- complete rewrite, mainly for easy integration into your own script ,
- stripped down script's size ,
- whenever possible, turns labels into functions, in order to have a maximum of local variables ,
- removed all unecessary stuff (animation, etc) ,
- changed the way "not shown windows" are checked ,
- no more screen blinking on script launch ,
- take care of desktop's background changes ,
- cpu usage optimisation.

Code:
#NoEnv
#SingleInstance, Force
SetBatchLines, -1
SetKeyDelay, 0
SetWinDelay, 0
OnExit, CleanExit



;   settings

Expose_MaxWin := 20   ;   maximum number of windows to handle
Expose_Border := 8      ;   border between thumbs



;   GUI init

Gui, +AlwaysOnTop -Caption  +Toolwindow +Owner +LastFound
Gui, Show, Hide w%A_ScreenWidth% h%A_ScreenHeight% x0 y0 , »Expose«
WinGet, Expose_ID , ID



;   hotkeys

Hotkey, MButton , Expose_Show ,AboveNormal
Hotkey, IfWinActive, ahk_id %Expose_ID%
Hotkey, LButton, Expose_Hide



;   global variables

   Loop, %Expose_MaxWin%
      Expose_WIN%A_Index% := true

   hdc_frontbuffer      := GetDC( Expose_ID )

   hdc_printwindow   := CreateCompatibleDC( hdc_frontbuffer )
   hbm_printwindow   := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
   hbm_old            := SelectObject( hdc_printwindow, hbm_printwindow)

   hdc_thumbnails      := CreateCompatibleDC( hdc_frontbuffer )
   hbm_thumbnails   := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
   hbm_old            := SelectObject( hdc_thumbnails, hbm_thumbnails )

   hdc_backbuffer      := CreateCompatibleDC( hdc_frontbuffer )
   hbm_backbuffer      := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
   hbm_old            := SelectObject( hdc_backbuffer, hbm_backbuffer)

   hdc_desktop         := CreateCompatibleDC( hdc_frontbuffer )
   hbm_desktop         := CreateCompatibleBitmap( hdc_frontbuffer, A_ScreenWidth, A_ScreenHeight )
   hbm_old            := SelectObject( hdc_desktop, hbm_desktop )

; other global variables:
;
;     Expose_ID
;     Expose_Cols
;     Expose_Rows
;     Expose_WIN0
;     Expose_Border
;     win_id
;     x
;     y

Return





CleanExit:

   Gui, Destroy
   ReleaseDC( Expose_ID, hdc_frontbuffer )
   ReleaseDC( Expose_ID, hdc_copy )
   DeleteObject( hbm_printwindow )
   DeleteDC( hdc_printwindow )
   DeleteObject( hbm_window )
   DeleteDC( hdc_window )
   DeleteObject( hbm_backbuffer )
   DeleteDC( hdc_backbuffer )
   DeleteObject( hbm_desktop )
   DeleteDC( hdc_desktop )

ExitApp





Expose_Show:

   if Expose_ListWin() {            ; show thumbs only if there's at least one window
      SetStretchBltMode( hdc_thumbnails, 4 )
      Gui Show
      if Wallpaper_IsNew() {      ; updates GUI if wallpaper has changed
         PaintDesktop( hdc_frontbuffer )
         BitBlt( hdc_desktop, 0, 0, A_ScreenWidth, A_ScreenHeight, hdc_frontbuffer, 0, 0, 0xCC0020 )
         }
      Expose_ShowWin()
   }

Return



Wallpaper_IsNew()
{

Static   wallpaper_last

   RegRead, wallpaper, HKEY_CURRENT_USER, Control Panel\Desktop, Wallpaper
   if (wallpaper <> wallpaper_last) {
      wallpaper_last := wallpaper
      return   true
   }

}




Expose_ListWin()
{

Global   Expose_ID

   WinGet id, list
   win_list :=
   Loop %id% {
      win_id := id%A_Index%
      WinGet, style, Style, ahk_id %win_id%         ; ignore windows without title bar
      WinGet, state, MinMax, ahk_id %win_id%      ; ignore minimized windows
      if ( style & 0xC00000 ) and ( state <> "-1" ) and ( win_id <> Expose_ID )
         win_list := win_list . win_id . ","
   }
   StringTrimRight win_list, win_list, 1
   Sort win_list, D,   ; keep positions of thumbnails
   Return win_list
}



Expose_ShowWin()
{

Global   Expose_ID
      , Expose_Cols
      , Expose_Rows
      , Expose_WIN0
      , Expose_Border
      , hdc_frontbuffer
      , hdc_printwindow
      , hdc_thumbnails
      , hdc_desktop

         win_list := Expose_ListWin()         ; get list of windows' id
         StringSplit, num_win, win_list, `,
         num_win := num_win0               ; count windows

         Expose_Cols := ceil(sqrt(num_win))
         Expose_Rows := ceil(num_win / Expose_Cols)

         thumb_w := A_ScreenWidth  // Expose_Cols
         thumb_h := A_ScreenHeight // Expose_Rows
         screen_ratio := A_ScreenWidth / A_ScreenHeight * Expose_Rows / Expose_Cols

         Loop Parse, win_list, `,
         {
            Expose_WIN%A_Index% := A_LoopField         ; store window's id
            WinGetPos,,, w%A_Index%, h%A_Index%, ahk_id %A_LoopField%
            win_ratio := w%A_Index% / h%A_Index%
            If (win_ratio < screen_ratio) {      ; tall window
               thumb_h%A_Index% := thumb_h - 2*Expose_Border
               thumb_w%A_Index% := Floor(thumb_w * win_ratio / screen_ratio) - 2*Expose_Border
            }
            Else {                                 ; wide window
               thumb_w%A_Index% := thumb_w - 2*Expose_Border
               thumb_h%A_Index% := Floor(thumb_h * screen_ratio / win_ratio) - 2*Expose_Border
            }
            if ( thumb_w%A_Index% > w%A_Index% or thumb_h%A_Index% > h%A_Index% ) {
               thumb_w%A_Index% := w%A_Index%
               thumb_h%A_Index% := h%A_Index%
            }
         }
         BitBlt( hdc_thumbnails, 0, 0, A_ScreenWidth, A_ScreenHeight, hdc_desktop, 0, 0 , 0xCC0020)

      Loop %num_win% {
         pos_x := thumb_w * Mod(A_Index-1,Expose_Cols)
         pos_y := thumb_h * ((A_Index-1)//Expose_Cols)

         PrintWindow( Expose_WIN%A_Index%, hdc_printwindow, 0) ; 0=window, 1=Child(no toolbars)
         hdc_target := hdc_thumbnails

         StretchBlt( hdc_target , pos_x + ( thumb_w - thumb_w%A_Index% ) // 2
                     , pos_y + ( thumb_h - thumb_h%A_Index% ) // 2
                     , thumb_w%A_Index%
                     , thumb_h%A_Index%
                     ,hdc_printwindow, 0, 0, w%A_Index%, h%A_Index% ,0xCC0020) ; SRCCOPY
         BitBlt( hdc_frontbuffer, 0 , 0 , A_ScreenWidth, A_ScreenHeight ,hdc_thumbnails,  0 , 0 , 0xCC0020) ; flip
       }
}



Expose_Hide:

   MouseGetPos x, y
   Gui, Hide
   win_id := 1 + x*Expose_Cols//A_ScreenWidth + y*Expose_Rows//A_ScreenHeight * Expose_Cols
   win_id := Expose_WIN%win_id%
   WinActivate,ahk_id %win_id%
   ; WinGetPos,,, x, y, A
   ; MouseMove, x/2, y/2

Return




; --------------------------------------------------------------------------------------------------
; Library: no need to modify below

; Libary (could be put in extra file )
; #include <GDI.ahk>
; for documentation of commands see: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/wingdistart_9ezp.asp

; -- highlevel not direct dllcall mapping , simplifiers
CreateDCBuffer(ByRef hdc_from, ByRef hdc_to, ByRef hbm_to, w ,h ) {
   ; does not work, something wrong with ByRef and global
   hdc_to  := CreateCompatibleDC(hdc_from) ; buffer
   hbm_to  := CreateCompatibleBitmap(hdc_from,w,h)
   old     := SelectObject(hdc_to,hbm_to)
}

; -- mfc wrapper
GetDC( hw ) {
   return DLLCall("GetDC", UInt, hw )
}

CreateDC( driver,device,output,mode  ) {
   return DLLCall("GetDC", UInt, driver, UInt, device, UInt, output, UInt, mode )
}

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

CreateCompatibleDC( hdc ) {
   return DllCall("gdi32.dll\CreateCompatibleDC", UInt,hdc)
}

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

SelectObject( hdc , hbm ) {
   return DllCall("gdi32.dll\SelectObject", UInt,hdc, UInt,hbm)
}

DeleteObject( hbm ) {
   return DllCall("gdi32.dll\DeleteObject", UInt,hbm)   
}

DeleteDC( hdc ) {
   return DllCall("gdi32.dll\DeleteDC", UInt,hdc )
}

ReleaseDC( hwnd, hdc ) {
   return DllCall("gdi32.dll\ReleaseDC", UInt,hwnd,UInt,hdc )
}

PrintWindow( window_id , hdc , mode ) {
   return DllCall("PrintWindow", UInt, window_id , UInt,hdc, UInt, mode)
}

StretchBlt( hdc_dest , x1, y1, w1, h1, hdc_source , x2, y2, w2, h2 , mode) {
   return DllCall("gdi32.dll\StretchBlt"
          , UInt,hdc_dest  , Int,x1, Int,y1, Int,w1, Int,h1
             , UInt,hdc_source, Int,x2, Int,y2, Int,w2, Int,h2
          , UInt,mode)
}

BitBlt( hdc_dest, x1, y1, w1, h1 , hdc_source, x2, y2 , mode ) {
   return DllCall("gdi32.dll\BitBlt"
          , UInt,hdc_dest   , Int, x1, Int, y1, Int, w1, Int, h1
             , UInt,hdc_source    , Int, x2, Int, y2
          , UInt, mode)
}

PaintDesktop(  hdc ) {
   return DllCall("PaintDesktop", UInt, hdc )
}

; constants
; see: http://www.adaptiveintelligence.net/Developers/Reference/Win32API/GDIConstants.aspx
; #SRCCOPY = 0xCC0020



Have fun
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Fri Feb 01, 2008 3:35 pm    Post subject: Reply with quote

Thx for updating this.

Unfortunately, the main problem with this script still remains - the order of thumbs depends on activation.
_________________
Back to top
View user's profile Send private message MSN Messenger
Laszlo



Joined: 14 Feb 2005
Posts: 4016
Location: Pittsburgh

PostPosted: Fri Feb 01, 2008 3:43 pm    Post subject: Reply with quote

It is really fast, but three of my 8 open windows don’t show up: MS World, Total commander and Lotus Notes. Is there something to set?
majkinetor wrote:
the order of thumbs depends on activation
If you don't like it, you can order them by window titles, ID's, etc., as it was done in my mod.
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Fri Feb 01, 2008 4:20 pm    Post subject: Reply with quote

Quote:
If you don't like it, you can order them by window titles, ID's, etc., as it was done in my mod.

I can do it, but can other people do it ?
I was just saying what I find particulary bad in otherwise one of the most interesting scripts at the forum.

Ordering by titles is not enough - besides that, it needs to have the ability to present the same order as in taskbar. As you look at the taskbar all the time, its most natural to order that way, everything else is breaking the main win concept.

Quote:
It is really fast, but three of my 8 open windows don’t show up:

This problem and oposite problem combined with the mentioned one is the reason I don't use this script from the first time. I didn't find time to fix it myself so far, but I plan to do it for a long time. I hoped Smurth did that, but both "problems" remain. Its more conceptual error then script error. Only windows that should be visible in selection screen are those that have taskbar button. Contrary to that, I get all kind of windows and that looks very bad and confusing depending on what apps you use (and there are also some windows that are not visible sometimes). Its the best to show only those windows that are visible on taskbar (and have an option for other windows eventualy)
_________________
Back to top
View user's profile Send private message MSN Messenger
Smurth



Joined: 13 Dec 2006
Posts: 11

PostPosted: Fri Feb 22, 2008 7:34 am    Post subject: Reply with quote

Sorry for the long delay...

Quote:
Unfortunately, the main problem with this script still remains - the order of thumbs depends on activation.


I don't understand what you mean.


Quote:
It is really fast, but three of my 8 open windows don’t show up:


try to replace:
Code:
      if ( style & 0xC00000 ) and ( state <> "-1" ) and ( win_id <> Expose_ID )


with these:
Code:
      WinGetPos,,,w,, ahk_id %win_id%
      if  (style & 0x800000) and (w>0) and ( state <> "-1" ) and ( win_id <> Expose_ID )
Back to top
View user's profile Send private message
Rhys



Joined: 17 Apr 2007
Posts: 722
Location: Florida

PostPosted: Fri Feb 22, 2008 5:05 pm    Post subject: Reply with quote

This is very cool! I am beginning to dislike Java (more than I already did) though, since none of these cool scripts can 'see' the contents of a Java window.
_________________
[Join IRC!]
Back to top
View user's profile Send private message
airjrdn



Joined: 25 Feb 2008
Posts: 35

PostPosted: Mon Feb 25, 2008 4:19 pm    Post subject: Reply with quote

This is pretty awesome.

Quick question though. I use my middle mouse button for two things; scrolling on webpages and opening links in new tabs. Any thoughts on how to either have it not execute when clicking on a text link or when the mouse x/y coords are different from when the wheel was pressed versus when it was released?

BTW, I tried adjusting the script to use the combination of left & right mouse buttons w/the following code replacements, but it just seemed to stop my left mouse button from working nearly everywhere else.

code from script:
Hotkey, MButton , Expose_Show ,AboveNormal

replaced with:
Hotkey, LButton & RButton, Expose_Show ,AboveNormal
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group