Jump to content
Sign in to follow this  
Alek

Multiple Desktops

Recommended Posts

Alek

This script allows you have multiple "Workspaces", I have tried to make it as simple as possible (Keep it simple, stupid. i love the KISS principle)

It gets a list of all the visable windows (with some exceptions) and hides and stores them in a array, then draw some cool effects :P and tada you have a new "workspace", the GUI has a "preview" of all your desktops (not real time, it takes a screenshot befor changeing desktop).

Bugs:

-Dual Monitor Problem

-Slow and nasty <_< its the hide/show window which is slow

-Dosent always restore all the windows :wacko:

To Do:

-Change desktop while draging windows close to the screen edge and move the window to the next desktop(i have no idea how to :blink:)

-Make i support other then stretched form of wallpaper

Hotkeys:

-ctrl+alt+left/right = change desktop left or right

Edit:

-Added komalos capture behind window UDF (makes it screencap behind the window you want to move to another "workspace")

-Fixed dual monitor

-more small fixes

-Added transition effect (fade or slide)

-Changed _WinAPI_EnumWindowsTop() to WinList(), hopefully it works better.

-Fixed multi wallpaper on XP (i think)

-Bin rewriten, now faster, and better looking :P

-Supports diffrerent wallpapers (just change the wallpaper on the "workspace" the way you normaly change wallpaper ;))

-Uses arrays to store data, instead of Ini

-Works with autoit 3.2.12.1

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#Include <WinAPI.au3>
#Include <ScreenCapture.au3>
#Include <Constants.au3>
#include <Misc.au3>
#NoTrayIcon

Opt("GUIOnEventMode", 1)

;Baisc Settings
Global $Class_Blacklist = "|BasicWindow|SideBar_AppBarWindow|SideBar_AppBarBullet|Progman|Button|ThunderRT6FormDC|ROCKETDOCK|"
Global $Num_Of_Desktop = IniRead(@ScriptDir & "\Data.ini","Setings","Num_Of_Desktop","4")
Global $Gui_Size = IniRead(@ScriptDir & "\Data.ini","Setings","Gui_Size","80")
Global $Slide_Trans = True
Global $Fade_Trans = False
Global $Debug = False
Global $Trans_Speed = 400

;Stuff  that user should be able to control
Global $DesktopSize = WinGetClientSize("Program Manager")
Global Const $Ratio = $DesktopSize[0] / $DesktopSize[1]
Global $Desktop_Data[$Num_Of_Desktop][1]
Global $Desktop_Pic[$Num_Of_Desktop]
Global $Curent_Desktop = 0
Global $Sticky_Window
Global $Hover_Wait_Timer
Global $Form1, $Hover_Form
IniWrite(@ScriptDir & "\Data.ini", "Wallpaper", "Desktop_Default", _Wallpaper_Get())

For $x = 0 To $Num_Of_Desktop -1
    $Desktop_Data[$x][0] = IniRead(@ScriptDir & "\Data.ini","Wallpaper","Desktop_" & $x+1, _Wallpaper_Get())
    ConsoleWrite($Desktop_Data[$x][0] & @CRLF)
Next

Global $Form_Size_X = (($Gui_Size* $Ratio) * $Num_Of_Desktop) + ($Num_Of_Desktop * 5)
Global $Form_Size_Y = $Gui_Size + 10
Global $Default_Gui_Pos = IniRead(@ScriptDir & "\Data.ini","Setings","Default_Gui_Pos", $DesktopSize[0]-25 & "," & $DesktopSize[1]-$Form_Size_Y-32)
$Default_Gui_Pos = StringSplit($Default_Gui_Pos, ",")

