replaceWindows桌面

对于我正在做的软件项目,我需要replace桌面窗口。

要求:

  • 窗口需要在桌面图标上(不再需要)
  • 多屏幕/显示器
  • 其他窗口可以照常运行
  • 我想保持任务栏完好无损
  • 当按下Windows + D或单击桌面button时,它应该显示我的应用程序。

我目前一直在尝试Naskohell ,但这取代了包括任务栏在内的整个桌面。 我可以写我自己的任务栏,但我觉得这是我希望避免的额外工作。

然后是SetWindowPos函数,但我不知道使用哪个Z级来实现我想要的。

有谁能告诉我什么是达到我的要求的最好方法?

你需要在桌面之上,在你的应用程序之下,并隐藏任务栏。 Id首先尝试通过在WinForms应用程序中隐藏任务栏隐藏任务栏

其次,通过使用HWND_BOTTOM将窗口设置到最底部。 有一些古怪的行为是最好的测试跨多个操作系统的Windows窗体设置为最底层


编辑 – 好了,因为任务栏不断显示出来,有一点摆弄。 加载时会有闪烁,然后到后面。 其中的一些可以优化,但我会留给你 – 但这是一个工作演示。 我已经测试移动任务栏和多个桌面 – 所有似乎工作正常。 您还需要防止窗口关闭(如果您想要这样的行为),但是需要挂钩到WM_CLOSE中。 并忽略它(仍然不会阻止某人使用任务管理器,在这种情况下,您需要类似于观察器进程,并进行相互监视以检测另一个关闭时)。 我已经从几个SO帖子和一些旋转编译这个。

窗口属性显示在任务栏= false WindowState =最大化ControlBox = false FormBorderStyle =无

使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Diagnostics;
使用System.Drawing;
使用System.Linq;
使用System.Runtime.InteropServices;
使用System.Text;
使用System.Threading.Tasks;
使用System.Windows.Forms;

