#NoEnv #SingleInstance ,Force ; configuration SetBatchLines ,-1 SetWinDelay ,0 CoordMode ,Mouse,Screen CoordMode ,ToolTip,Screen countps = 0 Main: ; this is only for reading, there is no "Main:" beeing called ;) Gosub, Configuration ; Read from configfile Gosub, CreateFiles ; Create some files and dirs Gosub, GetTaskbarPos ; the taskbar Gosub, GetThumbSizes ; calc the thumbnail dims Gosub, GetWorkPos ; the area of "normal" windows Gosub, GetDockPos ; the deskman-dock Gosub, InitDockGui ; paint dock with picture placeholders Gosub, TRAYMENU ; init trayicon Gosub, WinBottom ; move deskman away (needed when inside taskbar ? Gosub, RefreshDock ; Get Fresh Thumbnails ;Gosub, DEBUG Return Configuration: BinDir = %A_ScriptDir%\DeskManBin TempDir = %A_ScriptDir%\DeskManTemp FastDir = "E:\My Files" file_320mph = %A_ScriptDir%\..\320mph\320mph.ahk file_iview = %BinDir%\i_view32.exe file_spacer = %BinDir%\s.gif appTitle = DeskMan - Dock appName = DeskMan ; perhaps this can be read automatically ? PaperSizeMode = "Off" wincorrect_y = 1 repaintcounter =0 Gosub ,READINI ; Screenlayout: ; 1 2 ; 3 4 ; define some Hot-Keys (win + arrow , or alt-gr + arrow (1 hand only!) Hotkey, <^>!# , Run320Mph ; Launch 320Mph Hotkey, #s , OpenFastDir ; Open special dir Hotkey, <^>!Up , HalfUp ; Resize Window to take upper half Sector( 1 + 2 ) Hotkey, <^>!Down , HalfDown ; Resize Window to take lower half Sector( 3 + 4 ) Hotkey, <^>!Left , HalfLeft ; Resize Window to take left half Sector( 1 + 3 ) Hotkey, <^>!Right , HalfRight ; Resize Window to take right half Sector( 2 + 4 ) Hotkey, <^>!Enter , MaximizeWindow ; Resize; Maximize the window Sector( 1 + 2 + 3 + 4 ) Hotkey, <^>!- , TogglePaperSize ; Resize; Make Portrait-Layout (A4) for reading purpouse Hotkey, #4 , TogglePaperSizeOn ; Resize; A4 Hotkey, #5 , TogglePaperSizeFull ; Resize; Fullscreen (hide taskbar) Hotkey, #6 , TogglePaperSizeOff ; Resize; Maximize restore taskbar (Bug Desktop icons are gone) Hotkey, !F11 , SpecialFullScreen Hotkey, <^>!PgDn , NextWindow ; Alt-Esc (similar Alt-Tab) to Next Window (Task) Hotkey, <^>!PgUp , PrevWindow ; shift Alt-Esc (similar Alt-Tab) to Previous Window (Task) Hotkey, f9 , RefreshDockMax ; Maximize all Windows Hotkey, f12 , RefreshDock ; Repaint Thumbnails and clear cache Hotkey, ^f8 , ReloadScript ; For easier Programming Return CreateFiles: FileCreateDir , %TempDir% FileCreateDir , %BinDir% FileInstall,i_view32.exe, %BinDir%\i_view32.exe,0 FileInstall,s.gif , %BinDir%\s.gif,0 FileInstall,DeskMan.ahk , %BinDir%\DeskMan_v0.5.ahk,0 Return HalfUp: ResizeWin( work_x, work_y, work_w, ceil( work_h / 2 ) ) Return HalfDown: ResizeWin( work_x, ceil( work_h / 2 ), work_w, ceil( work_h / 2) ) Return HalfLeft: ResizeWin( work_x, work_y, ceil( work_w / 2), work_h ) Return HalfRight: ResizeWin( work_x + ceil(work_w / 2) , work_y , ceil(work_w/2), work_h ) Return MaximizeWindow: if PaperSizeMode <> "off" ResizeWin( 0 , 0 , A_ScreenWidth , A_ScreenHeight ) ; fullscreen else ResizeWin( work_x ,work_y , work_w, work_h ) ; without taskbar Return TogglePaperSize: if PaperSizeMode = "off" { WinHide ahk_class Shell_TrayWnd WinHide ahk_id %deskman_id% WinHide,Program Manager SetTimer, RepaintDock , off Gosub, TogglePaperSizeOn SetTimer, RepaintDock , off } else if PaperSizeMode = "on" { WinHide ahk_class Shell_TrayWnd WinHide ahk_id %deskman_id% WinHide,Program Manager SetTimer, RepaintDock , off Gosub, TogglePaperSizeFull SetTimer, RepaintDock , off } else ;if PaperSizeMode = "full" { WinShow ahk_class Shell_TrayWnd ; Taskbar WinShow ahk_id %deskman_id% ; Deskman-Dock WinShow,Program Manager ; Desktop SetTimer, RepaintDock , off Gosub, TogglePaperSizeOff forcerepaint = 1 Gosub, RepaintDock } Return PaperSize: ResizeWin( work_x + work_w / 8 ,work_y , work_w - work_w / 4, work_h ) Return Run320Mph: RunWait,%file_320mph% Return TogglePaperSizeOn: PaperSizeMode="on" WinGet, paperactive_id, ID, A WinSet, Style, -0xC00000, A WinGetActiveStats, title, w, h, x, y if ( w > minwidth ) Gosub, PaperSize SetTimer, RepaintDock , off ; loop until current_id is in front (max is all processes) WinGet, ids, list,,, Program Manager loop, %ids% { win_id :=ids%a_index% if ( win_id <> paperactive_id ) { if ( winIsDocked%win_id% = 1 ) { WinMinimize, ahk_id %win_id% winisminimized%win_id% = %win_id% } } } WinActivate, %paperactive_id% WinShow, %paperactive_id% ;SetTimer, RepaintDock , %repainttimer% Return TogglePaperSizeFull: PaperSizeMode="full" WinGet, paperactive_id, ID, A WinSet, Style, -0xC00000, A WinGetActiveStats, title, w, h, x, y if ( w > minwidth ) Gosub, MaximizeWindow SetTimer, RepaintDock , off ; loop until current_id is in front (max is all processes) WinGet, ids, list,,, Program Manager loop, %ids% { win_id :=ids%a_index% if ( win_id <> paperactive_id ) { if ( winIsDocked%win_id% = 1 ) { WinMinimize, ahk_id %win_id% winisminimized%win_id% = %win_id% } } } WinActivate, %paperactive_id% WinShow, %paperactive_id% ;SetTimer, RepaintDock , %repainttimer% Return TogglePaperSizeOff: PaperSizeMode="off" WinGet, paperactive_id, ID, A WinSet, Style, +0xC00000, A Gosub, WinBottom ; move window away SetTimer, RepaintDock , off ; loop until current_id is in front (max is all processes) WinGet, ids, list,,, Program Manager loop, %ids% { win_id :=ids%a_index% if ( win_id <> paperactive_id ) { if ( winisminimized%win_id% = win_id ) { WinRestore, ahk_id %win_id% Gosub, WinBottom ; move window away winisminimized%win_id% = } } } WinActivate, %paperactive_id% WinShow, %paperactive_id% WinGetActiveStats, title, w, h, x, y if ( w > minwidth ) Gosub, MaximizeWindow ;SetTimer, RepaintDock , %repainttimer% Return OpenFastDir: RunWait, explorer %FastDir% Return SpecialFullScreen: Send, {F11} Gosub, MaximizeWindow Return NextWindow: Send, !+{esc} Return PrevWindow: WinBottom: Send, !{esc} Return InitDockGui: ; add some picture-placeholder (dock-positions) y=0 x=0 Loop, %maxthumbs% { ; Icon Titlebar Gui, Add, Pic , gRestoreWin x%x% y%y% w12 h12 vPicB%a_index% ; add dock-slots to gui y+= 12 ; Thumbnail Gui, Add, Pic , gRestoreWin x%x% y%y% vPic%a_index% ; add dock-slots to gui x2 := x+15 y2 := y-9 ; Title-Text Gui, Font, s6 Gui, Add, Text , vText%a_index% x%x2% y%y2% h12 w2000 r1 #fcfcfc, if ( taskbar_pos = "left" or taskbar_pos ="right" ) y += %thumb_h% ; move pointer for next pos else { x += %thumb_w% ; move pointer for next pos y -= 12 ; restore y titlebar } } Gui, -Caption ; window-style / chrome Gui, +ToolWindow Gui, +AlwaysOnTop +LastFound +Owner ; +Owner prevents a taskbar button from appearing. Gui, Show, x%dock_x% y%dock_y% w%dock_w% h%dock_h% , %appTitle% ; display window/Toolbar WinGet, deskman_id, ID, %appTitle% ; fetch deskman_id for fast checks Gosub, DockToFront ;SetTimer, DockToFront, %repainttimer% Return GetTaskbarPos: ; get dimensions and position of taskbar (specialcase autohide ?) WinGetPos, taskbar_x, taskbar_y, taskbar_w, taskbar_h, ahk_class Shell_TrayWnd ; find out if its on top/left/bottom/right with its x,y ; x0,y0 ( w < h ) means its on top if ( taskbar_x < 10 and taskbar_w < taskbar_h ) taskbar_pos = left ; x0,y0 ( w >= h ) means its on left if ( taskbar_x < 10 and taskbar_w >= taskbar_h ) taskbar_pos = top ; x+,y0 means its on right if ( taskbar_x > 10 ) taskbar_pos = right ; x0,y+ means its on bottom if ( taskbar_y > 10 ) taskbar_pos = bottom Return GetThumbSizes: ; calculate size of a thumbnail thumb_w := ceil( A_ScreenWidth / maxthumbs ) ; width of dock (also thumbnail-width) thumb_h := ceil( A_ScreenHeight / maxthumbs ) ; height of thumbnails Return GetWorkPos: ; default without taskbar if ( insidetaskbar = "1" ) { dock2_w = 0 dock2_h = 0 } else { dock2_w := thumb_w dock2_h := thumb_h } if taskbar_pos = left { work_x := dock2_w + taskbar_w + work_border work_y := work_border - 1 work_w := A_ScreenWidth - taskbar_w - dock2_w -work_border -work_border work_h := A_ScreenHeight - work_border +1 } if taskbar_pos = top { work_x := work_border work_y := dock2_h + taskbar_h + dock_border + work_border - 1 work_w := A_ScreenWidth - work_border -work_border work_h := A_ScreenHeight - taskbar_h - dock_h -work_border -workborder +1 } if taskbar_pos = bottom { work_x := work_border work_y := work_border -1 work_w := A_ScreenWidth -work_border -work_border work_h := A_ScreenHeight - taskbar_h - dock2_h -work_border -work_border +1 } if taskbar_pos = right { work_x := work_border work_y := work_border -1 work_w := A_ScreenWidth - taskbar_w - dock2_w -work_border -work_border work_h := A_ScreenHeight - work_border -work_border +1 } ; irfanview needs integer and not float so lets precalc it here and dont mess with casting later work_h_half := ceil( work_h / 2 ) work_w_half := ceil( work_w / 2 ) ; windows smaller than half get part-shot and not full window minwidth := work_w_half Return GetDockPos: if ( insidetaskbar = 1 ) { if taskbar_pos = right { dock_x := work_x + work_w + work_border + dock_border + 2 dock_y := insidetaskbar_y0 dock_w := thumb_w dock_h := A_ScreenHeight - insidetaskbar_y0 - insidetaskbar_yf } if taskbar_pos = left { dock_x := taskbar_w - dock_border dock_y := insidetaskbar_y0 dock_w := thumb_w dock_h := A_ScreenHeight - insidetaskbar_y0 - insidetaskbar_yf } if taskbar_pos = top { dock_x := insidetaskbar_x0 dock_y := taskbar_h - dock_border dock_w := A_ScreenWidth - insidetaskbar_x0 - insidetaskbar_xf dock_h := thumb_h } if taskbar_pos = bottom { dock_x := insidetaskbar_x0 dock_y := work_y + work_h +work_border + dock_border dock_w := A_ScreenWidth - insidetaskbar_x0 - insidetaskbar_xf dock_h := thumb_h } } else { if taskbar_pos = right { dock_x := work_x + work_w + work_border + dock_border + 2 dock_y := 0 dock_w := thumb_w dock_h := A_ScreenHeight } if taskbar_pos = left { dock_x := taskbar_w - dock_border dock_y := 0 dock_w := thumb_w dock_h := A_ScreenHeight } if taskbar_pos = top { dock_x := 0 dock_y := taskbar_h - dock_border dock_w := A_ScreenWidth dock_h := thumb_h } if taskbar_pos = bottom { dock_x := 0 dock_y := work_y + work_h + work_border + dock_border dock_w := A_ScreenWidth dock_h := thumb_h } } Return ResizeWin( XPos, YPos, XSize, YSize ) { WinGet, active_id, ID, A ; fetch active foreground-window if ( active_id = deskman_id ) return ; correct some pixels in positioning to look "just right" ;YPos := YPos - wincorrect_y ;YSize := YSize + wincorrect_y WinMove, ahk_id %active_id%, , %XPos% , %YPos% , %XSize% , %YSize% ; invalidate window so it gets refreshed next time WinIsDocked%active_id% = ;Gosub, DockToFront } DockToFront: ; force DeskMan to Front Gui, +AlwaysOnTop +LastFound +Owner ; +Owner prevents a taskbar button from appearing. Return RefreshDockMax: maximizeall = 1 Gosub, RefreshDock Return RefreshDock: Gosub, DockToFront SetTimer, RepaintDock , Off ; clear old timers ; remove thumbnails FileDelete, %TempDir%* ; keep active window! WinGet, current_id, ID, A ; start with active Gosub, CaptureThumbActive winIsDocked%capture_id% = 1 capture_id =x ; clear ; loop until current_id is in front (max is all processes) WinGet, ids, list,,, Program Manager loop, %ids% { if ( capture_id <> current_id ) { Gosub, WinBottom if maximizeall = 1 { WinGetActiveStats, title, w, h, x, y if ( w > minwidth ) ResizeWin( work_x ,work_y , work_w, work_h ) } Gosub, CaptureThumbActive winIsDocked%capture_id% = 1 } } forcerepaint = 1 maximizeall = 0 Gosub, RepaintDock return RepaintDock: ; remove closed thumbs but dont do much (as this is done in a loop!) SetTimer, RepaintDock , off ; clear old timers if ( forcedocktofront = "1" ) { Gosub, DockToFront } ; try to add foreground-window to dock if not in there ( changes are good we hit it shortly after start-new) WinGet, active_id, ID, A WinGetTitle, title, ahk_id %active_id% ;tooltip, %repaintcounter% if repaintcounter > 10 { forcerepaint = 1 winIsDocked%active_id% = } ; detect and add new windows if ( winIsDocked%active_id% = "" or winIsDockedTitle%active_id% <> title) { winIsDockedTitle%active_id% := title ; store title and repaint if this changes ;sleep, 500 ; give the window a little bit time to render itself Gosub, CaptureThumbActive winIsDocked%capture_id% = 1 GuiControl,1:,Pic1, *w%thumb_w% *h%thumb_h% %TempDir%\thumb_%capture_id%.bmp } ; test if display has changed ! dockedNewCount = 0 ; start with empty dock Loop, %maxthumbs% { dockIdNew%a_index% = ;clear } ; stack minimized windows into dock ;this way all "non-dead" minimized windows get stacked into dock WinGet, ids, list,,, Program Manager Loop, %ids% { StringTrimRight, id, ids%a_index%, 0 ; find the id of this window if winIsDocked%id% ; is window with this id in dock already ? { dockedNewCount += 1 ; how many slots are used already ? dockIdNew%dockedNewCount% = %id% ; remeber id for this position } } ; fill with file_spacer if empty loop, %maxthumbs% { val1 := DockId%a_index% val2 := DockIdNew%a_index% if ( val1 <> val2 ) { forcerepaint = 1 Gosub, DockToFront } } if forcerepaint <> { dockedCount = 0 ; start with empty dock Loop, %maxthumbs% { dockId%a_index% = ;clear } ; stack minimized windows into dock ;this way all "non-dead" minimized windows get stacked into dock WinGet, ids, list,,, Program Manager Loop, %ids% { StringTrimRight, id, ids%a_index%, 0 ; find the id of this window if winIsDocked%id% ; is window with this id in dock already ? { dockedCount += 1 ; how many slots are used already ? dockId%dockedCount% = %id% ; remeber id for this position title := winIsDockedTitle%id% GuiControl,1:,Pic%dockedCount% , *w%thumb_w% *h%thumb_h% %TempDir%\thumb_%id%.bmp GuiControl,1:,PicB%dockedCount%, *w12 *h12 %TempDir%\thumbB_%id%.bmp if ( forcetitlerepaint = "1" ) { GuiControl,1:,Text%dockedCount%, %title% } } } ; fill with file_spacer if empty loop, %maxthumbs% { if DockId%a_index% = { GuiControl,1:,Pic%a_index%, *w%thumb_w% *h%thumb_h% %file_spacer% } } repaintcounter =0 Gosub, TryResizeDock Gosub, DockToFront } ; end forcerepaint forcerepaint = ; try not to draw in next round (but its multithreaded!) somebody can click restore while repaint, if ( forceautorefresh = "1") { repaintcounter := repaintcounter +1 } SetTimer, RepaintDock , %repainttimer% Return TryResizeDock: if ( forcedocktransparent = "1") { newheight := dockedNewCount * ( thumb_h + 12 ) if ( newheight > dock_h ) newheight := dock_h newwidth := dockedNewCount * thumb_w if ( newwidth > dock_w ) newwidth := dock_w if ( taskbar_pos ="left" or taskbar_pos="right" ) WinMove , ahk_id %deskman_id% ,, %dock_x%, %dock_y%, %dock_w% , %newheight% else WinMove , ahk_id %deskman_id% ,, %dock_x%, %dock_y%, %newwidth% , %dock_h% } Return CaptureThumbActive: WinGet , captureactive_id, ID, A winGetTitle, title , ahk_id %captureactive_id% WinGetClass, class , ahk_id %captureactive_id% ;get Class-name capture_id = if ( title = "" or captureactive_id = deskman_id ) ; skip DeskMan Window (recursion!) return ; skip some programs not good with deskman if class in TPickSessionDlg,TForm,TFormMain,TBaseLoadErrorDlg,Shell_TrayWnd,DV2ControlHost,ZORRO,Progman, tooltips_class32,AutoHotkeyGUI,TForm4,AutoHotkeyGUI,TfrmDUGraph,TNMGraph return Gosub, CaptureThumb return CaptureThumb: capture_id := captureactive_id wingetpos, x, y, width, height, ahk_id %capture_id% ; read width from capture-window if ( width < minwidth ) { ; get picture cropped so we see more detail RunWait,%file_iview% /silent /capture=1 /crop=(0`,0`,%work_w_half%`,%work_h_half%) /resample=(%thumb_w%`,%thumb_h%) /convert=%TempDir%\thumb_%capture_id%.bmp } else { ; get thumb of active window RunWait,%file_iview% /silent /jpgq=100 /capture=1 /resample=(%thumb_w%`,%thumb_h%) /convert=%TempDir%\thumb_%capture_id%.bmp } ; always capture icon and title RunWait,%file_iview% /silent /capture=1 /crop=(0`,0`,24`,24) /resample=(12`,12) /convert=%TempDir%\thumbB_%capture_id%.bmp return RestoreWin: StringReplace, pos , A_GuiControl, Pic SetTimer, RepaintDock , off Gosub, WinBottom ; undo the click on deskman ; find active window, which is on top of stack, DeskMan is active because of click ; get some lookups forcerepaint = 1 dockIdpos := dockId%pos% id := dockId%pos% if ( winIsDocked%id% <> "" ) { ; activate restored id WinActivate, ahk_id %id% WinGetTitle, title, ahk_id %id% wingetpos, x, y, width, height, ahk_id %id% ; only maximize and move big windows, as small ones eg. dialogboxes dont like maximize if ( width > minwidth ) { ResizeWin( %work_x%, %work_y%, %work_w%, %work_h% ) } winIsDocked%id% = ; force repaint in next interval } Gosub, RepaintDock Return ReloadScript: Reload ; Sleep 200 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached. MsgBox, 4,, The script could not be reloaded. Would you like to open it for editing? IfMsgBox, Yes, Edit Return DEBUG: tooltip, %work_x% %work_y% %work_w% %work_h% Return TRAYMENU: Menu,Tray,Add,&Settings,SETTINGS Menu,Tray,Add,DeskMan,ABOUT Menu,Tray,Add Menu,Tray,Add,&About,ABOUT Menu,Tray,Add,E&xit,EXIT Menu,Tray,Default,DeskMan Return ABOUT: about= (LTrim DeskMan `nControl all your Windows, similar to Apple-Dock but different ;) `n`nThis program uses IrFanView by Irfan Skiljan. `nHolomind @2006 (based on) MultiMonMan Skrommel @2006 www.donationcoders.com/skrommel ) MsgBox,0,DeskMan,%about% Return SETTINGS: Gosub,READINI RunWait,%appName%.ini Gosub,READINI Return READINI: IfNotExist,%appName%.ini { ini= (LTrim `;[Settings] `;maxthumbs = 14 ; how many thumbs to show ( screenheight / maxthumbs = thumbheight )? `;work_border = 4 ; looks nicer `;dock_border = 0 ; make a gap between dock and your window. `;repainttimer = 1000 ; msecs `;forcedocktofront=0 ; force at every repaint desman to always on top `;forcedocktransparent=0 ; force at every repaint desman to always on top `;insidetaskbar = 0 ; `;insidetaskbar_x0 = 70 ; when needed move this much (eg. startbutton) `;insidetaskbar_y0 = 30 ; when needed move that much (eg. startbutton) `;insidetaskbar_xf = 200 ; when needed keep free on right (eg. trayicons+clock) `;insidetaskbar_yf = 200 ; when needed keep free on bottom (eg. trayicons+clock) [Settings] maxthumbs=14 work_border=4 dock_border=0 repainttimer=1000 forcetitlerepaint=1 forcedocktofront=0 forcedocktransparent=0 insidetaskbar=0 insidetaskbar_x0=70 insidetaskbar_y0=30 insidetaskbar_xf=200 insidetaskbar_yf=200 ) FileAppend,%ini%,%appName%.ini ini= } IniRead,forcedocktofront ,%appName%.ini,Settings,forcedocktofront IniRead,forcedocktransparent ,%appName%.ini,Settings,forcedocktransparent IniRead,forcetitlerepaint ,%appName%.ini,Settings,forcetitlerepaint IniRead,maxthumbs ,%appName%.ini,Settings,maxthumbs IniRead,work_border ,%appName%.ini,Settings,work_border IniRead,dock_border ,%appName%.ini,Settings,dock_border IniRead,repainttimer ,%appName%.ini,Settings,repainttimer IniRead,insidetaskbar ,%appName%.ini,Settings,insidetaskbar IniRead,insidetaskbar_x0 ,%appName%.ini,Settings,insidetaskbar_x0 IniRead,insidetaskbar_y0 ,%appName%.ini,Settings,insidetaskbar_y0 IniRead,insidetaskbar_xf ,%appName%.ini,Settings,insidetaskbar_xf IniRead,insidetaskbar_yf ,%appName%.ini,Settings,insidetaskbar_yf Return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GuiClose: EXIT: ExitApp