适用于Windows 10虚拟桌面的API

时间:2015-08-04 05:36:05

标签: windows-10 virtual-desktop

有没有办法枚举,切换,添加虚拟桌面以及在代码之间移动桌面?最好是WinAPI。

3 个答案:

答案 0 :(得分:28)

Windows SDK Support Team Blog通过IVirtualDesktopManager发布了C# demo to switch Desktops

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

它包含用于检测Window显示在哪个桌面上的API,它可以将Windows切换到桌面。

答案 1 :(得分:12)

有这个人制作了一个应用程序来映射键盘shorcut以在虚拟桌面之间移动窗口。 https://github.com/Grabacr07/SylphyHorn (我每天都用它)

他有一个博客,他解释了他的所作所为 http://grabacr.net/archives/5701(您可以使用谷歌翻译,它是日语)

事实上,他在Alberto Tostado的回应中使用了相同的api。 http://www.cyberforum.ru/blogs/105416/blog3671.html api可以在他的github上找到https://github.com/Grabacr07/VirtualDesktop

api使用起来非常简单但是从另一个进程移动窗口似乎是不可能的。

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

为了解决这个问题,他们制作了另一个实现,他们与俄罗斯博客中的那个一起使用

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

第二个实现可以在这里找到:https://github.com/tmyt/VDMHelper 这个可以将窗口从另一个进程移动到另一个桌面。但它现在是错误的。例如,当我尝试移动像谷歌Chrome这样的窗口时,它会崩溃。

所以这是我研究的结果。我现在试图用这些api制作StickyWindow功能。

答案 2 :(得分:7)

我担心所有关于&#34;虚拟桌面&#34;在Windows 10中没有记录,但在俄罗斯页面中,我已经看到记录了接口。我不会说俄语,但似乎他们使用了逆向工程。无论如何,代码非常清楚(感谢他们!)。

留意:     http://www.cyberforum.ru/blogs/105416/blog3671.html

我一直试图查看旧API的CreateDesktop,OpenDesktop等是否与新的虚拟桌面相关联,但是没办法......

这些接口适用于Windows 10的最终产品版本(2015-05-08),但在Microsoft为其提供文档之前,您不应该在真正的广泛分布式应用程序中使用它们。风险太大。

问候。