命名空间DesktopReplacement
 {
    公共部分类Form1:Form
     {
         private bool _enableOverride;
        内部类NativeMethods
         {
            公共const int WM_WINDOWPOSCHANGING = 0x46;
            公共const int WM_WINDOWPOSCHANGED = 0x47;
             public const int GWL_HWNDPARENT = -8;
             public const int SW_SHOW = 1;


             [标志()]
            公共枚举SetWindowPosFlags
             {
                 SWP_NOSIZE = 0x1,
                 SWP_NOMOVE = 0x2,
                 SWP_NOZORDER = 0x4,
                 SWP_NOREDRAW = 0x8,
                 SWP_NOACTIVATE = 0x10,
                 SWP_FRAMECHANGED = 0x20,
                 SWP_DRAWFRAME = SWP_FRAMECHANGED,
                 SWP_SHOWWINDOW = 0x40,
                 SWP_HIDEWINDOW = 0x80,
                 SWP_NOCOPYBITS = 0x100,
                 SWP_NOOWNERZORDER = 0x200,
                 SWP_NOREPOSITION = SWP_NOOWNERZORDER,
                 SWP_NOSENDCHANGING = 0x400,
                 SWP_DEFERERASE = 0x2000,
                 SWP_ASYNCWINDOWPOS = 0x4000,
             }

            公共枚举WindowZOrder
             {
                 HWND_TOP = 0,
                 HWND_BOTTOM = 1,
                 HWND_TOPMOST = -1,
                 HWND_NOTOPMOST = -2,
             }

             [StructLayout(LayoutKind.Sequential)]
            公共结构WINDOWPOS
             {
                 public IntPtr hWnd;
                 public IntPtr hwndInsertAfter;
                 public int x;
                 public int y;
                 public int cx;
                 public int cy;
                公共SetWindowPosFlags标志;

                 //返回lParam参数指向的WINDOWPOS结构
                 // WM_WINDOWPOSCHANGING或WM_WINDOWPOSCHANGED消息。
                公共静态WINDOWPOS FromMessage(消息消息)
                 {
                     //将lParam参数设置为WINDOWPOS结构,
                     //并返回新的结构
                    返回(WINDOWPOS)Marshal.PtrToStructure(msg.LParam,typeof(WINDOWPOS));
                 }

                 //替换lParam指向的原始WINDOWPOS结构
                 // WM_WINDOWPOSCHANGING或WM_WINDOWPSCHANGING消息的参数
                 //用这个,这样本地窗口就能看到任何东西
                 //改变了我们对它的值。
                公共无效的UpdateMessage(消息味精)
                 {
                     //将这个更新后的结构重新编译回lParam,以便原生
                     / /窗口可以响应我们的变化。
                     //它指向的旧结构也应该被删除。
                     Marshal.StructureToPtr(this,msg.LParam,true);
                 }
             }
         }


        公共静态类HWND
         {
            公共静态只读IntPtr
             NOTOPMOST =新的IntPtr(-2),
             BROADCAST =新的IntPtr(0xffff),
             TOPMOST =新的IntPtr(-1),
             TOP =新的IntPtr(0),
             BOTTOM =新的IntPtr(1);
         }


        公共静态类SWP
         {
             public static readonly int
             NOSIZE = 0x0001,
             NOMOVE = 0x0002,
             NOZORDER = 0x0004,
             NOREDRAW = 0x0008,
             NOACTIVATE = 0x0010,
             DRAWFRAME = 0x0020,
             FRAMECHANGED = 0x0020,
             SHOWWINDOW = 0x0040,
             HIDEWINDOW = 0x0080,
             NOCOPYBITS = 0x0100,
             NOOWNERZORDER = 0x0200,
             NOREPOSITION = 0x0200,
             NOSENDCHANGING = 0x0400,
             DEFERERASE = 0x2000,
             ASYNCWINDOWPOS = 0x4000;
         }


         [DllImport(“user32.dll”,SetLastError = true)]
        静态外部int SetWindowLong(IntPtr hWnd,int nIndex,IntPtr dwNewLong);

         [DllImport(“user32.dll”,SetLastError = true)]
        静态extern IntPtr FindWindow(字符串lpWindowClass,字符串lpWindowName);

         [DllImport(“user32.dll”,SetLastError = true)]
        静态外部IntPtr FindWindowEx(IntPtr parentHandle,IntPtr childAfter,字符串className,字符串windowTitle);

         [的DllImport( “USER32.DLL”)]
         public static extern bool SetWindowPos(IntPtr hWnd,IntPtr hWndInsertAfter,int X,int Y,int cx,int cy,int uFlags);

         [的DllImport( “USER32.DLL”)]
         private static extern int ShowWindow(IntPtr hwnd,int command);



         public Form1()
         {
            的InitializeComponent();
         }

        私人无效Form1_Load(对象发件人,EventArgs e)
         {

             IntPtr hprog = FindWindowEx(
                 FindWindowEx(
                     FindWindow(“Progman”,“程序管理器”),
                     IntPtr.Zero,“SHELLDLL_DefView”,“”
                 )
                 IntPtr.Zero,“SysListView32”,“FolderView”
             );

             SetWindowLong(this.Handle,NativeMethods.GWL_HWNDPARENT,hprog);
         }

        保护覆盖无效WndProc(参考消息m)
         {
            如果(_enableOverride)
             {
                如果(m.Msg == NativeMethods.WM_WINDOWPOSCHANGING)
                 {

                     //提取对应于这个消息的WINDOWPOS结构
                     NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(m);


                     wndPos.flags = wndPos.flags |  NativeMethods.SetWindowPosFlags.SWP_NOZORDER;
                     wndPos.UpdateMessage(米);

                 }
             }

             base.WndProc(ref m);
         }


         private void timer1_Tick(object sender,EventArgs e)
         {
             SetWindowPos(Handle,HWND.BOTTOM,0,0,0,SWP.SHOWWINDOW | SWP.NOMOVE | SWP.NOOWNERZORDER | SWP.NOSIZE | SWP.NOACTIVATE);

             IntPtr task = FindWindow(“Shell_TrayWnd”,“”);
             ShowWindow(task,NativeMethods.SW_SHOW);

             _enableOverride = true;
         }

     }
 }

