代码
1、在alt+tab中隐藏窗口
2、不在任务栏显示
3、将窗口设为“桌面”的子窗口
4、重启资源管理器则重新自启动
5、切换桌面重新设置父窗口
C#
//在alt+tab中隐藏
protected override CreateParams CreateParams
{
get
{
const int WS_EX_APPWINDOW = 0x40000;
const int WS_EX_TOOLWINDOW = 0x80;
CreateParams cp = base.CreateParams;
cp.ExStyle &= (~WS_EX_APPWINDOW);
cp.ExStyle |= WS_EX_TOOLWINDOW;
return cp;
}
}
private IntPtr programIntPtr = IntPtr.Zero;
private void Find()
{
// 通过类名查找一个窗口,返回窗口句柄。
programIntPtr = Win32.FindWindow("Progman", null);
}
private void Init()
{
// 窗口句柄有效
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);
// 窗口置父,设置背景窗口的父窗口为 Program Manager 窗口
Win32.SetParent(this.Handle, programIntPtr);
}
}
private void OnLoad(object sender, EventArgs e)
{
this.Dock = DockStyle.Fill;
this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
Rectangle bound = Screen.PrimaryScreen.Bounds;
this.Width = bound.Width;
this.Height = bound.Height;
this.Left = 0;
this.Top = 0;
Find();
Init();
this.WindowState = FormWindowState.Maximized;
IntPtr oldprogramIntPtr = programIntPtr;
new Thread(() =>
{
while (true)
{
Find();
//当资源管理器重启后,程序自动重启
if (programIntPtr != oldprogramIntPtr)
{
Application.ExitThread();
Application.Exit();
Application.Restart();
Process.GetCurrentProcess().Kill();
}
//某些原因下,桌面窗口的子窗口会失效,比如按下 win+tab
//我们查找一下桌面窗口的子窗口,找不到当前壁纸程序的句柄,那就重新设置一下
bool hasChild = false;
Win32.EnumChildWindows(programIntPtr, (IntPtr hwnd, IntPtr lParam) =>
{
hasChild |= hwnd == this.Handle;
return true;
}, IntPtr.Zero);
if (hasChild == false)
{
Init();
}
Thread.Sleep(1000);
}
}).Start();
}
public static class Win32
{
[DllImport("user32.dll")]
public static extern bool EnumChildWindows(IntPtr hWndParent, EnumChildCallback lpEnumFunc, IntPtr lParam);
public delegate bool EnumChildCallback(IntPtr hwnd, IntPtr lParam);
[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);
}