$Form1 = GUICreate("", $Form_Size_X + 45, $Form_Size_Y, $Default_Gui_Pos[1], $Default_Gui_Pos[2], $WS_POPUP + $WS_BORDER, $WS_EX_TOPMOST + $WS_EX_TOOLWINDOW)
GUISetBkColor(0xccccff)
$Slide_Button = GUICtrlCreateButton("<", 5, 20,15, $Form_Size_Y - 25)
$Exit_Button = GUICtrlCreateButton("X", 5,5 ,15, 15)
$Slide_Button2 = GUICtrlCreateButton(">", $Form_Size_X + 25, 20,15, $Form_Size_Y - 25)
$Exit_Button2 = GUICtrlCreateButton("X", $Form_Size_X + 25,5 ,15, 15)
;GUICtrlCreateLabel("", 0,0, $Form_Size_X + 25, $Form_Size_X, -1, $GUI_WS_EX_PARENTDRAG)

;GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlSetBkColor($Slide_Button, 0xaaaaff)
GUICtrlSetBkColor($Slide_Button2, 0xaaaaff)
GUICtrlSetBkColor($Exit_Button, 0xaaaaff)
GUICtrlSetBkColor($Exit_Button2, 0xaaaaff)

GUICtrlSetOnEvent($Slide_Button, "_Slide")
GUICtrlSetOnEvent($Exit_Button, "_Exit")
GUICtrlSetOnEvent($Slide_Button2, "_Slide")
GUICtrlSetOnEvent($Exit_Button2, "_Exit")

For $x = 0 To $Num_Of_Desktop - 1
    $Desktop_Pic[$x] = GUICtrlCreatePic($Desktop_Data[$x][0], (($Gui_Size*$Ratio) * $x) + (5 * ($x)) + 25, 5, $Gui_Size * $Ratio, $Gui_Size)
Next

$Hover_Form = GUICreate("", $Gui_Size * $Ratio, $Gui_Size, 30, 5,$WS_POPUP, $WS_EX_TOPMOST + $WS_EX_TOOLWINDOW + $WS_EX_MDICHILD, $Form1)
GUISetBkColor(0xFFFFFF)

$Fade_Form = GUICreate("", $DesktopSize[0], $DesktopSize[1], 0, 0, $WS_POPUP, $WS_EX_TOPMOST + $WS_EX_TOOLWINDOW)
$Fade_Form_Pic = GUICtrlCreatePic("", 0, 0, 0, 0)

GUISetState(@SW_HIDE, $Fade_Form)
GUISetState(@SW_SHOW, $Form1)
GUISetState(@SW_SHOW, $Hover_Form)
WinSetTrans($Form1, "", 255)
WinSetTrans($Fade_Form, "", 255)
WinSetTrans($Hover_Form, "",120)
WinSetOnTop($Form1, "", 1)

While 1
    Sleep(10)
    $Msg = _Effects()
    If $Msg Then _ChangeDesktop($Msg)
    _CheckWallpaper()
    _CheckHotKeys()
WEnd

Func _CheckWallpaper()
    If $Desktop_Data[$Curent_Desktop][0] <> _Wallpaper_Get() Then
        If @OSVersion = "WIN_VISTA" Then
            IniWrite(@ScriptDir & "\Data.ini","Wallpaper","Desktop_" & $Curent_Desktop+1, _Wallpaper_Get())
            $Desktop_Data[$Curent_Desktop][0] = _Wallpaper_Get()
        Else
            FileCopy(_Wallpaper_Get(), @ScriptDir & "\Desktop_" & $Curent_Desktop & ".bmp")
            IniWrite(@ScriptDir & "\Data.ini","Wallpaper","Desktop_" & $Curent_Desktop+1, @ScriptDir & "\Desktop_" & $Curent_Desktop & ".bmp")
            $Desktop_Data[$Curent_Desktop][0] =  @ScriptDir & "\Desktop_" & $Curent_Desktop & ".bmp"
        EndIf
    EndIf
EndFunc