既然你正在使用WPF – 试试这个。 它需要一些清理/格式,但你得到的重点:)

使用系统;
使用System.Diagnostics;
使用System.Runtime.InteropServices;
使用System.Windows;
使用System.Windows.Interop;
使用System.Windows.Threading;

命名空间WpfApplication1
 {
     /// 
     /// MainWindow.xaml的交互逻辑
     /// 
    公共部分类MainWindow:Window
     {
         public MainWindow()
         {
             this.SourceInitialized + = MainWindow_SourceInitialized;
             this.WindowStyle = WindowStyle.None;
             this.Loaded + = Window_Loaded;
             this.WindowState = WindowState.Maximized;
            的InitializeComponent();


             DispatcherTimer dispatcherTimer = new DispatcherTimer();
             dispatcherTimer.Tick + = dispatcherTimer_Tick;
             dispatcherTimer.Interval = new TimeSpan(0,0,0,500);
             dispatcherTimer.Start();

         }


         private bool _enableOverride;
        内部类NativeMethods
         {
            公共const int WM_WINDOWPOSCHANGING = 0x46;
            公共const int WM_WINDOWPOSCHANGED = 0x47;
             public const int GWL_HWNDPARENT = -8;
             public const int SW_SHOW = 1;


             [标志]
            公共枚举SetWindowPosFlags
             {
                 SWP_NOSIZE = 0x1,
                 SWP_NOMOVE = 0x2,
                 SWP_NOZORDER = 0x4,
                 SWP_NOREDRAW = 0x8,
                 SWP_NOACTIVATE = 0x10,
                 SWP_FRAMECHANGED = 0x20,
                 SWP_DRAWFRAME = SWP_FRAMECHANGED,
                 SWP_SHOWWINDOW = 0x40,
                 SWP_HIDEWINDOW = 0x80,
                 SWP_NOCOPYBITS = 0x100,
                 SWP_NOOWNERZORDER = 0x200,
                 SWP_NOREPOSITION = SWP_NOOWNERZORDER,
                 SWP_NOSENDCHANGING = 0x400,
                 SWP_DEFERERASE = 0x2000,
                 SWP_ASYNCWINDOWPOS = 0x4000
             }

            公共枚举WindowZOrder
             {
                 HWND_TOP = 0,
                 HWND_BOTTOM = 1,
                 HWND_TOPMOST = -1,
                 HWND_NOTOPMOST = -2
             }

             [StructLayout(LayoutKind.Sequential)]
            公共结构WINDOWPOS
             {
                 public IntPtr hWnd;
                 public IntPtr hwndInsertAfter;
                 public int x;
                 public int y;
                 public int cx;
                 public int cy;
                公共SetWindowPosFlags标志;

                 //返回lParam参数指向的WINDOWPOS结构
                 // WM_WINDOWPOSCHANGING或WM_WINDOWPOSCHANGED消息。
                公共静态WINDOWPOS FromMessage(IntPtr lParam)
                 {
                     //将lParam参数设置为WINDOWPOS结构,
                     //并返回新的结构
                    返回(WINDOWPOS)Marshal.PtrToStructure(lParam,typeof(WINDOWPOS));
                 }

                 //替换lParam指向的原始WINDOWPOS结构
                 // WM_WINDOWPOSCHANGING或WM_WINDOWPSCHANGING消息的参数
                 //用这个,这样本地窗口就能看到任何东西
                 //改变了我们对它的值。
                公共无效UpdateMessage(IntPtr lParam)
                 {
                     //将这个更新后的结构重新编译回lParam,以便原生
                     / /窗口可以响应我们的变化。
                     //它指向的旧结构也应该被删除。
                     Marshal.StructureToPtr(this,lParam,true);
                 }
             }
         }


        公共静态类HWND
         {
            公共静态只读IntPtr
             NOTOPMOST =新的IntPtr(-2),
             BROADCAST =新的IntPtr(0xffff),
             TOPMOST =新的IntPtr(-1),
             TOP =新的IntPtr(0),
             BOTTOM =新的IntPtr(1);
         }


        公共静态类SWP
         {
             public static readonly int
             NOSIZE = 0x0001,
             NOMOVE = 0x0002,
             NOZORDER = 0x0004,
             NOREDRAW = 0x0008,
             NOACTIVATE = 0x0010,
             DRAWFRAME = 0x0020,
             FRAMECHANGED = 0x0020,
             SHOWWINDOW = 0x0040,
             HIDEWINDOW = 0x0080,
             NOCOPYBITS = 0x0100,
             NOOWNERZORDER = 0x0200,
             NOREPOSITION = 0x0200,
             NOSENDCHANGING = 0x0400,
             DEFERERASE = 0x2000,
             ASYNCWINDOWPOS = 0x4000;
         }


         [DllImport(“user32.dll”,SetLastError = true)]
        静态外部int SetWindowLong(IntPtr hWnd,int nIndex,IntPtr dwNewLong);

         [DllImport(“user32.dll”,SetLastError = true)]
        静态extern IntPtr FindWindow(字符串lpWindowClass,字符串lpWindowName);

         [DllImport(“user32.dll”,SetLastError = true)]
        静态外部IntPtr FindWindowEx(IntPtr parentHandle,IntPtr childAfter,字符串className,字符串windowTitle);

         [的DllImport( “USER32.DLL”)]
         public static extern bool SetWindowPos(IntPtr hWnd,IntPtr hWndInsertAfter,int X,int Y,int cx,int cy,int uFlags);

         [的DllImport( “USER32.DLL”)]
         private static extern int ShowWindow(IntPtr hwnd,int command);


         private void dispatcherTimer_Tick(object sender,EventArgs e)
         {
             //确保我们不重叠任务栏。
             SetWindowPos(new WindowInteropHelper(this).Handle,HWND.BOTTOM,0,0,0,SWP.SHOWWINDOW | SWP.NOMOVE | SWP.NOOWNERZORDER | SWP.NOSIZE | SWP.NOACTIVATE);

             IntPtr task = FindWindow(“Shell_TrayWnd”,“”);
             ShowWindow(task,NativeMethods.SW_SHOW);

             _enableOverride = true;
         }


        私人IntPtr WndProc(IntPtr hwnd,int msg,IntPtr wParam,IntPtr lParam,ref布尔处理)
         {
            如果(_enableOverride)
             {
                 if(msg == NativeMethods.WM_WINDOWPOSCHANGING)
                 {
                    的Debug.WriteLine( “WM_WINDOWPOSCHANGING”);
                     //提取对应于这个消息的WINDOWPOS结构
                    如果我们的WM_WINDOWPOSCHANGING结构体,// lParam具有ptr到WindowsPos结构体
                     NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(lParam);

                     wndPos.flags = wndPos.flags |  NativeMethods.SetWindowPosFlags.SWP_NOZORDER;
                     wndPos.UpdateMessage(lParam的);
                     // handled = true;
                 }
             }

            返回IntPtr.Zero;
         }

         private void MainWindow_SourceInitialized(object sender,EventArgs e)
         {
             HwndSource source = PresentationSource.FromVisual(this)as HwndSource;
             source.AddHook(的WndProc);
         }

         private void Window_Loaded(object sender,RoutedEventArgs e)
         {
             IntPtr hWnd = new WindowInteropHelper(this).Handle;

             IntPtr hprog = FindWindowEx(
                            FindWindowEx(
                                FindWindow(“Progman”,“程序管理器”),
                                IntPtr.Zero,“SHELLDLL_DefView”,“”
                            )
                            IntPtr.Zero,“SysListView32”,“FolderView”
                        );

             SetWindowLong(hWnd,NativeMethods.GWL_HWNDPARENT,hprog);
         }
     }
 }