桌面壁纸层嵌入窗口(wallpaper engine核心)原理讲解

我们在自定义壁纸的时候,通常会使用

<DllImport("user32.dll", EntryPoint:="SystemParametersInfo")>
Shared Function SystemParametersInfo(uAction As Integer, uParam As Integer, lpvParam As String, fuWinIni As Integer) As Integer

End Function

bmp.Save(Application.StartupPath & "\1.bmp")
SystemParametersInfo(20, True, Application.StartupPath & "\1.bmp", 1)

来设置桌面背景的图片,但是这只限于win10,而win7想要做到是不可能的,因为win7并不知道函数里面的参数是什么意思,所以,我们在研究许多资料后,找到了简洁的代码(win32模块我放在文章末尾

Public Sub SetAnimeBackground(ByVal videoPtr As IntPtr)
    Dim windows_version As Double = Environment.OSVersion.Version.Major
    progmanPtr = FindWindow("Progman", Nothing)

    If progmanPtr = IntPtr.Zero Then
        MessageBox.Show("当前系统可能不支持运行本程序或者卡死")
        Return
    Else
        SendMessageTimeout(progmanPtr, &H52C, IntPtr.Zero, IntPtr.Zero, 0, &H3E8, sendMessageBack)
        EnumWindows(Function(hwnd, param)

                        If Win32.FindWindowEx(hwnd, IntPtr.Zero, "SHELLDLL_DefView", Nothing) <> IntPtr.Zero Then
                            workWPtr = Win32.FindWindowEx(IntPtr.Zero, hwnd, "WorkerW", Nothing)

                            If windows_version < 6.2 Then
                                Win32.ShowWindow(workWPtr, 0)
                            End If
                        End If

                        Return True
                    End Function, 0)

        If windows_version < 6.2 Then
            SetParent(videoPtr, progmanPtr)
        Else
            SetParent(videoPtr, workWPtr)
        End If

        Thread.Sleep(500)
        SetWindowPos(videoPtr, IntPtr.Zero, 0, 0, Win32.GetSystemMetrics(0), Win32.GetSystemMetrics(1), 0)
        Thread.Sleep(100)
        'VideoForm.videoForm.Show()
    End If
End Sub

此代码来自wenshitao提供的部分代码,GitHub开源项目:AnimateBackgroundWinform/gui_animate_destop/Util.cs at master · Nakasu-ksm/AnimateBackgroundWinform · GitHub

本人在基础上稍作修改,相比之下,某些C++的代码显得格外臃肿

ok这里解读一下使用方法,函数的参数是想要嵌入背景层的窗口句柄,如果你需要把窗口切出来只需要

SetParent(hwnd, IntPtr.Zero)

即可

如果你不需要全屏,则可以注释掉

SetWindowPos(videoPtr, IntPtr.Zero, 0, 0, Win32.GetSystemMetrics(0), Win32.GetSystemMetrics(1), 0)

 这样,所有windows的原生态窗口就可以轻松地嵌入背景了,但例如百度网盘、哔哩哔哩客户端、UWP应用等无法嵌入

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks
Imports Microsoft.Win32
Imports System.Runtime.InteropServices

Public Module Win32

    <DllImport("user32.dll")>
    Public Function FindWindow(ByVal className As String, ByVal winName As String) As IntPtr

    End Function
    <DllImport("user32.dll")>
    Public Function SendMessageTimeout(ByVal hwnd As IntPtr, ByVal msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByVal fuFlage As UInteger, ByVal timeout As UInteger, ByVal result As IntPtr) As IntPtr

    End Function
    <DllImport("user32.dll")>
    Public Function EnumWindows(ByVal proc As EnumWindowsProc, ByVal lParam As Integer) As Boolean

    End Function
    Public Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
    <DllImport("user32.dll")>
    Public Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal className As String, ByVal winName As String) As IntPtr

    End Function
    <DllImport("user32.dll")>
    Public Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Boolean

    End Function
    <DllImport("user32.dll")>
    Public Function SetParent(ByVal hwnd As IntPtr, ByVal parentHwnd As IntPtr) As IntPtr

    End Function
    <DllImport("user32.dll", EntryPoint:="GetSystemMetrics")>
    Public Function GetSystemMetrics(ByVal which As Integer) As Integer

    End Function
    <DllImport("gdi32.dll", EntryPoint:="GetDeviceCaps", SetLastError:=True)>
    Public Function GetDeviceCaps(ByVal hdc As IntPtr, ByVal nIndex As Integer) As Integer

    End Function
    <DllImport("user32.dll")>
    Public Sub SetWindowPos(ByVal hwnd As IntPtr, ByVal hwndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal flags As UInteger)

    End Sub

End Module

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值