Func _CheckHotKeys()
    If _IsPressed(27) And _IsPressed(11) And _IsPressed(12) Then
        $Sticky_Window = WinGetHandle("")
        If $Curent_Desktop = $Num_Of_Desktop - 1 Then
            _ChangeDesktop(0)
        Else
            _ChangeDesktop($Curent_Desktop + 1)
        EndIf
        
        Do
            Sleep(1)
        Until _IsPressed(27) = 0 Or _IsPressed(11) = 0 Or _IsPressed(12) = 0
    ElseIf _IsPressed(25) And _IsPressed(11) And _IsPressed(12) Then
        $Sticky_Window = WinGetHandle("")
        If $Curent_Desktop = 0 Then
            _ChangeDesktop($Num_Of_Desktop - 1)
        Else
            _ChangeDesktop($Curent_Desktop - 1)
        EndIf
        
        Do
            Sleep(1)
        Until _IsPressed(25) = 0 Or _IsPressed(11) = 0 Or _IsPressed(12) = 0
    EndIf
EndFunc

Func _Effects()
    Local $cur_desktop
    
    $Ginfo = GUIGetCursorInfo($Form1)
    If Not @error Then
        For $x = 0 To $Num_Of_Desktop -1
            If $Ginfo[4] = $Desktop_Pic[$x] Then
                $a_Pos = ControlGetPos($Form1, "", $Desktop_Pic[$x])
                $f_pos = WinGetPos($Form1)
                WinMove($Hover_Form, "", $f_pos[0] + $a_Pos[0] + 1,  $f_pos[1] + $a_Pos[1] + 1, $a_pos[2], $a_pos[3])
                $Hover_Wait_Timer = 0
                $cur_desktop = String($x)
                ExitLoop
            EndIf
        Next
        
        If $x = $Num_Of_Desktop And TimerDiff($Hover_Wait_Timer) > 500 And $Hover_Wait_Timer > 0 Then 
            $a_Pos = ControlGetPos($Form1, "", $Desktop_Pic[$Curent_Desktop])
            $f_pos = WinGetPos($Form1)
            WinMove($Hover_Form, "", $f_pos[0] + $a_Pos[0] + 1,  $f_pos[1] + $a_Pos[1] + 1, $a_pos[2], $a_pos[3])
            $Hover_Wait_Timer = 0
        ElseIf $x = $Num_Of_Desktop And  $Hover_Wait_Timer = 0 Then
            $Hover_Wait_Timer = TimerInit()
        EndIf
        
        If $Ginfo[2] And $Ginfo[4] = 0 And WinActive($Form1) Then
            $a_pos = WinGetPos($Form1)
            While _IsPressed(01)
                If @error Then ExitLoop
                $a_pos[1] = MouseGetPos(1) - $Ginfo[1]
                If $a_pos[1] >= $DesktopSize[1] - $a_pos[3] Then $a_pos[1] = $DesktopSize[1] - $a_pos[3]
                If $a_pos[1] <= 0 Then $a_pos[1] = 0
                WinMove($Form1, "", $a_pos[0], $a_pos[1])
                If MouseGetPos(0) > $DesktopSize[0] / 2 And $a_pos[0] <= 0 Then
                    $a_pos[0] = ($DesktopSize[0]-$a_pos[0]) - $a_pos[2]
                ElseIf MouseGetPos(0) < $DesktopSize[0] / 2 And $a_pos[0] + $a_pos[2] >= $DesktopSize[0] Then
                    $a_pos[0] = ($DesktopSize[0]-$a_pos[0]) - $a_pos[2]
                EndIf
                Sleep(10)
            WEnd
            IniWrite(@ScriptDir & "\Data.ini","Setings","Default_Gui_Pos", $a_pos[0] & "," & $a_pos[1])
        EndIf
    EndIf
    
    $Ginfo = GUIGetCursorInfo($Hover_Form)
    If @error Then Return
    
    If (WinActive($Form1) Or WinActive($Hover_Form)) And $Ginfo[0] > 0 And $Ginfo[0] < $Form_Size_X And $Ginfo[1] > 0  And $Ginfo[1] < $Form_Size_Y  And $Ginfo[2] Then Return $cur_desktop
EndFunc

