web-dev-qa-db-ja.com

Windows 10仮想デスクトップ用のAPI

仮想デスクトップを列挙、切り替え、追加し、コードからデスクトップ間でウィンドウを移動する方法はありますか?できれば、WinAPI。

36
Alex Butenko

Windows SDKサポートチームのブログ IVirtualDesktopManagerを介して デスクトップを切り替えるC#デモ を投稿しました:

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

windowsが表示されているデスクトップを検出するAPIが含まれており、Windowsをデスクトップに切り替えて移動できます。

29
magicandre1981

キーボードショートカットをマップして仮想デスクトップ間でウィンドウを移動するアプリケーションを作成したこの男がいます。 https://github.com/Grabacr07/SylphyHorn (毎日使用しています)

彼は彼が何をしたかを説明するブログを持っています http://grabacr.net/archives/5701 (Google翻訳を使用できます)

実際、彼は、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

2番目の実装は次の場所にあります。 https://github.com/tmyt/VDMHelper これにより、ウィンドウを別のプロセスから別のデスクトップに移動できます。しかし、今のところバグがあります。たとえば、google chromeのようなウィンドウを移動しようとするとクラッシュします。

これが私の研究の結果です。これらのAPIを使用してStickyWindow機能を作成しようとしています。

13
CodeName

Windows 10の「仮想デスクトップ」に関するすべてが文書化されていないのではないかと心配していますが、ロシア語のページではインターフェースを文書化しています。ロシア語は話せませんが、リバースエンジニアリングを使用しているようです。とにかく、コードは非常に明確です(ありがとう!)。

ここに注目してください: http://www.cyberforum.ru/blogs/105416/blog3671.html

古いAPIのCreateDesktop、OpenDesktopなどが新しい仮想デスクトップにリンクされているかどうかを確認しようとしましたが、方法はありません...

これらのインターフェイスは、Windows 10の最終製品リリース(2015-05-08)で機能しますが、Microsoftがドキュメント化するまで、実際に広く分散したアプリケーションで使用しないでください。あまりにも多くのリスク。

よろしく。

7
Alberto Tostado