April 24, 2024, 05:20:35 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Creating and switching between multiple desktops

Started by sapero, April 25, 2011, 01:30:11 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

sapero

April 25, 2011, 01:30:11 PM Last Edit: April 25, 2011, 11:18:18 PM by sapero
This is the simplest program for desktop switching, it can switch between 10 desktops with a global hotkey WIN+0 ... WIN+9.

Compile for windows target and run. It will stay invisible, servicing desktop switching. To terminate it, switch back to the default desktop (WIN+1), run the program again and click Yes in the asking box.

Known issue: system hotkeys, like ctrl+alt+del, alt+tab, will not work on desktop 2,3,4...9,0, at least they don't work on XP - the action is taken on the default desktop.


$include "shlwapi.inc"
$include "userenv.inc"

$define DESKTOP_NAME_STRING_FORMAT T"IWBDesktop%d"
$define SINGLE_INSTANCE_STRING     T"IWBDesktopSwitcher"

int %g_NumberOfDesktops = 10 ' up to 10
BOOL   g_valid[10]
HDESK  g_desktop[10] ' g_desktop[0] is the current input desktop

Start()
end

sub DoSwitchDesktop(int index)

STARTUPINFO si = 0
PROCESS_INFORMATION pi
itstring szProfiles[MAX_PATH]
itstring szDesktopName[sizeof(DESKTOP_NAME_STRING_FORMAT)+16]
itstring szShellName[MAX_PATH]

' if not default desktop
if (index)
wsprintf(szDesktopName, DESKTOP_NAME_STRING_FORMAT, index)
' if desktop is not created yet
if (!g_desktop[index])
g_desktop[index] = CreateDesktop(szDesktopName,NULL,NULL,0,GENERIC_ALL,NULL)
endif
endif

' assign this thread to the new desktop now, because we want to call FindWindow
SetThreadDesktop(g_desktop[index])
' activate selected desktop
SwitchDesktop(g_desktop[index])

' run explorer if not already running
if (!FindWindow(T"Progman", T"Program Manager")) ' explorer related window
si.cb = sizeof(si)
if (index) then si.lpDesktop = szDesktopName

DWORD cch = MAX_PATH
GetProfilesDirectory(szProfiles, &cch)

cch = MAX_PATH
' load shell name from the registry
if (SHGetValue(HKEY_LOCAL_MACHINE,T"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", T"Shell", 0, szShellName, &cch))
szShellName = T"explorer.exe"
endif

$macro runexe(cmdline) (CreateProcess(0, cmdline, 0, 0, FALSE, 0, 0, szProfiles, &si, &pi))
with pi
' execute shell loaded from registry
if (runexe(szShellName))
CloseHandle(.hThread)
CloseHandle(.hProcess)
' if failed and shell is not "explorer", execute explorer
elseif (lstrcmpi(szShellName, T"explorer.exe") && runexe(T"explorer.exe"))
CloseHandle(.hThread)
CloseHandle(.hProcess)
' if failed, execute command processor
elseif (runexe(T"cmd.exe"))
CloseHandle(.hThread)
CloseHandle(.hProcess)
endif
endwith
endif

if (index) then SetThreadDesktop(g_desktop[0])
endsub


'==================================================

sub Start()
int a
BOOL HasHotKeys = FALSE

' save the default desktop
g_desktop[0] = GetThreadDesktop(GetCurrentThreadId())
g_valid[0]   = TRUE

' create an exit event
HANDLE hExitEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, SINGLE_INSTANCE_STRING)
if (hExitEvent)
if (_MessageBox(0, T"This application is already running.\nWould you like to close it?", T"MultiDesktop", MB_YESNOCANCEL)==IDYES)
SetEvent(hExitEvent)
endif
CloseHandle(hExitEvent)
return
endif
hExitEvent = CreateEvent(0,0,0,SINGLE_INSTANCE_STRING)

' register hotkeys
for a = 0 to g_NumberOfDesktops-1
g_valid[a] = RegisterHotKey(0, a, MOD_WIN, a<9 ? `1`+a : `0`)
HasHotKeys |= g_valid[a]
next a

if (HasHotKeys)
MSG msg

while (TRUE)
DWORD dwWaitResult = MsgWaitForMultipleObjectsEx(1, &hExitEvent, INFINITE, QS_ALLEVENTS, MWMO_ALERTABLE)

select (dwWaitResult)
case  0           ' event signalled
case& WAIT_FAILED ' event closed ?
break

case 1
' process all pending messages
while (PeekMessage(&msg,0,0,0,PM_REMOVE))
' WM_HOTKEY:
' HIWORD(lParam) - virtual key code
' LOWORD(lParam) - modifiers
int index = HIWORD(msg.lParam) - `1`
index = (index==-1) ? 9 : index

if (msg.message==WM_HOTKEY)
if (LOWORD(msg.lParam) == MOD_WIN _
&& index >= 0 && index < g_NumberOfDesktops /*validate bounds*/_
&& g_valid[index] /* a hotkey must be registered*/)

DoSwitchDesktop(index)
endif
endif
wend

case WAIT_TIMEOUT
endselect
wend
CloseHandle(hExitEvent)

for a = 0 to g_NumberOfDesktops-1
if (g_valid[a])   then UnregisterHotKey(0, a)
if (a&&g_desktop[a]) then CloseDesktop(g_desktop[a])
next a

DoSwitchDesktop(0)
endif

endsub