Func _Slide()
    Local $i_dir,$s_dir = 0
    Switch @GUI_CtrlId
        Case $Slide_Button
            If GUICtrlRead($Slide_Button) = "<" Then $i_dir = 1
            $s_dir = "Right"
        Case $Slide_Button2 
            If GUICtrlRead($Slide_Button2) = ">" Then $i_dir = 1
            $s_dir = "Left"
    EndSwitch
    
    If $i_dir = 0 Then
        _WinSlide($Form1, $s_dir, $i_dir, 15, 25)
    Else
        _WinSlide($Form1, $s_dir, $i_dir, 15, 20)
    EndIf
    
    If GUICtrlRead($Slide_Button) = ">" Then
        GUICtrlSetData($Slide_Button, "<")
        GUICtrlSetData($Slide_Button2, ">")
    Else
        GUICtrlSetData($Slide_Button, ">")
        GUICtrlSetData($Slide_Button2, "<")
    EndIf
    
    Return
EndFunc

Func _WinSlide($s_hwnd, $s_Dir, $i_dir, $i_speed = 10, $i_Stop = 0)
    Local $a_pos = WinGetPos($Form1)
    Local $i_sleeptime = 10
    Local $i_step
    
    Switch $i_dir
        Case 0
            Switch $s_Dir
                Case "Left"
                    For $x = $a_pos[2]-$i_Stop To $i_Stop Step -1 * _Sub($i_Stop, $a_pos[2]) / $i_speed
                        WinMove($s_hwnd, "", $x - $a_pos[2], $a_pos[1])
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", $i_Stop - $a_pos[2] , $a_pos[1])
                Case "Right"
                    For $x = $DesktopSize[0]-($a_pos[2]-$i_Stop) To $DesktopSize[0] - $i_Stop Step _Sub($DesktopSize[0]-($a_pos[2]-$i_Stop),$DesktopSize[0] - $i_Stop) / $i_speed
                        WinMove($s_hwnd, "", $x, $a_pos[1])
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", $DesktopSize[0] - $i_Stop, $a_pos[1])
                Case "Up"
                    For $x = $a_pos[3] To $i_Stop Step -1 * _Sub($i_Stop, $a_pos[3]) / $i_speed
                        WinMove($s_hwnd, "", $a_pos[0], $x - $a_pos[3])
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", $a_pos[0], $i_Stop - $a_pos[3] )
                Case "Down"
                    For $x = $DesktopSize[1]-$a_pos[3] To $DesktopSize[1] - $i_Stop Step _Sub($DesktopSize[1]-$a_pos[3],$DesktopSize[1] - $i_Stop) / $i_speed
                        WinMove($s_hwnd, "", $a_pos[0], $x)
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", $a_pos[0], $DesktopSize[1] - $i_Stop)
            EndSwitch
        Case Else
            Switch $s_Dir
                Case "Left"
                    For $x = $i_Stop To $a_pos[2] - $i_Stop Step _Sub($i_Stop, $a_pos[2]) / $i_speed
                        WinMove($s_hwnd, "", $x - $a_pos[2], $a_pos[1])
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", 0 - $i_Stop, $a_pos[1])
                Case "Right"
                    For $x = $DesktopSize[0] - $i_Stop To $DesktopSize[0]-($a_pos[2]+$i_Stop) Step -1 * _Sub($DesktopSize[0]-($a_pos[2]+$i_Stop),$DesktopSize[0] - $i_Stop) / $i_speed
                        WinMove($s_hwnd, "", $x, $a_pos[1])
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", $DesktopSize[0]-$a_pos[2]+$i_Stop, $a_pos[1])
                Case "Up"
                    For $x = $i_Stop To $a_pos[3] Step _Sub($i_Stop, $a_pos[3]) / $i_speed
                        WinMove($s_hwnd, "", $a_pos[0], $x - $a_pos[3])
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", $a_pos[0], 0 - $i_Stop)
                Case "Down"
                    For $x = $DesktopSize[1] - $i_Stop To $DesktopSize[1]-$a_pos[3]+$i_Stop Step -1 * _Sub($DesktopSize[1]-$a_pos[3],$DesktopSize[1] - $i_Stop) / $i_speed
                        WinMove($s_hwnd, "", $a_pos[0] , $x)
                        Sleep($i_sleeptime)
                    Next
                    WinMove($s_hwnd, "", $a_pos[0], $DesktopSize[1]-$a_pos[3])
            EndSwitch
    EndSwitch
    Return
