Подтвердить что ты не робот

API для виртуальных рабочих столов Windows 10

Есть ли способ перечислить, переключить, добавить виртуальные рабочие столы и переместить окно между рабочими столами из кода? Предпочтительно WinAPI.

4b9b3361

Ответ 1

Блог группы поддержки Windows SDK опубликовал демонстрацию С# для переключения настольных компьютеров через интерфейс 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);
        }
    }
}

он включает в себя API для обнаружения, на каком рабочем столе отображается окно, и он может переключать и перемещать Windows на Рабочий стол.

Ответ 2

Есть этот парень, который сделал приложение для сопоставления клавиатуры shorcut, чтобы переместить окно между виртуальным рабочим столом. https://github.com/Grabacr07/SylphyHorn (Я использую его каждый день)

У него есть блог, где он объясняет, что он сделал http://grabacr.net/archives/5701 (вы можете использовать перевод google на японском языке)

Он фактически использовал те же самые api mantionned в ответ Альберто Тостадо. 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 Это может перемещать окно из другого процесса на другой рабочий стол. НО это сейчас багги. Например, когда я пытаюсь переместить какое-то окно, например, google chrome, оно сработает.

Итак, это результат моих исследований. Теперь я пытаюсь сделать функцию StickyWindow с этими api.

Ответ 3

Я боюсь, что все о "виртуальных рабочих столах" в Windows 10 недокументированы, но на русской странице я видел документированные интерфейсы. Я не говорю по-русски, но кажется, что они использовали обратную инженерию. Во всяком случае, код очень ясен (спасибо им!).

Следите за нами:   http://www.cyberforum.ru/blogs/105416/blog3671.html

Я пытался выяснить, связан ли старый API CreateDesktop, OpenDesktop и т.д. с новыми виртуальными рабочими столами, но никак...

Интерфейсы работают с окончательной производственной версией Windows 10 (2015-05-08), но вы не должны использовать их в реальном широко распространенном приложении до тех пор, пока Microsoft не документирует их. Слишком большой риск.

С уважением.