WPF自定义Windows桌面背景

适用于: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值