EndFunc

Func _Sub($s_Num1, $s_Num2)
    If $s_Num1 > $s_Num2 Then Return $s_Num1 - $s_Num2
    Return $s_Num2 - $s_Num1
EndFunc

Func _Exit()
    Exit
EndFunc

Func _Wallpaper_Change($s_BitmapImage, $l_params = 0)
    Local $ai_Ret
    $ai_Ret = DllCall('user32.dll', 'long', 'SystemParametersInfoA', 'long', 20, 'long', 0, 'str', $s_BitmapImage, 'long', $l_params)
    RegWrite('HKEY_CURRENT_USER\Control Panel\Desktop','Wallpaper','REG_SZ',$s_BitmapImage)
    Return $ai_Ret[0]
EndFunc

Func _Wallpaper_Get()
    Return RegRead("HKEY_CURRENT_USER\Control Panel\Desktop","WallPaper")
EndFunc

Func _ScreenShot()
    Local $Reset_WinStyle = False
    ;_SetWinStat($Form1, 1)
    ;_SetWinStat($Hover_Form, 1)
    If _IsPressed(10) Then
        $Old_EX_STYLE = _WinAPI_GetWindowLong($Sticky_Window, $GWL_EXSTYLE) ;tnx komalo for this trick :P
        WinSetTrans($Sticky_Window, "", 255)
        Sleep(50)
        $Reset_WinStyle  = True
    EndIf
    
    _ScreenCapture_Capture(@TempDir & "\Desktop_" & $Curent_Desktop & ".bmp", 0, 0, $DesktopSize[0], $DesktopSize[1], False)
    If $Reset_WinStyle Then _WinAPI_SetWindowLong($Sticky_Window, $GWL_EXSTYLE, $Old_EX_STYLE)
    
    GUICtrlSetImage($Desktop_Pic[$Curent_Desktop], @TempDir & "\Desktop_" & $Curent_Desktop & ".bmp")
    GUICtrlSetImage($Fade_Form_Pic, @TempDir & "\Desktop_" & $Curent_Desktop & ".bmp")
    WinSetTrans($Hover_Form, "", 120)
    ;_SetWinStat($Form1, 2)
    ;_SetWinStat($Hover_Form, 2)
    
    If $Fade_Trans Or $Slide_Trans Then DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Fade_Form, "int", 0, "long", 0x00080000)
EndFunc

Func _ChangeDesktop($s_desktop)
    Local $win, $x
    If $s_desktop = $Curent_Desktop Then Return
    
    $win = _GetWindows()
    _ScreenShot()
    
    If $win[0] > UBound($Desktop_Data,2) - 1 Then ReDim $Desktop_Data[$Num_Of_Desktop][$win[0] + 1]
    For $x = 1 To UBound($Desktop_Data,2) -1
        $Desktop_Data[$Curent_Desktop][$x] = ""
    Next
    
    For $x = 1 To $win[0]
        $Desktop_Data[$Curent_Desktop][$x] = $win[$x]
        If $win[$x] = "" Then ContinueLoop
        _SetWinStat($win[$x], 1)
    Next
    
    For $x =  UBound($Desktop_Data, 2) -1 To 1 Step -1
        If $Desktop_Data[$s_desktop][$x] = "" Then ContinueLoop
        _SetWinStat($Desktop_Data[$s_desktop][$x], 2)
    Next
    
    If _IsPressed(10) Then _SetWinStat($Sticky_Window , 2)

    If $Desktop_Data[$s_desktop][0] <> _Wallpaper_Get() Then _Wallpaper_Change($Desktop_Data[$s_desktop][0], 3)
    
    If $Fade_Trans Then
        DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Fade_Form, "int", $Trans_Speed, "long", 0x00090000)
    ElseIf $Slide_Trans Then
        If $s_desktop > $Curent_Desktop Then
            DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Fade_Form, "int", $Trans_Speed, "long", 0x00050002)
        Else
            DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $Fade_Form, "int", $Trans_Speed, "long", 0x00050001)
        EndIf
    EndIf
    $Curent_Desktop = $s_desktop
