使用SHELLDLL_DefView作为父级,坐标毫无意义

时间:2018-06-08 21:45:59

标签: c# wpf windows desktop

我尝试创建一个停留在桌面后面的桌面上的WPF应用程序并忽略show desktop(Windows + D)命令,如FencesRainmeter

我通过将父设置为SHELLDLL_DefView来保持桌面,但现在坐标没有意义(对我而言)。

如果我将位置设置为0x0,则它显示在某个界限之外。

当我启用AllowTransparency时,协调会加倍,窗口会自动远离主监视器。

以下是我测试此代码的代码:

public partial class MainWindow : Window
{
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindowEx(IntPtr hP, IntPtr hC, string sC, string sW);

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

    const int SWP_NOSIZE = 0x0001;
    const int SWP_NOMOVE = 0x0002;
    const int SWP_NOZORDER = 0x0004;
    const int SWP_NOACTIVATE = 0x0010;
    const int SWP_SHOWWINDOW = 0x0040;

    public MainWindow()
    {
        InitializeComponent();
        LocationChanged += Window_LocationChanged;
        WindowStyle = WindowStyle.None;
        AllowsTransparency = true;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // The handle of this window
        var windowHandle = new WindowInteropHelper(this).Handle;

        // Try to find the desktop under progman
        var progmanHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "Progman", null);
        var desktopHandle = FindWindowEx(progmanHandle, IntPtr.Zero, "SHELLDLL_DefView", null);

        // If the desktop if not under Progman, then search under WorkerW
        if (desktopHandle == IntPtr.Zero)
        {
            var workerHandle = IntPtr.Zero;
            do
            {
                workerHandle = FindWindowEx(IntPtr.Zero, workerHandle, "WorkerW", null);
                desktopHandle = FindWindowEx(workerHandle, IntPtr.Zero, "SHELLDLL_DefView", null);
            }
            while (workerHandle != IntPtr.Zero && desktopHandle == IntPtr.Zero);
        }

        // Set the desktop as the parent, this will display the window on the desktop
        SetParent(windowHandle, desktopHandle);

        // Coordinates for my second monitor (for testing)
        int x = 1680, y = 0;

        // Coordinates are suddenly doubled with transparency.
        if (AllowsTransparency)
        {
            x *= 2;
            y *= 2;
        }

        // Sets the window position
        // Left = Top = 0;
        SetWindowPos(windowHandle, IntPtr.Zero, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
    }

    private void Window_LocationChanged(object sender, EventArgs e)
    {
        // Helpful
        try
        {
            Console.WriteLine("Point: " + Left + "x" + Top + " - Pixel: " + PointToScreen(new Point(0, 0)));
        }
        catch (Exception) { }
    }
}

Picture of my monitor setup.

我还没找到任何关于我的谷歌的东西。我可能错过了一些明显的东西。 :)

有人可以帮助我朝正确的方向发展吗?

编辑:修复了代码中的错误。

0 个答案:

没有答案