适用于Windows 10虚拟桌面的API

Ale*_*nko 38 virtual-desktop windows-10

有没有办法枚举,切换,添加虚拟桌面和从代码之间移动桌面之间的窗口?优选地,WinAPI.

mag*_*981 32

Windows SDK的支持团队博客贴出了C#的演示来切换桌面通过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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它包括用于检测Window显示在哪个桌面上的API,它可以切换和移动Windows桌面.

  • Kinda让您想知道为什么Microsoft不只是直接为此添加键盘快捷键,不是吗? (4认同)

Cod*_*ame 15

有一个人做了一个应用程序来映射键盘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;
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • @ycomp我制作了一个可以从AutoHotkey https://github.com/Ciantic/VirtualDesktopAccessor访问的DLL (2认同)

小智 8

我担心Windows 10中的所有"虚拟桌面"都没有记录,但在我看到的俄语页面中记录了接口.我不会说俄语,但似乎他们使用了逆向工程.无论如何,代码非常清楚(感谢他们!).

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

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

这些接口与Windows 10的最终产品版本(2015-05-08)一起使用,但在Microsoft记录它们之前,不应在真正的广泛分布式应用程序中使用它们.风险太大.

问候.

  • [记录](https://msdn.microsoft.com/en-us/library/windows/desktop/mt186440%28v=vs.85%29.aspx). (4认同)