Есть ли способ перечислить, переключить, добавить виртуальные рабочие столы и переместить окно между рабочими столами из кода? Предпочтительно WinAPI.
API для виртуальных рабочих столов Windows 10
Ответ 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 не документирует их. Слишком большой риск.
С уважением.