Search code examples
c#wpf

Overlay windows is not coming on top when ShowInTaskbar="False" is set at window level and uiAccess="true"?


I am developing one overlay application(WPF app in .net 6 in visual studio 2022) to make window to show on top of all the application.

Added app.Manifest file and made uiacceess=true app.manifest:

    <requestedExecutionLevel level="asInvoker" uiAccess="true" />

MainWindow.xaml:

<Window x:Class="WpfApp2.MainWindow"

        ...
        Title="MainWindow" Height="450" Width="800"  ShowInTaskbar="False"  >

If i remove the ShowInTaskbar = false setting from window level and build and sign the exe - at this time the exe is coming on top of all the apps .

Just want to understand why ShowInTaskbar = false(setting in window) property is not allowing the window to come on top of other application/games eventhough we made above changes?


Solution

  • You could try the workaround suggested here:

    "When we set ShowInTaskbar=false on the Window, WPF is for some reason creating a hidden owner window that does not have WS_EX_TOPMOST set for its extended window style, regardless of whether our window has TopMost=true.

    using System
    using System.Windows.Interop;
    
    public partial class SomeWindow
    {
        public enum GetWindowCmd : uint
        {
            GW_HWNDFIRST = 0
            GW_HWNDLAST = 1
            GW_HWNDNEXT = 2
            GW_HWNDPREV = 3,
            GW_OWNER = 4,
            GW_CHILD = 5,
            GW_ENABLEDPOPUP = 6
        }
    
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindow(IntPtr hWnd, GetWindowCmd uCmd);
    
        [Flags]
        public enum SetWindowPosFlags
        {
            SWP_NOSIZE = 0x0001,
            SWP_NOMOVE = 0x0002,
            SWP_NOZORDER = 0x0004,
            SWP_NOREDRAW = 0x0008,
            SWP_NOACTIVATE = 0x0010,
            SWP_FRAMECHANGED = 0x0020,
            SWP_SHOWWINDOW = 0x0040,
            SWP_HIDEWINDOW = 0x0080,
            SWP_NOCOPYBITS = 0x0100,
            SWP_NOOWNERZORDER = 0x0200,
            SWP_NOSENDCHANGING = 0x0400
        }
    
        [DllImport("user32.dll")]
        public static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPosFlags uFlags);
    
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            IntPtr hWnd = new WindowInteropHelper(this).Handle;
    
            IntPtr hWndHiddenOwner = GetWindow(hWnd, GetWindowCmd.GW_OWNER);
    
            if (hWndHiddenOwner != IntPtr.Zero)
            {
                IntPtr HWND_TOPMOST = new IntPtr(-1);
                SetWindowPos(hWndHiddenOwner, HWND_TOPMOST, 0, 0, 0, 0,
                   SetWindowPosFlags.SWP_NOMOVE |
                   SetWindowPosFlags.SWP_NOSIZE |
                   SetWindowPosFlags.SWP_NOACTIVATE);
            }
        }
    }