适用于:windows 10/11
原理:将自己的窗体放到“Program Manager”窗体最底层。Program Manager是桌面的窗体。使用UISpy或spy++可以查看到。
使用到的win32api
[DllImport("user32.dll", EntryPoint = "SetParent")]
public static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags);
[DllImport("user32", CharSet = CharSet.Ansi, EntryPoint = "FindWindowA", ExactSpelling = false, SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);
public delegate bool EnumWindowsCallback(IntPtr hwnd, int lParam);
[DllImport("user32.dll")]
public static extern int EnumWindows(EnumWindowsCallback callPtr, int lParam);
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("user32.dll")]
public static extern int GetWindowRect(IntPtr hwnd, out Rect lpRect);
我这里使用Chrom内核进行网页页面渲染
从nuget搜索:CefSharp.Wpf.NETCore,版本自行选择。
窗体代码
<Window x:Class="WallpaperWPF.WallpaperWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WallpaperWPF"
xmlns:chrome="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
mc:Ignorable="d"
Title="WallpaperWindow" Left="0" Top="0" WindowState="Maximized" WindowStyle="None" ShowInTaskbar="False" AllowsTransparency="True" Loaded="Window_Loaded">
<Grid Name="grid">
</Grid>
</Window>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var h = new WindowInteropHelper(this).Handle;
IntPtr p = GetWorkerW();
Core.Rect rect;
Win32API.GetWindowRect(p, out rect);
this.Width = rect.Right;
this.Height = rect.Bottom;
Win32API.SetParent(h, p);
Win32API.SetWindowPos(h, new IntPtr(Win32API.HWND_BOTTOM), 0, 0, 0, 0, 0x0001);
var setting = new CefSettings();
if (Cef.IsInitialized == false)
{
Cef.Initialize(setting);
}
webView = new ChromiumWebBrowser();
grid.Children.Add(webView);
if (!string.IsNullOrEmpty(Url)) { webView.Address = Url; }
}
public IntPtr GetWorkerW()
{
var windowHandle = Win32API.FindWindow("Progman", "Program Manager");
UIntPtr result;
Win32API.SendMessageTimeout(windowHandle, 0x052c, UIntPtr.Zero, IntPtr.Zero, 0x0000, 0x3e8, out result);
Win32API.EnumWindows(EnumWindowsProc, 0);
Win32API.ShowWindow(_workerw, 0);
return windowHandle;
}
public bool EnumWindowsProc(IntPtr tophandle, int topparamhandle)
{
IntPtr defview = Win32API.FindWindowEx(tophandle, IntPtr.Zero, "SHELLDLL_DefView", null);
if (defview != IntPtr.Zero)
{
_workerw = Win32API.FindWindowEx(IntPtr.Zero, tophandle, "WorkerW", null);
}
return true;
}