API for Windows 10 virtual desktops

后端 未结 3 662
一整个雨季
一整个雨季 2020-12-07 13:41

Is there any way to enumerate, switch, add virtual desktops and move window between desktops from code? Preferably, WinAPI.

相关标签:
3条回答
  • 2020-12-07 14:10

    I fear that all about "Virtual desktops" in Windows 10 is undocumented, but in a Russian page I've seen documented the interfaces. I don't speak Russian but seems that they have used reversed engineering. Anyway, the code is very clear (Thanks to them!).

    Keep an eye here: http://www.cyberforum.ru/blogs/105416/blog3671.html

    I've been trying to see if the old API's CreateDesktop, OpenDesktop, etc... is linked to the new Virtual-Desktops, but no way...

    The interfaces work with the final production release of Windows 10 (2015-05-08), but you shouldn't use them in a real wide distributed application until Microsoft documents them. Too much risk.

    Regards.

    0 讨论(0)
  • 2020-12-07 14:16

    The Windows SDK Support Team Blog posted a 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);
            }
        }
    }
    

    it includes the API to detect on which desktop the Window is shown and it can switch and move a Windows the a Desktop.

    0 讨论(0)
  • 2020-12-07 14:24

    There is this guy that made a application to map keyboard shorcut to move a window between virtual desktop. https://github.com/Grabacr07/SylphyHorn (I use it every day )

    He has a blog where he explain what he did http://grabacr.net/archives/5701 ( you can use google translate it is in japanese)

    He in fact used the same api mantionned in the Alberto Tostado response. http://www.cyberforum.ru/blogs/105416/blog3671.html and the api can be found on his github https://github.com/Grabacr07/VirtualDesktop

    The api is really simple to use BUT it seems impossible to move a window from another process.

    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;
        }
    

    To workaround this problem they made another implementation that they use alongside the one in the russian blog

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

    The second implementation can be found here: https://github.com/tmyt/VDMHelper This one can move a window from another process to another desktop. BUT it is buggy right now. For exemple when i try to move some window like google chrome it crash.

    So this is the result of my research. I m rigth now trying to make a StickyWindow feature with these api.

    0 讨论(0)
提交回复
热议问题