2015-08-04 20 views

risposta

21

Il Windows SDK Support Team Blog inviato un C# demo to switch Desktops via IVirtualDesktopManager:

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("a5cd92ff-29be-454c-8d04-d82879fb3f1b")] 
[System.Security.SuppressUnmanagedCodeSecurity] 
public interface IVirtualDesktopManager 
{ 
[PreserveSig] 
int IsWindowOnCurrentVirtualDesktop(
    [In] IntPtr TopLevelWindow, 
    [Out] out int OnCurrentDesktop 
    ); 
[PreserveSig] 
int GetWindowDesktopId(
    [In] IntPtr TopLevelWindow, 
    [Out] out Guid CurrentDesktop 
    ); 

[PreserveSig] 
int MoveWindowToDesktop(
    [In] IntPtr TopLevelWindow, 
    [MarshalAs(UnmanagedType.LPStruct)] 
    [In]Guid CurrentDesktop 
    ); 
} 

[ComImport, Guid("aa509086-5ca9-4c25-8f95-589d3c07b48a")] 
public class CVirtualDesktopManager 
{ 

} 
public class VirtualDesktopManager 
{ 
    public VirtualDesktopManager() 
    { 
     cmanager = new CVirtualDesktopManager(); 
     manager = (IVirtualDesktopManager)cmanager; 
    } 
    ~VirtualDesktopManager() 
    { 
     manager = null; 
     cmanager = null; 
    } 
    private CVirtualDesktopManager cmanager = null; 
    private IVirtualDesktopManager manager; 

    public bool IsWindowOnCurrentVirtualDesktop(IntPtr TopLevelWindow) 
    { 
     int result; 
     int hr; 
     if ((hr = manager.IsWindowOnCurrentVirtualDesktop(TopLevelWindow, out result)) != 0) 
     { 
      Marshal.ThrowExceptionForHR(hr); 
     } 
     return result != 0; 
    } 

    public Guid GetWindowDesktopId(IntPtr TopLevelWindow) 
    { 
     Guid result; 
     int hr; 
     if ((hr = manager.GetWindowDesktopId(TopLevelWindow, out result)) != 0) 
     { 
      Marshal.ThrowExceptionForHR(hr); 
     } 
     return result; 
    } 

    public void MoveWindowToDesktop(IntPtr TopLevelWindow, Guid CurrentDesktop) 
    { 
     int hr; 
     if ((hr = manager.MoveWindowToDesktop(TopLevelWindow, CurrentDesktop)) != 0) 
     { 
      Marshal.ThrowExceptionForHR(hr); 
     } 
    } 
} 

esso include l'API per rilevare su quale desktop viene mostrata la finestra e si può cambiare e spostare un Windows l'un desktop.

+1

Kinda ti chiede perché Microsoft non ha aggiunto solo una scorciatoia da tastiera per questo direttamente doesn ' t it ... – Adam

7

Temo che tutto ciò che riguarda "Desktop virtuali" in Windows 10 non sia documentato, ma in una pagina russa ho visto le interfacce documentate. Non parlo russo ma sembra che abbiano usato l'ingegneria invertita. Ad ogni modo, il codice è molto chiaro (grazie a loro!).

Tenete d'occhio qui: http://www.cyberforum.ru/blogs/105416/blog3671.html

Ho cercato di vedere se CreateDesktop della vecchia API, OpenDesktop, ecc ... è legata alla nuova Virtual-Desktop, ma nessun modo ...

Le interfacce funzionano con la versione di produzione finale di Windows 10 (2015-05-08), ma non è necessario utilizzarle in un'applicazione distribuita su vasta scala finché Microsoft non le documenta. Troppo rischio.

Saluti.

+4

[È documentato] (https://msdn.microsoft.com/en-us/library/windows/desktop/mt186440%28v=vs.85 % 29.aspx). –

+0

Sì, c'è qualche documentazione per un'interfaccia. Ma come lo usi in una "normale" app UWP usando C#/xaml ?? Puoi dare qualche esempio? – okieh

+0

@okieh guarda la mia risposta. Microsoft ha creato una demo C# – magicandre1981

9

C'è questo tizio che ha creato un'applicazione per mappare la tastiera shorcut per spostare una finestra tra il desktop virtuale. https://github.com/Grabacr07/SylphyHorn (lo uso tutti i giorni)

Lui ha un blog in cui spiega quello che ha fatto http://grabacr.net/archives/5701 (è possibile utilizzare Google Translate è in giapponese)

Ha infatti utilizzato la stessa API mantionned in la risposta di Alberto Tostado. http://www.cyberforum.ru/blogs/105416/blog3671.html e l'API può essere trovato sul suo github https://github.com/Grabacr07/VirtualDesktop

l'API è molto semplice da usare, ma sembra impossibile spostare una finestra da un altro processo.

public static bool MoveToDesktop(IntPtr hWnd, VirtualDesktop virtualDesktop) 
    { 
     ThrowIfNotSupported(); 

     int processId; 
     NativeMethods.GetWindowThreadProcessId(hWnd, out processId); 

     if (Process.GetCurrentProcess().Id == processId) // THAT LINE 
     { 
      var guid = virtualDesktop.Id; 
      VirtualDesktop.ComManager.MoveWindowToDesktop(hWnd, ref guid); 
      return true; 
     } 

     return false; 
    } 

Per risolvere questo problema hanno fatto un'altra implementazione che usano accanto a quello nel blog russo

if (VirtualDesktopHelper.MoveToDesktop(hWnd, right) //<- the one in the russian blog 
        || this.helper.MoveWindowToDesktop(hWnd, right.Id)) <- the second implementation 

La seconda implementazione può essere trovato qui: https://github.com/tmyt/VDMHelper Questo si può spostare una finestra da un altro elaborare su un altro desktop. MA è bacato in questo momento. Ad esempio quando provo a spostare alcune finestre come google chrome si blocca.

Quindi questo è il risultato della mia ricerca. Ora sto cercando di creare una funzione StickyWindow con queste API.

+0

Mi piacerebbe fare qualcosa di ancora più semplice dello spostamento di windows, solo per cambiare desktop. Come potrei farlo? Sono molto frustrato dalla mancanza di un ritorno alla chiave del desktop precedente, che sarebbe la cosa più utile di sempre - e dalla mancanza di tasti diretti del desktop - ad es. come win-ctrl-1 per andare al desktop 1 - quindi mi piacerebbe scrivere uno script autoit per rendere quelle chiavi – ycomp

+0

Sì questo è molto semplice da implementare! C'è questo progetto: https://github.com/nullpo-head/Windows-10-Virtual-Desktop-Switching-Shortcut che fa esattamente quello Ma io suggerirei di personalizzare solo il codice da questo progetto (https : //github.com/Grabacr07/SylphyHorn) per le tue esigenze. Ha un'implementazione migliore. – CodeName

+0

@ycomp Ho creato una DLL accessibile da AutoHotkey https://github.com/Ciantic/VirtualDesktopAccessor – Ciantic

Problemi correlati