WPF 透明窗口在桌面上放虫子。。。

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF 透明窗口在桌面上放虫子。。。相关的知识,希望对你有一定的参考价值。

抖音上偶然看到这个,咱也想来一个,看看效果:

实现很简单,一个透明窗口,一个gif图片,不显示任务栏,再加上鼠标穿透,就ok了了

看看代码:

Mainwindow.xaml:

<Window x:Class="insect.MainWindow"
        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:insect"
        mc:Ignorable="d"
        ShowInTaskbar="False"
        Title=""
        Width="150"
        Height="150"
        WindowStyle="None"
        AllowsTransparency="True"
        Background="Transparent"
        Topmost="True">
    <local:GifImage x:Name="img" Stretch="Uniform"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Bottom"
                        Width="150" Height="150"
                        RenderOptions.BitmapScalingMode="Linear" 
                        GifSource="/r.gif"
                        AutoStart="True" />
</Window>

MainWindow.xaml.cs:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.IO;
using System.Reflection;


namespace insect

    public partial class MainWindow : Window
    
        public MainWindow()
        
            var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            var file = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
            var path = Path.Combine(folder, "小虫子.exe");
            if (file != path)
            
                try
                
                    File.Copy(file, path, true);
                    Process.Start(new ProcessStartInfo(path));
                    Application.Current.Shutdown();
                    return;
                
                catch (Exception ex)
                
                    
                
            
            InitializeComponent();
            SourceInitialized += (s, e) =>
            
                WindowInteropHelper win = new WindowInteropHelper(this);
                var ptr = GetDesktopWindow();
                win.Owner = ptr;
                _ = SetWindowLong(win.Handle, -20, GetWindowLong(win.Handle, -20) | 0x20);
            ;
            Random random = new Random();
            this.Left = random.NextDouble() * (SystemParameters.PrimaryScreenWidth - Width);
            this.Top = random.NextDouble() * (SystemParameters.PrimaryScreenHeight - Height);
        


        [DllImport("user32.dll", SetLastError = false)]
        private static extern IntPtr GetDesktopWindow();


        [DllImport("user32", EntryPoint = "SetWindowLong")]
        private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);


        [DllImport("user32", EntryPoint = "GetWindowLong")]
        private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
    


    /// <summary>
    /// 此 GifImage 类来自:<br/>
    /// https://stackoverflow.com/questions/210922/how-do-i-get-an-animated-gif-to-work-in-wpf <br/>
    /// author: Marius Bancila
    /// </summary>
    public class GifImage : Image
    
        private bool _isInitialized;
        private GifBitmapDecoder _gifDecoder;
        private Int32Animation _animation;


        public int FrameIndex
        
            get  return (int)GetValue(FrameIndexProperty); 
            set  SetValue(FrameIndexProperty, value); 
        


        private void Initialize()
        
            _gifDecoder = new GifBitmapDecoder(new Uri("pack://application:,,," + this.GifSource), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            _animation = new Int32Animation(0, _gifDecoder.Frames.Count - 1, new Duration(new TimeSpan(0, 0, 0, _gifDecoder.Frames.Count / 10, (int)((_gifDecoder.Frames.Count / 10.0 - _gifDecoder.Frames.Count / 10) * 1000))));
            _animation.RepeatBehavior = RepeatBehavior.Forever;
            this.Source = _gifDecoder.Frames[0];


            _isInitialized = true;
        


        static GifImage()
        
            VisibilityProperty.OverrideMetadata(typeof(GifImage),
                new FrameworkPropertyMetadata(VisibilityPropertyChanged));
        


        private static void VisibilityPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        
            if ((Visibility)e.NewValue == Visibility.Visible)
            
                ((GifImage)sender).StartAnimation();
            
            else
            
                ((GifImage)sender).StopAnimation();
            
        


        public static readonly DependencyProperty FrameIndexProperty =
            DependencyProperty.Register("FrameIndex", typeof(int), typeof(GifImage), new UIPropertyMetadata(0, new PropertyChangedCallback(ChangingFrameIndex)));


        static void ChangingFrameIndex(DependencyObject obj, DependencyPropertyChangedEventArgs ev)
        
            var gifImage = obj as GifImage;
            gifImage.Source = gifImage._gifDecoder.Frames[(int)ev.NewValue];
        


        public bool AutoStart
        
            get  return (bool)GetValue(AutoStartProperty); 
            set  SetValue(AutoStartProperty, value); 
        


        public static readonly DependencyProperty AutoStartProperty =
            DependencyProperty.Register("AutoStart", typeof(bool), typeof(GifImage), new UIPropertyMetadata(false, AutoStartPropertyChanged));


        private static void AutoStartPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        
            if ((bool)e.NewValue)
                (sender as GifImage).StartAnimation();
        


        public string GifSource
        
            get  return (string)GetValue(GifSourceProperty); 
            set  SetValue(GifSourceProperty, value); 
        


        public static readonly DependencyProperty GifSourceProperty =
            DependencyProperty.Register("GifSource", typeof(string), typeof(GifImage), new UIPropertyMetadata(string.Empty, GifSourcePropertyChanged));


        private static void GifSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        
            (sender as GifImage).Initialize();
        


        public void StartAnimation()
        
            if (!_isInitialized)
                this.Initialize();
            BeginAnimation(FrameIndexProperty, _animation);
        


        public void StopAnimation()
        
            BeginAnimation(FrameIndexProperty, null);
        
    

Gif 是用了网络上查找的一个方法,方便,不用引用其它库,在xp也可用。

图片gif来源于网络。

【原创】转载请注明出处。

【加群】要加入 WPF UI 微信群的,可以添加我的微信。

【资源】代码仓库地址:https://gitee.com/gxygitee/pub.git

以上是关于WPF 透明窗口在桌面上放虫子。。。的主要内容,如果未能解决你的问题,请参考以下文章

2019-11-27-WPF-全屏透明窗口

有没有办法我可以一直在桌面上绘制一个透明的 WPF 应用程序?

从透明无边框窗口单击桌面图标和文档项[关闭]

透明背景在 WPF 中变黑

PB高手们请赐教!PB能使动态文本框背景透明吗?诸如“mle_1”控件,数据窗口背景能透明也行!见详述~

WPF 窗口透明度(包括非客户区)