C#将From窗体设置为桌面

在用C#窗口应用程序写动态壁纸软件的时候,最核心的问题在于如何让一个窗口成为桌面,以及在置为桌面的时候全屏化,下面给出实现过程

 

原理:windows 最底层的窗体 Program Manage (如图所示),想要你的窗体出现在桌面icon后面,只需要把自己的窗体作为 Program Manage 的子窗体,然后隐藏原先的壁纸层就可以了,win10 你可以选择在原先壁纸之上和icon之下的位置(可以省略隐藏原壁纸),但这种是兼容win7和win10的做法。

你可以使用 Visual Studio的 Spy++来查看 Window的窗体。

 

 

首先我们需要添加一个Win32的类,在命名空间中添加如下代码:

public static class Win32
    {
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string className, string winName);

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessageTimeout(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam, uint fuFlage, uint timeout, IntPtr result);

        [DllImport("user32.dll")]
        public static extern bool EnumWindows(EnumWindowsProc proc, IntPtr lParam);
        public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string winName);

        [DllImport("user32.dll")]
        public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);

        [DllImport("user32.dll")]
        public static extern IntPtr SetParent(IntPtr hwnd, IntPtr parentHwnd);
    }

 

 

 

然后在窗口代码里添加

 

 


private IntPtr programIntPtr = IntPtr.Zero;

private Form2 foas = null;

public void Init()
        {
            // 通过类名查找一个窗口,返回窗口句柄。
            programIntPtr = Win32.FindWindow("Progman", null);

            // 窗口句柄有效
            if (programIntPtr != IntPtr.Zero)
            {

                IntPtr result = IntPtr.Zero;

                // 向 Program Manager 窗口发送 0x52c 的一个消息,超时设置为0x3e8(1秒)。
                Win32.SendMessageTimeout(programIntPtr, 0x52c, IntPtr.Zero, IntPtr.Zero, 0, 0x3e8, result);

                // 遍历顶级窗口
                Win32.EnumWindows((hwnd, lParam) =>
                {
                    // 找到包含 SHELLDLL_DefView 这个窗口句柄的 WorkerW
                    if (Win32.FindWindowEx(hwnd, IntPtr.Zero, "SHELLDLL_DefView", null) != IntPtr.Zero)
                    {
                        // 找到当前 WorkerW 窗口的,后一个 WorkerW 窗口。
                        IntPtr tempHwnd = Win32.FindWindowEx(IntPtr.Zero, hwnd, "WorkerW", null);

                        // 隐藏这个窗口
                        Win32.ShowWindow(tempHwnd, 0);
                    }
                    return true;
                }, IntPtr.Zero);
            }
        }

 

 

 

然后在某个按钮单击事件里写

        private void button1_Click(object sender, EventArgs e)

        {
                // 初始化桌面
            foas = new Form2();
            Init();
            // 窗口置父,设置背景窗口的父窗口为 Program Manager 窗口
            Win32.SetParent(foas.Handle, programIntPtr);
            foas.Show();
        }

 

 


就完成了

 

 


效果如图

窗口桌面化
可以看到灰色的窗口出现在图标下方了,已经被置为桌面了,emmm,因为我开的双屏,然后两个屏幕的高度不一样,所以在主屏幕里,被我置为桌面的窗口没有全部显示出来(这一点尤为重要……最大化的时候会

posted @ 2023-01-27 17:12  Domefy  阅读(225)  评论(0编辑  收藏  举报