none
如何让一个Transparent的窗口,topmost=true,始终在最上面?(在任务栏上面) RRS feed

  • 问题

  • 我的测试程序很简单,一个透明窗口(窗口全屏)里面有个image,放在窗口的右下角,已经设置了Topmost="True",

    但是在点击窗口的透明部分的时候,任务栏回跑到我的窗口前面, 把我的image遮挡住一部分,请问怎么让我的窗口始终在最前面?

    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" 
            WindowStyle="None" AllowsTransparency="True" Background="Transparent" Topmost="True"
            
            >
        <Grid>
            <Image x:Name="idImageHome" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="440" Height="622" Source="/Assets/cat.jpg"
                   />
        </Grid>
    </Window>
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfApplication3
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.Left = 0.0;
                this.Top = 0.0;
                this.Width = System.Windows.SystemParameters.PrimaryScreenWidth;
                this.Height = System.Windows.SystemParameters.PrimaryScreenHeight;
            }
        }
    }


    2014年2月18日 4:02

答案

  • 一个比较笨的方法是在一个线程里面一直不停设置当前窗口在最顶端即可,这样就算窗口被任务栏挡住也可以马上恢复顶端显示,请参考以下代码:

            private static readonly IntPtr HWND_TOP = new IntPtr(0);
            private const uint SWP_NOSIZE = 0x0001;
            private const uint SWP_NOMOVE = 0x0002;
            private const uint TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
    
            [DllImport("user32.dll")]
            private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
    
            protected override void OnSourceInitialized(EventArgs e)
            {
                base.OnSourceInitialized(e);
                IntPtr handle = ((HwndSource)PresentationSource.FromVisual(this)).Handle;
                Thread t = new Thread(() =>
                {
                    while (true)
                    {
                        SetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, TOPMOST_FLAGS);
                    }
                });
                t.IsBackground = true;
                t.Start();
            }


    2014年2月20日 17:00
  • 根据你的代码,我重现了这个问题。当第一次运行该程序时,程序是置于Taskbar 之上的,但是当点击Taskbar之后,该程序就会出现在Taskbar 之下。对这个问题,我查阅了很多资料和一些代码。我们是没有办法去实现这样的功能的。在桌面上,除了Taskbar这片区域之外,是可以做到Top Most的。我查找的一个类似的帖子,不过是通过第三方的插件去实现的,可以参考下:

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/a7e45349-fffd-49e7-bf2b-ce55bfd9a552/topmost-how-make-my-aplication-work-always-on-top?forum=wpf


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年2月19日 13:31
    版主

全部回复

  • 根据你的代码,我重现了这个问题。当第一次运行该程序时,程序是置于Taskbar 之上的,但是当点击Taskbar之后,该程序就会出现在Taskbar 之下。对这个问题,我查阅了很多资料和一些代码。我们是没有办法去实现这样的功能的。在桌面上,除了Taskbar这片区域之外,是可以做到Top Most的。我查找的一个类似的帖子,不过是通过第三方的插件去实现的,可以参考下:

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/a7e45349-fffd-49e7-bf2b-ce55bfd9a552/topmost-how-make-my-aplication-work-always-on-top?forum=wpf


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年2月19日 13:31
    版主
  • 一个比较笨的方法是在一个线程里面一直不停设置当前窗口在最顶端即可,这样就算窗口被任务栏挡住也可以马上恢复顶端显示,请参考以下代码:

            private static readonly IntPtr HWND_TOP = new IntPtr(0);
            private const uint SWP_NOSIZE = 0x0001;
            private const uint SWP_NOMOVE = 0x0002;
            private const uint TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;
    
            [DllImport("user32.dll")]
            private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
    
            protected override void OnSourceInitialized(EventArgs e)
            {
                base.OnSourceInitialized(e);
                IntPtr handle = ((HwndSource)PresentationSource.FromVisual(this)).Handle;
                Thread t = new Thread(() =>
                {
                    while (true)
                    {
                        SetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, TOPMOST_FLAGS);
                    }
                });
                t.IsBackground = true;
                t.Start();
            }


    2014年2月20日 17:00