对于我正在做的软件项目,我需要replace桌面窗口。
要求:
我目前一直在尝试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); } } }