EndFunc

Func _SetWinStat($h_wnd, $i_stat)
    Switch $i_stat
        Case 1
            _WinAPI_ShowWindow($h_wnd, @SW_HIDE)
        Case 2
            _WinAPI_ShowWindow($h_wnd, @SW_SHOW)
    EndSwitch
EndFunc

Func _GetWindows()
    Local $aWindows, $i, $s_return, $i_count
    
    $aWindows = WinList()
    For $i =  1 To $aWindows[0][0]
        If $aWindows[$i][0] = "" Then ContinueLoop
        If Not _WinAPI_IsWindowVisible($aWindows[$i][1]) Then ContinueLoop
        If StringInStr($Class_Blacklist, _WinAPI_GetClassName($aWindows[$i][1]) & "|") Then ContinueLoop
        If _IsPressed(10) And $aWindows[$i][1] = $Sticky_Window Then ContinueLoop
        
        $i_count += 1
        If $Debug Then ConsoleWrite($i_count & ": " & $aWindows[$i][1] & " -> " & $aWindows[$i][0] & @CRLF)
        $s_return &= $aWindows[$i][1] & Chr(1)
    Next
    
    Return StringSplit(StringTrimRight($s_return, 1),Chr(1))
EndFunc

Func OnAutoitExit()
    For $y = 0 To UBound($Desktop_Data, 1) -1
        For $x = 0 To UBound($Desktop_Data, 2) -1
            If $Desktop_Data[$y][$x] = "" Then ContinueLoop
            _SetWinStat($Desktop_Data[$y][$x], 2)
        Next
    Next
    
    _Wallpaper_Change(IniRead(@ScriptDir & "\Data.ini", "Wallpaper", "Desktop_Default",_Wallpaper_Get()), 3)
EndFunc
Edited by Alek

[font="Impact"]Never fear, I is here.[/font]

Share this post


Link to post
Share on other sites
Draygoes

What happens if your temp folder gets cleared?


Spoiler

 

"If a vegetarian eats vegetables,What the heck does a humanitarian eat?"

"I hear voices in my head, but I ignore them and continue on killing."

"You have forced me to raise the indifference warning to beige, it's a beige alert people. As with all beige alerts please prepare to think about the possibility of caring."

An optimist says that giving someone power DOESN'T immediately turn them into a sadist. A pessimist says that giving someone power doesn't IMMEDIATELY turn them into a sadist.

 

 

Share this post


Link to post
Share on other sites
BillLuvsU

Your screwed, unless you had the forsight to change that part of the script. =]


[center][/center]Working on the next big thing.Currently Playing: Halo 4, League of LegendsXBL GT: iRememberYhslaw

Share this post


Link to post
Share on other sites
Alek

it should now work better, its now fully comented and alot cleaner :)


[font="Impact"]Never fear, I is here.[/font]

Share this post


Link to post
Share on other sites
L3G3NdKillEr

nice Tool

Great Work!


i'm very responsible, when ever something goes wrong they always say I'm responsible.Life is like an Adventure... BUT COOL GRAPHICS<====================----=LEGEND KILLER=----=========================>

Share this post


Link to post
Share on other sites
Erik.

Does it work when you have 2 monitors?


I little problem, hard to find and fix

Share this post


Link to post
Share on other sites
Robjong

yes, i have it working on 2 monitors atm, nice job :)

Share this post


Link to post
Share on other sites
Alek

you can now drag a window from 1 desktop to another (warping)

if your on the last desktop and try and drag it too the nextone you will end up on the first desktop

same if you try and drag a window past the first desktop, then you will end up on the last desktop


[font="Impact"]Never fear, I is here.[/font]

Share this post


Link to post
Share on other sites
Alek

Bin updated, its now faster and better looking :P


[font="Impact"]Never fear, I is here.[/font]

Share this post


Link to post
Share on other sites
Jochem

doesn't seems to work with 2 monitors. If I swich of one it is working.

is this solvable?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×