 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
Posted: Mon Feb 08, 2010 8:24 pm Post subject: Virtual Desktops & extras for Win7 |
|
|
The following script enable support of vitual desktops and add some cool features to windows management. It has been developed and tested under Win7 and should work on Vista, too. Windows XP is not supported.
The script only contain the bare minimum so you can easily add it to your own work.
Notes:
- I strongly recommand to disable AeroShake.
- Applications run as admin doesn't react to Autohotkey; that is, they can't be move to another desktop and will appear on each desktop, like sticky windows.
Virtual Desktops features:
- Provide horizontal virtual desktops. You can define as many desktops as you like. Switching from a desktop to another produce a nice scrolling effect.
- You can drag a window from a desktop to another.
- Activating a window (by any way) automatically brings you to the desktop containing that window.
- Use WIN+Left or WIN+Right to switch desktop.
- Use WIN+ALT+Left or WIN+ALT+Right to bring the active window to another desktop.
- Use WIN+D to minimize all windows of the current desktop.
- Use WIN+D once again to restore minimized windows.
- Use CTRL+WIN+H to toggle other desks windows visibility from taskbar
- ALT+Enter toggle the active window in fullscreen mode (see below).
Mouse Wheel features:
- Using the wheel under any window will scroll the control under the mouse (and give the focus to the owner window if xWM_ActivateOnWheel is set). Original code from Shimanov: http://www.autohotkey.com/forum/viewtopic.php?t=6772#54821
- Using the wheel under a window's titlebar will change the transparency level of that window.
Right-click under a window's titlebar to access the window options:
- "Fullscreen": put (or restore from) the window in fullscreen mode. That is, removes the menubar and the borders, and then maximize the window.
- "AlwaysOnTop": Toggles the window's AlwaysOnTop state. This won't work with some windows and the AlwaysOnTop state is lost when windows are minimized.
- "Show on all desktops": marks the window as "sticky" (present on every desks).
Other:
You can define functions to be launched when a window of a given WindowClass is run for the first time (see the "OnRun" section in "config.ini")
This script depend on a lightweight/optimized version of Tic's GDI+ library: Original code: http://www.autohotkey.com/forum/viewtopic.php?t=32238
config.ini:
| Code: | [xWM]
; number of virtual desktops (start with 0)
DeskCount=2
; desktop switching speed
DeskSpeed=80
; delay between window switching from a desktop to another (in milliseconds)
WndSwitchDelay=500
; hide tasks of other desktops ?
HideOtherDesks=0
; automatically activate window on mouse wheel ?
ActivateOnWheel=1
; EasyWheel acceleration
WheelAccel=0x280000
; EasyWheel max speed
WheelMaxSpeed=0x1800000
; list of sticky windows class (shown on all desktops). Use ¤ as separator
Sticky=
; structures used internally (do NOT edit manually)
sDesktop=
sMinimized=
[OnRun]
; the following sample launch the "test" function when explorer is run
CabinetWClass=test
[Opt]
OnExitClearTemp=1
OnExitClearRecents=1
[Str]
WinOntop=Always on top
WinSticky=Show on all desktops
WinFullscr=Fullscreen
WinOpacity=Opacity
FnNotDef=Call to a non-existent function
|
xWM.ahk:
| Code: | #NoEnv
#KeyHistory 0
#SingleInstance force
#HotkeyInterval 100
#MaxHotkeysPerInterval 255
#MaxThreadsPerHotkey 1
SetWorkingDir %A_ScriptDir%
Process, Priority,, R
SetWinDelay, -1
SetBatchLines,-1
SetKeyDelay, -1
CoordMode, Mouse, Screen
DetectHiddenWindows, Off
OnExit, CleanAndQuit
SetFormat,FLOAT, 6.2
xMAX := A_ScreenWidth-1
yMAX := A_ScreenHeight-1
xWM_DeskCurrent := 0
OnRun := "`n"
IniRead("config.ini")
Menu, xWM_WinMenu, Add, %Str_WinFullscr%, xWM_WinMenuExec
Menu, xWM_WinMenu, Add, %Str_WinOntop%, xWM_WinMenuExec
Menu, xWM_WinMenu, Add, %Str_WinSticky%, xWM_WinMenuExec
Gdip_StartStop()
if xWM_DeskCount {
DllCall("SetWinEventHook", "uint", 10, "uint", 11, "uint", 0
, "uint", RegisterCallback("xWM_OnDragWindow", "F" )
, "uint", 0, "uint", 0, "uint", 0)
SetTimer, xWM_CheckActive, 250
}
Return
xWM_CheckActive()
{
Global xWM_sMinimized
, xWM_sDesktop
, Str_FnNotDef
, OnRun
Static hActive, OnRunID
hwnd := WinExist("A")
if (hwnd=hActive)
return
hActive := hwnd
WinGet, s, Style, ahk_id %hwnd%
if not (s & 0x80000)
return
if InStr(xWM_sMinimized, hwnd . ",") {
WinSet, Enable,, ahk_id %hwnd%
a := InStr(xWM_sMinimized, ",", 1, InStr(xWM_sMinimized, hwnd . ",") )+1
a := SubStr(xWM_sMinimized, a, InStr(xWM_sMinimized, "¤", 1, a)-a)
StringReplace, xWM_sMinimized, xWM_sMinimized, %hwnd%`,%a%¤
a := a = "Off" ? 255 : a
t := 16
Loop
{
t +=round(A_Index*1.7)
if (t>a) {
a := a = 255 ? "Off" : a
break
}
WinSet,Transparent, %t%, ahk_id %hwnd%
Sleep, 20
}
WinSet,Transparent, %a%, ahk_id %hwnd%
}
else if InStr(xWM_sDesktop, hwnd . ",") {
t := SubStr(xWM_sDesktop, InStr(xWM_sDesktop, ",", 1, InStr(xWM_sDesktop, hwnd . ",")+1)+1, 1)
xWM_SwitchDesk("!" . t)
}
WinGetClass, class, ahk_id %hwnd%
if InStr(OnRun, "`n" . class . "=") && not InStr(OnRunID, hwnd . ",") {
t := hwnd ","
Loop, Parse, OnRunID, `,
{
IfWinExist ahk_id %A_LoopField%
t .= A_LoopField ","
}
OnRunID := t
p := InStr(OnRun, "=", 1, InStr(OnRun, "`n" . class . "="))
t := SubStr(OnRun, p+1, InStr(OnRun, "`n", 1, p+1)-p-1 )
if IsFunc(t)
%t%(hwnd)
else
Msgbox %Str_FnNotDef% : %t%
}
}
xWM_CheckActive:
xWM_CheckActive()
Return
CleanAndQuit()
{
Local s, s0, s1, s2, s3, s4, d
DetectHiddenWindows, On
if (A_ExitReason="Reload") {
d := ""
Loop, Parse, xWM_sDesktop, ¤
{
if not A_LoopField
continue
StringSplit, s, A_LoopField, `,
if WinExist("ahk_id" . s1) {
s2 := s2<xWM_DeskCurrent ? s2-xWM_DeskCurrent+xWM_DeskCount+1 : s2-xWM_DeskCurrent
d .= s1 "," s2 "," s3 "," s4 "¤"
}
}
xWM_sDesktop := d
}
else {
xWM_WinRestore()
Loop, Parse, xWM_sDesktop, ¤
{
StringSplit, s, A_LoopField, `,
WinShow, ahk_id %s1%
WinSet, Enable,, ahk_id %s1%
WinSet, Transparent, %s3%, ahk_id %s1%
}
xWM_sDesktop := ""
xWM_sMinimized := ""
}
IniWrite, %xWM_sDesktop%, config.ini, xWM, sDesktop
IniWrite, %xWM_sMinimized%, config.ini, xWM, sMinimized
Gdip_StartStop()
if Opt_OnExitClearRecents {
EnvGet,s, USERPROFILE
FileDelete, %s%\Recent\*.*
}
if Opt_OnExitClearTemp {
Loop, %A_Temp%\*.*, 1, 1
{
FileSetAttrib, -RS, %A_LoopFileLongPath%
if Instr(FileExist(A_LoopFileLongPath), "D")
FileRemoveDir, %A_LoopFileLongPath%, 1
else
FileDelete, %A_LoopFileLongPath%
}
}
ExitApp
}
CleanAndQuit:
CleanAndQuit()
Return
IniRead(f)
; Read a whole .ini file and creates variables like this:
; %Section%%Key% = %value%
{
Local s, c, p, key, k
FileRead, s, %f%
Loop, Parse, s, `n`r, %A_Space%%A_Tab%
{
c := SubStr(A_LoopField, 1, 1)
if (c="[")
key := SubStr(A_LoopField, 2, -1)
else if (c=";")
continue
else if (key="OnRun")
OnRun .= A_LoopField "`n"
else {
p := InStr(A_LoopField, "=")
if p {
k := SubStr(A_LoopField, 1, p-1)
%key%_%k% := SubStr(A_LoopField, p+1)
}
}
}
}
;
; DESKTOP FUNCTIONS
;
Dwm_RegisterThumbnail(source, target, sx, sy, sw, sh, dx, dy, dw, dh, alpha=255)
{
dwFlags:=0X7
; DWM_TNP_RECTDESTINATION (0x00000001) Indicates a value for rcDestination has been specified.
; DWM_TNP_RECTSOURCE (0x00000002) Indicates a value for rcSource has been specified.
; DWM_TNP_OPACITY (0x00000004) Indicates a value for opacity has been specified.
; DWM_TNP_VISIBLE (0x00000008) Indicates a value for fVisible has been specified.
; DWM_TNP_SOURCECLIENTAREAONLY (0x00000010) Indicates a value for fSourceClientAreaOnly has been specified.
fVisible:=1
fSourceClientAreaOnly:=1
VarSetCapacity(struct,45,0)
VarSetCapacity(thumbnail,4,0)
;struct _DWM_THUMBNAIL_PROPERTIES
NumPut(dwFlags,struct,0,"UInt")
NumPut(dx,struct,4,"Int")
NumPut(dy,struct,8,"Int")
NumPut(dw,struct,12,"Int")
NumPut(dh,struct,16,"Int")
NumPut(sx,struct,20,"Int")
NumPut(sy,struct,24,"Int")
NumPut(sw,struct,28,"Int")
NumPut(sh,struct,32,"Int")
NumPut(alpha,struct,36,"UChar")
NumPut(fVisible,struct,37,"Int")
NumPut(fSourceClientAreaOnly,struct,41,"Int")
DllCall("dwmapi.dll\DwmRegisterThumbnail","UInt",target,"UInt",source,"UInt",&thumbnail)
thumbnail:=NumGet(thumbnail)
DllCall("dwmapi.dll\DwmUpdateThumbnailProperties","UInt",thumbnail,"UInt",&struct)
Return thumbnail
}
Dwm_UnregisterThumbnail(thumbnail)
{
return DllCall("dwmapi.dll\DwmUnregisterThumbnail","UInt",thumbnail)
}
xWM_DoesWinReact(hwnd=0)
{
; Original code by Lexikos: http://www.autohotkey.com/forum/viewtopic.php?p=331659#331659
static WM_KEYDOWN=0x100, WM_KEYUP=0x101, vk_to_use=7
; Test whether we can send keystrokes to this window.
; Use a virtual keycode which is unlikely to do anything:
PostMessage, WM_KEYDOWN, vk_to_use, 0,, ahk_id %hwnd%
if !ErrorLevel
{ ; Seems best to post key-up, in case the window is keeping track.
PostMessage, WM_KEYUP, vk_to_use, 0xC0000000,, ahk_id %hwnd%
return true
}
return false
}
xWM_WinRestore()
; restore all minimized windows
{
Global xWM_sMinimized
Loop, Parse, xWM_sMinimized, ¤
{
if not A_LoopField
continue
StringSplit, s, A_LoopField, `,
WinSet, Enable,, ahk_id %s1%
WinSet, Transparent, %s2%, ahk_id %s1%
}
xWM_sMinimized :=
}
xWM_WinToggle()
; hide or show windows of the current desktop
{
Global xWM_sMinimized
w := A_ScreenWidth
h := A_ScreenHeight
pBitmap := Gdip_BitmapFromScreen(0, 0, w, h, 0x40CC0020)
hdc := CreateCompatibleDC()
hbm := CreateDIBSection(w, h, hdc)
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 1)
Gdip_SetInterpolationMode(G, 1)
Gdip_DrawImage(G, pBitmap, 0, 0, w, h, 0, 0, w, h)
Gdip_DisposeImage(pBitmap)
hwnd := CreateWindowEx("", 0x80800A8, 0x90000000, 0, "Static")
UpdateLayeredWindow(hwnd, hdc, 0, 0, w, h)
if xWM_sMinimized
xWM_WinRestore()
else {
WinGet, id, List
Loop, %id%
{
id := id%A_Index%
WinGet, s, Style, ahk_id %id%
WinGet, t, MinMax, ahk_id %id%
WinGet, a, Transparent, ahk_id %id%
if a is not Integer
a := "Off"
if xWM_DoesWinReact(id) && a && (t>=0) && (s & 0x80000) {
xWM_sMinimized .= id "," a "¤"
WinSet, Transparent, 0, ahk_id %id%
WinSet, Disable,, ahk_id %id%
}
}
WinActivate, Program Manager
}
a := 255
Loop
{
a -=round(A_Index*1.7)
if (a<16)
break
UpdateLayeredWindow(hwnd, hdc, 0, 0, w, h, a)
Sleep, 20
}
Gdip_DeleteGraphics(G)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
WinClose, ahk_id %hwnd%
}
xWM_HideOthersToggle()
{
Global xWM_DeskCurrent
, xWM_HideOtherDesks
, xWM_sDesktop
xWM_ActivateTopmost()
xWM_HideOtherDesks := xWM_HideOtherDesks ? 0 : 1
DetectHiddenWindows, On
Loop, Parse, xWM_sDesktop, ¤
{
StringSplit, s, A_LoopField, `,
if xWM_HideOtherDesks && (s2<>xWM_DeskCurrent)
WinHide, ahk_id %s1%
else
WinShow, ahk_id %s1%
}
DetectHiddenWindows, Off
IniWrite, %xWM_HideOtherDesks%, config.ini, xWM, HideOtherDesks
}
xWM_SwitchDesk(d, st=0)
; switch to the desired desktop
; if d is integer, it's an offset from the current desk
; if d starts with "!", it's an absolute desktop number
; st is the handle of a sticky window
{
Global xWM_sDesktop
, xWM_DeskCurrent
, xWM_DeskCount
, xWM_DeskSpeed
, xWM_HideOtherDesks
, xWM_Sticky
, xMAX
if not xWM_DeskCount
return
SetTimer, xWM_CheckActive, Off
if d is not integer
{
n := SubStr(d, 2)-xWM_DeskCurrent
m := abs(n)
if (m>xWM_DeskCount//2) {
if (n<0)
n := (xWM_DeskCount+1)+n
else
n := n-(xWM_DeskCount+1)
m := abs(n)
}
d := n//m
n := m
}
else
n := 1
speed := d*xWM_DeskSpeed
Loop, %n%
{
x := d>0 ? 0 : -A_ScreenWidth
hwnd := CreateWindowEx("", 0x80800A8, 0x90000000, 0, "Static", x, 0, A_ScreenWidth*2, A_ScreenHeight)
DllCall("SetWindowPos", "UInt", hWnd, "UInt", st, "Int", 0, "Int", 0, "Int", 0, "Int", 0, "UInt", 0x53)
WinGet, id, List
list := ""
Loop, %id%
{
id := id%A_Index%
list := id "," list
}
Loop, Parse, list, `,
{
if not A_LoopField
continue
WinGet, s, Style, ahk_id %A_LoopField%
WinGet, t, MinMax, ahk_id %A_LoopField%
WinGet, a, Transparent, ahk_id %A_LoopField%
WinGetClass, c, ahk_id %A_LoopField%
if a is not Integer
a := "255"
if xWM_DoesWinReact(A_LoopField) && a && (t>=0) && (s & 0x80000) && (A_LoopField<>st) {
if not InStr(xWM_Sticky, c "¤") {
xWM_sDesktop .= A_LoopField "," xWM_DeskCurrent "," a "¤"
WinSet, Disable,, ahk_id %A_LoopField%
WinGetPos, x, y, w, h, ahk_id %A_LoopField%
x := d>0 ? x : x+A_ScreenWidth
Dwm_RegisterThumbnail(A_LoopField, hwnd, 0, 0, w, h, x, y, x+w, y+h, a)
}
WinGet, x, ExStyle, ahk_id %A_LoopField%
if (x & 8)
DllCall("SetWindowPos", "UInt", hWnd, "UInt", A_LoopField, "Int", 0, "Int", 0, "Int", 0, "Int", 0, "UInt", 0x13)
}
}
deskcur := xWM_DeskCurrent
xWM_DeskCurrent += d
if (xWM_DeskCurrent<0)
xWM_DeskCurrent := xWM_DeskCount
else if (xWM_DeskCurrent>xWM_DeskCount)
xWM_DeskCurrent := 0
DetectHiddenWindows, On
Loop, Parse, xWM_sDesktop, ¤
{
if not A_LoopField
continue
StringSplit, s, A_LoopField, `,
if WinExist("ahk_id" . s1) {
if (s2=xWM_DeskCurrent) {
WinShow, ahk_id %s1%
WinGetPos, x, y, w, h, ahk_id %s1%
x := d>0 ? x+A_ScreenWidth : x
Dwm_RegisterThumbnail(s1, hwnd, 0, 0, w, h, x, y, x+w, y+h, s3)
}
}
else
StringReplace, xWM_sDesktop, xWM_sDesktop, %A_LoopField%¤
}
DetectHiddenWindows, Off
Loop, Parse, xWM_sDesktop, ¤
{
if not A_LoopField
continue
StringSplit, s, A_LoopField, `,
if (s2=deskcur)
WinSet, Transparent, 0, ahk_id %s1%
}
x := d>0 ? 0 : -A_ScreenWidth
Loop
{
x -= speed
if ((d<0) && (x>0)) or ((d>0) && (x<-A_ScreenWidth))
break
WinMove, ahk_id %hwnd%, , x, 0
if st {
MouseGetPos, w, h
w -= speed
w := w<32 ? 32 : ( w>A_ScreenWidth-32 ? A_ScreenWidth-32 : w )
MouseMove, %w%, %h%, 0
}
else
Sleep, 10
}
Loop, Parse, xWM_sDesktop, ¤
{
if not A_LoopField
continue
StringSplit, s, A_LoopField, `,
if (s2=xWM_DeskCurrent) {
StringReplace, xWM_sDesktop, xWM_sDesktop, %A_LoopField%¤
s3 := s3=255 ? "Off" : s3
WinSet, Transparent, %s3%, ahk_id %s1%
WinSet, Enable,, ahk_id %s1%
}
else if xWM_HideOtherDesks && (s2=deskcur)
WinHide, ahk_id %s1%
}
WinClose, ahk_id %hwnd%
}
if not st
xWM_ActivateTopmost()
SetTimer, xWM_CheckActive, 250
}
xWM_OnDragWindow(hWinEventHook, event, hWnd, idObject, idChild, dwEventThread, dwmsEventTime )
{
if (event & 1) {
SetTimer, xWM_OnDragWindow, Off
return
}
MouseGetPos, x, y, hwnd
SendMessage, 0x84,, x|y<<16,, ahk_id %hwnd%
if (ErrorLevel=2)
SetTimer, xWM_OnDragWindow, 20
}
xWM_OnDragWindow:
MouseGetPos, x
if not x {
Sleep, xWM_WndSwitchDelay
MouseGetPos, x
if x
return
SetTimer, xWM_OnDragWindow, Off
xWM_SwitchDesk(-1, WinExist("A"))
Sleep, 500
SetTimer, xWM_OnDragWindow, 20
}
else if (x=xMAX) {
Sleep, xWM_WndSwitchDelay
MouseGetPos, x
if (x<>A_ScreenWidth-1)
return
SetTimer, xWM_OnDragWindow, Off
xWM_SwitchDesk(1, WinExist("A"))
Sleep, 500
SetTimer, xWM_OnDragWindow, 20
}
return
;
; WINDOWS FUNCTIONS
;
xWM_ActivateTopmost()
; activate the topmost captioned window
; from the current desktop
{
Global xWM_Sticky
WinGet, id, List
Loop, %id%
{
id := id%A_Index%
WinGet, s, Style, ahk_id %id%
WinGet, xs, ExStyle, ahk_id %id%
WinGet, t, MinMax, ahk_id %id%
WinGet, a, Transparent, ahk_id %id%
WinGetClass, c, ahk_id %id%
if a is not Integer
a := "255"
if not (InStr(xWM_Sticky, c "¤") or (xs & 8)) && a && (t>=0) && (s & 0x80000)
break
}
WinActivate, ahk_id %id%
}
xWM_FullScrToggle(hwnd)
{
Global xWM_sFullScr
if Instr(xWM_sFullScr, hwnd . ",") {
s := SubStr(xWM_sFullScr, InStr(xWM_sFullScr, hwnd . ","))
StringSplit, s, s, `,
if s7
DllCall("SetMenu", "UInt", hwnd, "UInt", s7)
WinSet, Style, %s6%, ahk_id %hwnd%
WinMove, ahk_id %hwnd%,, %s2%, %s3%, %s4%, %s5%
StringReplace, xWM_sFullScr, xWM_sFullScr, %s1%`,%s2%`,%s3%`,%s4%`,%s5%`,%s6%`,%s7%
}
else {
WinGetPos, x, y, w, h, ahk_id %hwnd%
WinGet, s, Style, ahk_id %hwnd%
m := DllCall("GetMenu", "UInt", hwnd)
if m
DllCall("SetMenu", "UInt", hwnd, "UInt", 0)
WinSet, Style, -0x40000, ahk_id %hwnd%
xWM_sFullScr .= hwnd . "," x "," y "," w "," h "," s "," m "*"
WinMove, ahk_id %hwnd%,, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%
}
}
;
; MOUSE FUNCTIONS
;
EasyWheel(d)
; if xWM_ActivateOnWheel if set, check which window is under the mouse and gives it focus if it hasn't already
; then send scroll event to the control under the mouse
; if the mouse is over the titlebar then change the transparency level of the window
; original "Accelerate Wheel" code from Shimanov: http://www.autohotkey.com/forum/viewtopic.php?t=6772#54821
{
Global xWM_WheelAccel
, xWM_WheelMaxSpeed
, xWM_ActivateOnWheel
, Str_WinOpacity
Static t, s, title, title_id
if not d {
if title
WinSetTitle, ahk_id %title_id%,, %title%
title := 0
return
}
if (A_TickCount>500+t) {
t := A_TickCount
s :=0x780000
}
else if (s<xWM_WheelMaxSpeed)
s += xWM_WheelAccel*A_EventInfo
MouseGetPos x, y, hwnd, a, 1
if InStr(a, "ComboLBox") {
if (d=1)
Mouseclick, WU
else if (d=-1)
MouseClick, WD
return
}
SendMessage, 0x84,, x|y<<16,, ahk_id %hwnd%
if (ErrorLevel=2) {
if not title {
WinGetTitle, title, ahk_id %hwnd%
title_id := hwnd
}
WinGet, a, Transparent, ahk_id %hwnd%
if not a
a := 255
a += d*5
if (a<27)
a := 27
else if (a>255)
a := "Off"
WinSet, Transparent, %a%, ahk_id %hwnd%
if (a<>"Off") {
a := 100*a//255 . "%"
WinSetTitle, ahk_id %hwnd%,, %Str_WinOpacity%: %a%
}
SetTimer, EasyWheel, Off
SetTimer, EasyWheel, -500
return
}
h := DllCall("WindowFromPoint", "int", x, "int", y)
if xWM_ActivateOnWheel && (hwnd<>WinExist("A"))
WinActivate, ahk_id %hwnd%
SendMessage, 0x20A, d*s,(y<<16)|x,, ahk_id %h%
}
EasyWheel:
EasyWheel(0)
return
RButton()
{
Global xMAX
, xWM_WinMenu
, xWM_sFullScr
, xWM_Sticky
, Str_WinOnTop
, Str_WinSticky
, Str_WinFullscr
MouseGetPos, x, y, hwnd
WinGet, s, Style, ahk_id %hwnd%
if y {
SendMessage, 0x84,, x|y<<16,, ahk_id %hwnd%
if not ((ErrorLevel & 2) && (s & 0x80000)) {
MouseClick, R,,,, 0, D
return
}
}
WinActivate, ahk_id %hwnd%
KeyWait, RButton
xWM_WinMenu := hwnd
WinGet, s, ExStyle, ahk_id %hwnd%
WinGetClass, c, ahk_id %hwnd%
f := InStr(xWM_sFullScr, hwnd . ",") ? "Check" : "UnCheck"
c := InStr(xWM_Sticky, c . "¤") ? "Check" : "UnCheck"
s := (s & 8) ? "Check" : "UnCheck"
Menu, xWM_WinMenu, %s%, %Str_WinOnTop%
Menu, xWM_WinMenu, %c%, %Str_WinSticky%
Menu, xWM_WinMenu, %f%, %Str_WinFullscr%
Menu, xWM_WinMenu, Show
Sleep, 500
xWM_WinMenu := 0
}
xWM_WinMenuExec()
{
Global Str_WinOntop
, Str_WinSticky
, Str_WinFullscr
, xWM_WinMenu
, xWM_Sticky
if (A_ThisMenuItem=Str_WinOntop)
WinSet, AlwaysOnTop, Toggle, ahk_id %xWM_WinMenu%
else if (A_ThisMenuItem=Str_WinSticky) {
WinGetClass, class, ahk_id %xWM_WinMenu%
if InStr(xWM_Sticky, class . "¤")
StringReplace, xWM_Sticky, xWM_Sticky, %class%¤
else
xWM_Sticky .= class . "¤"
IniWrite, %xWM_Sticky%, config.ini, xWM, Sticky
}
else if (A_ThisMenuItem=Str_WinFullscr)
xWM_FullScrToggle(xWM_WinMenu)
}
xWM_WinMenuExec:
xWM_WinMenuExec()
return
#Include, %A_ScriptDir%\gdi+.ahk
test(hwnd)
{
MsgBox, Explorer will be move to the 2nd desktop.
xWM_SwitchDesk("!1", hwnd)
}
;
; HOTKEYS AND REMAPING
;
; Ctrl+Win+L = debug
^#L:: Listvars
; Control+Alt+Escape = Reload
^!ESC::Reload
; WIN+D = minimize/restore windows
#D:: xWM_WinToggle()
; virtual desktop switching
#Left:: xWM_SwitchDesk(-1)
#Right:: xWM_SwitchDesk(1)
^#Left:: xWM_SwitchDesk(-1, WinExist("A"))
^#Right:: xWM_SwitchDesk(1, WinExist("A"))
; Hide other desks windows toggle
^#H::xWM_HideOthersToggle()
; EasyWheel
WheelUp:: EasyWheel(1)
WheelDown:: EasyWheel(-1)
RButton:: RButton()
RButton Up::
if GetKeyState("RButton")
MouseClick, R,,,, 0, U
return
!Enter::
xWM_FullScrToggle(WinExist("A"))
return
|
gdi+.ahk:
| Code: | Gdip_StartStop()
{
Static pToken
if !pToken
{
If !DllCall("GetModuleHandle", "Str", "gdiplus")
DllCall("LoadLibrary", "Str", "gdiplus")
VarSetCapacity(si, 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UInt*", pToken, "UInt", &si, "UInt", 0)
return
}
DllCall("gdiplus\GdiplusShutdown", "UInt", pToken)
If hModule := DllCall("GetModuleHandle", "Str", "gdiplus")
DllCall("FreeLibrary", "UInt", hModule)
}
;
; WINDOWS FUNCTIONS
;
CreateWindowEx(lpWindowName="", dwExStyle=0x80080, dwStyle=0x90000000, hWndParent="", lpClassName="ObjectivShell", x=0, y=0, w=0, h=0)
; WS_POPUP := 0x80000000
; WS_VISIBLE := 0x10000000
; WS_EX_LAYERED := 0x00080000
; WS_EX_TOOLWINDOW := 0x00000080
; WS_EX_TOPMOST := 0x00000008
{
hwnd := DllCall("CreateWindowEx"
, "uInt", dwExStyle
, "Str", lpClassName
, "Str", lpWindowName
, "uInt", dwStyle
, "Int", x
, "Int", y
, "Int", w
, "Int", h
, "uInt", hWndParent
, "uInt",hMenu
, "uInt", hInstance
, "uInt", lpParam)
if (dwExStyle & 0x10)
DllCall("shell32.dll\DragAcceptFiles", "uInt", hwnd, "uInt", True)
return hwnd
}
UpdateLayeredWindow(hwnd, hdc, x, y, w, h, Alpha=255)
{
return DllCall("UpdateLayeredWindow"
, "UInt", hwnd
, "UInt", 0
, "UInt*", x|y<<32
, "Int64*", w|h<<32
, "UInt", hdc
, "Int64*", 0
, "UInt", 0
, "UInt*", Alpha<<16|0x1000000
, "UInt", 2)
}
;
; GDI FUNCTIONS
;
BitBlt(dDC, dx, dy, dw, dh, sDC, sx, sy, Raster="")
{
Return, DllCall("gdi32\BitBlt"
, "UInt", dDC
, "Int", dx
, "Int", dy
, "Int", dw
, "Int", dh
, "UInt", sDC
, "Int", sx
, "Int", sy
, "UInt", Raster ? Raster : 0x00CC0020)
}
GetDC(hwnd=0)
{
return DllCall("GetDC", "UInt", hwnd)
}
CreateCompatibleDC(hdc=0)
{
return DllCall("CreateCompatibleDC", "UInt", hdc)
}
ReleaseDC(hdc, hwnd=0)
{
return DllCall("ReleaseDC", "UInt", hwnd, "UInt", hdc)
}
DeleteDC(hdc)
{
return DllCall("DeleteDC", "UInt", hdc)
}
SelectObject(hdc, hgdiobj)
{
return DllCall("SelectObject", "UInt", hdc, "UInt", hgdiobj)
}
DeleteObject(hObject)
{
return DllCall("DeleteObject", "UInt", hObject)
}
CreateDIBSection(w, h, hdc, bpp=32, ByRef ppvBits=0)
{
VarSetCapacity(bi, 40, 0)
NumPut(w, bi, 4), NumPut(h, bi, 8), NumPut(40, bi, 0), NumPut(1, bi, 12, "UShort"), NumPut(0, bi, 16), NumPut(bpp, bi, 14, "UShort")
Return DllCall("CreateDIBSection", "UInt" , hdc, "UInt" , &bi, "UInt" , 0, "UInt*", ppvBits, "UInt" , 0, "UInt" , 0)
}
;
; STRUCTURE FUNCTIONS
;
CreateRectF(ByRef RectF, x, y, w, h)
; Creates a RectF object, containing the coordinates and dimensions of a rectangle
{
VarSetCapacity(RectF, 16)
NumPut(x, RectF, 0, "Float"), NumPut(y, RectF, 4, "Float"), NumPut(w, RectF, 8, "Float"), NumPut(h, RectF, 12, "Float")
}
;
; BITMAP FUNCTIONS
;
Gdip_CreateBitmap(Width, Height, Format=0x26200A)
{
DllCall("gdiplus\GdipCreateBitmapFromScan0", "Int", Width, "Int", Height, "Int", 0, "Int", Format, "UInt", 0, "UInt*", pBitmap)
return pBitmap
}
Gdip_BitmapFromHWND(hwnd, w, h)
{
hdc := CreateCompatibleDC(), hbm := CreateDIBSection(w, h, hdc), obm := SelectObject(hdc, hbm)
DllCall("PrintWindow", "UInt", hwnd, "UInt", hdc, "UInt", 0)
pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
Return, pBitmap
}
Gdip_BitmapFromScreen(x, y, w, h, Raster="")
{
chdc := CreateCompatibleDC(), hbm := CreateDIBSection(w, h, chdc), obm := SelectObject(chdc, hbm), hhdc := GetDC()
BitBlt(chdc, 0, 0, w, h, hhdc, x, y, Raster)
ReleaseDC(hhdc)
pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
SelectObject(hhdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
return pBitmap
}
Gdip_CreateBitmapFromFile(sFile)
{
VarSetCapacity(wFile, 1023)
DllCall("kernel32\MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &sFile, "Int", -1, "UInt", &wFile, "Int", 512)
DllCall("gdiplus\GdipCreateBitmapFromFile", "UInt", &wFile, "UInt*", pBitmap)
return pBitmap
}
Gdip_CreateBitmapFromHBITMAP(hBitmap, Palette=0)
{
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "UInt", hBitmap, "UInt", Palette, "UInt*", pBitmap)
return pBitmap
}
Gdip_DisposeImage(pBitmap)
{
return DllCall("gdiplus\GdipDisposeImage", "UInt", pBitmap)
}
Gdip_GetImageWidth(pBitmap)
{
DllCall("gdiplus\GdipGetImageWidth", "UInt", pBitmap, "UInt*", Width)
return Width
}
Gdip_GetImageHeight(pBitmap)
{
DllCall("gdiplus\GdipGetImageHeight", "UInt", pBitmap, "UInt*", Height)
return Height
}
Gdip_BlurBitmap(pBitmap, Blur)
{
sWidth := Gdip_GetImageWidth(pBitmap), sHeight := Gdip_GetImageHeight(pBitmap)
dWidth := sWidth//Blur, dHeight := sHeight//Blur
pBitmap1 := Gdip_CreateBitmap(dWidth, dHeight)
G1 := Gdip_GraphicsFromImage(pBitmap1)
Gdip_SetInterpolationMode(G1, 7)
Gdip_DrawImage(G1, pBitmap, 0, 0, dWidth, dHeight, 0, 0, sWidth, sHeight)
Gdip_DeleteGraphics(G1)
Gdip_DisposeImage(pBitmap)
pBitmap2 := Gdip_CreateBitmap(sWidth, sHeight)
G2 := Gdip_GraphicsFromImage(pBitmap2)
Gdip_SetInterpolationMode(G2, 7)
Gdip_DrawImage(G2, pBitmap1, 0, 0, sWidth, sHeight, 0, 0, dWidth, dHeight)
Gdip_DeleteGraphics(G2)
Gdip_DisposeImage(pBitmap1)
return pBitmap2
}
;
; GRAPHICS FUNCTIONS
;
Gdip_SetSmoothingMode(pGraphics, SmoothingMode)
; Default = 0
; HighSpeed = 1
; HighQuality = 2
; None = 3
; AntiAlias = 4
{
return DllCall("gdiplus\GdipSetSmoothingMode", "UInt", pGraphics, "Int", SmoothingMode)
}
Gdip_SetInterpolationMode(pGraphics, InterpolationMode)
; Default = 0
; LowQuality = 1
; HighQuality = 2
; Bilinear = 3
; Bicubic = 4
; NearestNeighbor = 5
; HighQualityBilinear = 6
; HighQualityBicubic = 7
{
return DllCall("gdiplus\GdipSetInterpolationMode", "UInt", pGraphics, "Int", InterpolationMode)
}
Gdip_SetCompositingMode(pGraphics, CompositingMode=0)
; CompositingModeSourceOver = 0 (blended)
; CompositingModeSourceCopy = 1 (overwrite)
{
return DllCall("gdiplus\GdipSetCompositingMode", "UInt", pGraphics, "Int", CompositingMode)
}
Gdip_GraphicsFromHDC(hdc)
{
DllCall("gdiplus\GdipCreateFromHDC", "UInt", hdc, "UInt*", pGraphics)
return pGraphics
}
Gdip_GraphicsFromImage(pBitmap)
{
DllCall("gdiplus\GdipGetImageGraphicsContext", "UInt", pBitmap, "UInt*", pGraphics)
return pGraphics
}
Gdip_DeleteGraphics(pGraphics)
{
return DllCall("gdiplus\GdipDeleteGraphics", "UInt", pGraphics)
}
Gdip_DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx, sy, sw, sh, Matrix=1)
{
If (Matrix&1 = "")
ImageAttr := Gdip_SetImageAttributesColorMatrix(Matrix)
Else if (Matrix != 1)
ImageAttr := Gdip_SetImageAttributesColorMatrix("1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|" Matrix "|0|0|0|0|0|1")
DllCall("gdiplus\GdipDrawImageRectRect", "UInt", pGraphics, "UInt", pBitmap
, "Float", dx, "Float", dy, "Float", dw, "Float", dh
, "Float", sx, "Float", sy, "Float", sw, "Float", sh
, "Int", 2, "UInt", ImageAttr, "UInt", 0, "UInt", 0)
If ImageAttr
Gdip_DisposeImageAttributes(ImageAttr)
}
;MatrixBright = 1.5|0|0|0|0|0|1.5|0|0|0|0|0|1.5|0|0|0|0|0|1|0|0.05|0.05|0.05|0|1
;MatrixGreyScale = 0.299|0.299|0.299|0|0|0.587|0.587|0.587|0|0|0.114|0.114|0.114|0|0|0|0|0|1|0|0|0|0|0|1
;MatrixNegative = -1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1
Gdip_SetImageAttributesColorMatrix(Matrix)
{
VarSetCapacity(ColourMatrix, 100, 0)
Matrix := RegExReplace(RegExReplace(Matrix, "^[^0-9-\.]+([0-9\.])", "$1", "", 1), "[^0-9-\.]+", "|")
StringSplit, Matrix, Matrix, |
Loop, 25
{
Matrix := Matrix%A_Index% ? Matrix%A_Index% : Mod(A_Index-1, 6) ? 0 : 1
NumPut(Matrix, ColourMatrix, (A_Index-1)*4, "Float")
}
DllCall("gdiplus\GdipCreateImageAttributes", "UInt*", ImageAttr)
DllCall("gdiplus\GdipSetImageAttributesColorMatrix", "UInt", ImageAttr, "Int", 1, "Int", 1, "UInt", &ColourMatrix, "Int", 0, "Int", 0)
VarSetCapacity(ColourMatrix, 0)
return ImageAttr
}
Gdip_DisposeImageAttributes(ImageAttr)
{
Return, DllCall("gdiplus\GdipDisposeImageAttributes", "UInt", ImageAttr)
}
Gdip_FillRectangle(pGraphics, pBrush, x, y, w, h)
{
return DllCall("gdiplus\GdipFillRectangle", "UInt", pGraphics, "Int", pBrush, "Float", x, "Float", y, "Float", w, "Float", h)
}
Gdip_GraphicsClear(pGraphics, ARGB=0x00ffffff)
{
return DllCall("gdiplus\GdipGraphicsClear", "UInt", pGraphics, "Int", ARGB)
}
;
; RESOURCES
;
Gdip_BrushCreateSolid(ARGB=0xff000000)
{
DllCall("gdiplus\GdipCreateSolidFill", "Int", ARGB, "UInt*", pBrush)
return pBrush
}
Gdip_DeleteBrush(pBrush)
{
return DllCall("gdiplus\GdipDeleteBrush", "UInt", pBrush)
}
;
; TEXT FUNCTIONS
;
Gdip_DrawText(pGraphics, Text, Font="", x=0, y=0, w=128, h=128)
{
StringSplit, s, Font, `,
; s1 = Font
; s2 = Size
; s3 = Color
; s4 = Style
; s5 = Align
; s6 = vAlign
; s7 = rendering type
nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &s1, "Int", -1, "UInt", 0, "Int", 0)
VarSetCapacity(wFont, nSize*2)
DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &s1, "Int", -1, "UInt", &wFont, "Int", nSize)
DllCall("gdiplus\GdipCreateFontFamilyFromName", "UInt", &wFont, "UInt", 0, "UInt*", hFamily)
DllCall("gdiplus\GdipCreateFont", "UInt", hFamily, "Float", s2, "Int", s4, "Int", 0, "UInt*", hFont)
CreateRectF(RC, 0, 0, w, h)
DllCall("gdiplus\GdipSetTextRenderingHint", "UInt", pGraphics, "Int", s7)
DllCall("gdiplus\GdipCreateStringFormat", "Int", 0x4000, "Int", 0, "UInt*", hFormat)
nSize := DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &Text, "Int", -1, "UInt", 0, "Int", 0)
VarSetCapacity(wString, nSize*2)
DllCall("MultiByteToWideChar", "UInt", 0, "UInt", 0, "UInt", &Text, "Int", -1, "UInt", &wString, "Int", nSize)
VarSetCapacity(ReturnRC, 16)
DllCall("gdiplus\GdipMeasureString", "UInt", pGraphics, "UInt", &wString, "Int", -1, "UInt", hFont, "UInt", &RC, "UInt", hFormat, "UInt", &ReturnRC, "UInt*", Chars, "UInt*", Lines)
if (s6=1)
y := y
else If (s6=2)
y := h-NumGet(ReturnRC, 12, "Float")
else
y := (h-NumGet(ReturnRC, 12, "Float"))//2
CreateRectF(RC, x, y, w, NumGet(ReturnRC, 12, "Float"))
pBrush := Gdip_BrushCreateSolid(s3)
DllCall("gdiplus\GdipSetStringFormatAlign", "UInt", hFormat, "Int", s5)
DllCall("gdiplus\GdipDrawString", "UInt", pGraphics, "UInt", &wString, "Int", -1, "UInt", hFont, "UInt", &RC, "UInt", hFormat, "UInt", pBrush)
Gdip_DeleteBrush(pBrush)
DllCall("gdiplus\GdipDeleteStringFormat", "UInt", hFormat)
DllCall("gdiplus\GdipDeleteFont", "UInt", hFont)
DllCall("gdiplus\GdipDeleteFontFamily", "UInt", hFamily)
}
Gdip_SetFontStyle(font)
{
StringSplit, s, Font, `,, %A_Space%
if s5 is not Integer
s5 := 4
s := "bold italic underline strikeout"
Loop, Parse, s, %A_Space%
{
if InStr(s4, A_LoopField)
style += 2**(A_Index-1)
}
s := "left center right"
Loop, Parse, s, %A_Space%
{
if InStr(s4, A_LoopField)
align := A_Index-1
}
s := "top bottom"
Loop, Parse, s, %A_Space%
{
if InStr(s4, A_LoopField)
valign := A_Index
}
s := s1 "," s2 "," s3 "," style "," align "," valign "," s5
return s
}
|
History:
20100213:
- Fix applications run as admin to have a nasty effect on desktop switching. Now, they are treated like sticky windows.
20100212:
- Fix desktp switching / windows minimizing not working with apps like iTune
- Clean-up the code
Last edited by Smurth on Sat Feb 26, 2011 10:10 pm; edited 9 times in total |
|
| Back to top |
|
 |
bold
Joined: 20 Apr 2006 Posts: 21
|
Posted: Thu Feb 11, 2010 8:42 am Post subject: Does not work for me on Vista |
|
|
Does not work for me on Vista. Had to reboot because I could not get the taskmanager to kill the process due to keyboard and mouse buttons not working properly anymore.
Right clicking did not work and I could not change desktops.
Cheers, Bold  |
|
| Back to top |
|
 |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
Posted: Thu Feb 11, 2010 11:50 am Post subject: |
|
|
Strange. Try to remove the following lines at the end of "xWM.ahk"
| Code: | RButton:: RButton()
RButton Up::
if GetKeyState("RButton")
MouseClick, R,,,, 0, U
return |
Have you tried to switch desktop using hotkeys ? |
|
| Back to top |
|
 |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
Posted: Thu Feb 11, 2010 6:50 pm Post subject: |
|
|
ADD:
CTRL+WIN+H to toggle other desks windows visibility from taskbar and update config.ini |
|
| Back to top |
|
 |
bold
Joined: 20 Apr 2006 Posts: 21
|
Posted: Thu Feb 11, 2010 10:12 pm Post subject: |
|
|
Works perfectly!
Could be a problem with my laptop before, or other conflicting scripts. Thanks, nice work. |
|
| Back to top |
|
 |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
Posted: Fri Feb 12, 2010 2:33 am Post subject: |
|
|
| Please, download xWM.ahk again; there was a typo in xWM_HideOthersToggle. |
|
| Back to top |
|
 |
System Monitor
Joined: 09 Mar 2007 Posts: 509 Location: Unknown
|
Posted: Fri Feb 12, 2010 2:58 am Post subject: |
|
|
Umm, WOW. It is awesome. One thing is that even though I pressed the hotkey to toggle other desks windows visibility from taskbar iTunes is still on both desktops. I also tried dragging it to another desktop and it stayed on both.
Seriously this awesome, thanks. |
|
| Back to top |
|
 |
randallf
Joined: 06 Jul 2009 Posts: 678
|
Posted: Fri Feb 12, 2010 6:09 am Post subject: |
|
|
| System Monitor wrote: | Umm, WOW. It is awesome.
Seriously this awesome, thanks. |
Not sure if I will use this but what awesome code |
|
| Back to top |
|
 |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
Posted: Fri Feb 12, 2010 1:46 pm Post subject: |
|
|
I know there could be problem with some apps. Mainly because they don't have a regular titlebar; or when they are run as admin (UAC) in which case I don't think about a way to fix this.
About apps like iTune, I'll try to see what I can do. But I don't want to rely on Window's taskbar to get the list of running windows since I want my script to be compatible with other shells.
Wait and see. |
|
| Back to top |
|
 |
Believer
Joined: 13 Jun 2008 Posts: 41 Location: Earth
|
|
| Back to top |
|
 |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
Posted: Fri Feb 12, 2010 6:18 pm Post subject: |
|
|
- Fix desktop switching / windows minimizing not working with apps like iTune
- A little bit of code cleaning |
|
| Back to top |
|
 |
Jeremiah
Joined: 20 Apr 2009 Posts: 797 Location: North Dakota, USA
|
Posted: Fri Feb 12, 2010 6:53 pm Post subject: |
|
|
Sorry if this is a stupid quesiton, but I see three code boxes up there and I'm not sure which one to use. Which one? Or, all of them? If all of them, do they all just go into one script? _________________ -Jeremiah |
|
| Back to top |
|
 |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
Posted: Fri Feb 12, 2010 7:47 pm Post subject: |
|
|
| You need the three. All in the same folder |
|
| Back to top |
|
 |
Smurth
Joined: 13 Dec 2006 Posts: 117
|
|
| Back to top |
|
 |
musicguy
Joined: 17 Feb 2010 Posts: 1
|
Posted: Wed Feb 17, 2010 12:48 am Post subject: |
|
|
I don't know if I am asking a stupid question or not, but i was wondering how to use the scroll features. everything is working, but i can't figure out the scrolling.
great code, many thanks |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|