在用C#窗口应用程序写动态壁纸软件的时候,最核心的问题在于如何让一个窗口成为桌面,以及在置为桌面的时候全屏化,下面给出实现过程
首先我们需要添加一个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,因为我开的双屏,然后两个屏幕的高度不一样,所以在主屏幕里,被我置为桌面的窗口没有全部显示出来(这一点尤为重要……最大化的时候会