更换 windows 桌面
Replacing the windows desktop
对于我正在进行的软件项目,我需要更换桌面 window。
要求:
- Window 需要位于桌面图标上方(不再需要)
- 多个screens/monitors
- 其他windows可以运行照常
- 我想保持任务栏不变
- 当按 windows+D 或单击桌面按钮时,它应该会显示我的应用程序。
我目前一直在尝试 Naskohell,但这会替换整个桌面,包括任务栏。我可以编写自己的任务栏,但我觉得这是我可以避免的很多额外工作。
然后是SetWindowPos功能,但我不知道用哪个Z级别来实现我想要的。
谁能告诉我实现我的要求的最佳方法是什么?
您需要位于桌面之上,应用之下,并隐藏任务栏。
我首先尝试通过 Hide TaskBar in WinForms Application
隐藏任务栏
其次,使用 HWND_BOTTOM 将 window 设置到最底部。
有一些古怪的行为最好在多个 OS 的 Setting a Windows form to be bottommost
中进行测试
编辑 - 好吧,因为任务栏不断出现,所以花了一点时间。加载时会出现闪烁,然后转到后面。其中一些可以优化,但我会把它留给你 - 但这是一个工作演示。我已经测试过移动任务栏和多个桌面 - 一切似乎都正常。您还需要防止 window 关闭(如果您想要这种行为),但要连接到 WM_CLOSE 中。并忽略它(仍然不会阻止某人使用任务管理器,在这种情况下,您需要类似观察者进程的东西,并且两个进程相互监视以检测对方何时关闭)。我从几个 SO 帖子和一些琐碎的事情中编译了这个。
window属性
在任务栏中显示 = false
WindowState = 最大化
控制框 = 假
FormBorderStyle = none
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DesktopReplacement
{
public partial class Form1 : Form
{
private bool _enableOverride;
internal class NativeMethods
{
public const int WM_WINDOWPOSCHANGING = 0x46;
public const int WM_WINDOWPOSCHANGED = 0x47;
public const int GWL_HWNDPARENT = -8;
public const int SW_SHOW = 1;
[Flags()]
public enum 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,
}
public enum WindowZOrder
{
HWND_TOP = 0,
HWND_BOTTOM = 1,
HWND_TOPMOST = -1,
HWND_NOTOPMOST = -2,
}
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
public IntPtr hWnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public SetWindowPosFlags flags;
// Returns the WINDOWPOS structure pointed to by the lParam parameter
// of a WM_WINDOWPOSCHANGING or WM_WINDOWPOSCHANGED message.
public static WINDOWPOS FromMessage(Message msg)
{
// Marshal the lParam parameter to an WINDOWPOS structure,
// and return the new structure
return (WINDOWPOS)Marshal.PtrToStructure(msg.LParam, typeof(WINDOWPOS));
}
// Replaces the original WINDOWPOS structure pointed to by the lParam
// parameter of a WM_WINDOWPOSCHANGING or WM_WINDOWPSCHANGING message
// with this one, so that the native window will be able to see any
// changes that we have made to its values.
public void UpdateMessage(Message msg)
{
// Marshal this updated structure back to lParam so the native
// window can respond to our changes.
// The old structure that it points to should be deleted, too.
Marshal.StructureToPtr(this, msg.LParam, true);
}
}
}
public static class HWND
{
public static readonly IntPtr
NOTOPMOST = new IntPtr(-2),
BROADCAST = new IntPtr(0xffff),
TOPMOST = new IntPtr(-1),
TOP = new IntPtr(0),
BOTTOM = new IntPtr(1);
}
public static class 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)]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpWindowClass, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string 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();
}
private void Form1_Load(object sender, EventArgs e)
{
IntPtr hprog = FindWindowEx(
FindWindowEx(
FindWindow("Progman", "Program Manager"),
IntPtr.Zero, "SHELLDLL_DefView", ""
),
IntPtr.Zero, "SysListView32", "FolderView"
);
SetWindowLong(this.Handle, NativeMethods.GWL_HWNDPARENT, hprog);
}
protected override void WndProc(ref Message m)
{
if (_enableOverride)
{
if (m.Msg == NativeMethods.WM_WINDOWPOSCHANGING)
{
// Extract the WINDOWPOS structure corresponding to this message
NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(m);
wndPos.flags = wndPos.flags | NativeMethods.SetWindowPosFlags.SWP_NOZORDER;
wndPos.UpdateMessage(m);
}
}
base.WndProc(ref m);
}
private void timer1_Tick(object sender, EventArgs e)
{
SetWindowPos(Handle, HWND.BOTTOM, 0, 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 - 请试一试。它需要一些 cleanup/formatting 但你明白了:)
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
namespace WpfApplication1
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class 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, 0, 500);
dispatcherTimer.Start();
}
private bool _enableOverride;
internal class NativeMethods
{
public const int WM_WINDOWPOSCHANGING = 0x46;
public const int WM_WINDOWPOSCHANGED = 0x47;
public const int GWL_HWNDPARENT = -8;
public const int SW_SHOW = 1;
[Flags]
public enum 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
}
public enum WindowZOrder
{
HWND_TOP = 0,
HWND_BOTTOM = 1,
HWND_TOPMOST = -1,
HWND_NOTOPMOST = -2
}
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
public IntPtr hWnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public SetWindowPosFlags flags;
// Returns the WINDOWPOS structure pointed to by the lParam parameter
// of a WM_WINDOWPOSCHANGING or WM_WINDOWPOSCHANGED message.
public static WINDOWPOS FromMessage(IntPtr lParam)
{
// Marshal the lParam parameter to an WINDOWPOS structure,
// and return the new structure
return (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS));
}
// Replaces the original WINDOWPOS structure pointed to by the lParam
// parameter of a WM_WINDOWPOSCHANGING or WM_WINDOWPSCHANGING message
// with this one, so that the native window will be able to see any
// changes that we have made to its values.
public void UpdateMessage(IntPtr lParam)
{
// Marshal this updated structure back to lParam so the native
// window can respond to our changes.
// The old structure that it points to should be deleted, too.
Marshal.StructureToPtr(this, lParam, true);
}
}
}
public static class HWND
{
public static readonly IntPtr
NOTOPMOST = new IntPtr(-2),
BROADCAST = new IntPtr(0xffff),
TOPMOST = new IntPtr(-1),
TOP = new IntPtr(0),
BOTTOM = new IntPtr(1);
}
public static class 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)]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpWindowClass, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string 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)
{
//ensure we don't overlap the taskbar.
SetWindowPos(new WindowInteropHelper(this).Handle, HWND.BOTTOM, 0, 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;
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (_enableOverride)
{
if (msg == NativeMethods.WM_WINDOWPOSCHANGING)
{
Debug.WriteLine("WM_WINDOWPOSCHANGING");
// Extract the WINDOWPOS structure corresponding to this message
//lParam has the ptr to a WindowsPos structure if its our WM_WINDOWPOSCHANGING struct
NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(lParam);
wndPos.flags = wndPos.flags | NativeMethods.SetWindowPosFlags.SWP_NOZORDER;
wndPos.UpdateMessage(lParam);
//handled = true;
}
}
return 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", "Program Manager"),
IntPtr.Zero, "SHELLDLL_DefView", ""
),
IntPtr.Zero, "SysListView32", "FolderView"
);
SetWindowLong(hWnd, NativeMethods.GWL_HWNDPARENT, hprog);
}
}
}
对于我正在进行的软件项目,我需要更换桌面 window。
要求:
- Window 需要位于桌面图标上方(不再需要)
- 多个screens/monitors
- 其他windows可以运行照常
- 我想保持任务栏不变
- 当按 windows+D 或单击桌面按钮时,它应该会显示我的应用程序。
我目前一直在尝试 Naskohell,但这会替换整个桌面,包括任务栏。我可以编写自己的任务栏,但我觉得这是我可以避免的很多额外工作。
然后是SetWindowPos功能,但我不知道用哪个Z级别来实现我想要的。
谁能告诉我实现我的要求的最佳方法是什么?
您需要位于桌面之上,应用之下,并隐藏任务栏。 我首先尝试通过 Hide TaskBar in WinForms Application
隐藏任务栏其次,使用 HWND_BOTTOM 将 window 设置到最底部。 有一些古怪的行为最好在多个 OS 的 Setting a Windows form to be bottommost
中进行测试编辑 - 好吧,因为任务栏不断出现,所以花了一点时间。加载时会出现闪烁,然后转到后面。其中一些可以优化,但我会把它留给你 - 但这是一个工作演示。我已经测试过移动任务栏和多个桌面 - 一切似乎都正常。您还需要防止 window 关闭(如果您想要这种行为),但要连接到 WM_CLOSE 中。并忽略它(仍然不会阻止某人使用任务管理器,在这种情况下,您需要类似观察者进程的东西,并且两个进程相互监视以检测对方何时关闭)。我从几个 SO 帖子和一些琐碎的事情中编译了这个。
window属性 在任务栏中显示 = false WindowState = 最大化 控制框 = 假 FormBorderStyle = none
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace DesktopReplacement { public partial class Form1 : Form { private bool _enableOverride; internal class NativeMethods { public const int WM_WINDOWPOSCHANGING = 0x46; public const int WM_WINDOWPOSCHANGED = 0x47; public const int GWL_HWNDPARENT = -8; public const int SW_SHOW = 1; [Flags()] public enum 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, } public enum WindowZOrder { HWND_TOP = 0, HWND_BOTTOM = 1, HWND_TOPMOST = -1, HWND_NOTOPMOST = -2, } [StructLayout(LayoutKind.Sequential)] public struct WINDOWPOS { public IntPtr hWnd; public IntPtr hwndInsertAfter; public int x; public int y; public int cx; public int cy; public SetWindowPosFlags flags; // Returns the WINDOWPOS structure pointed to by the lParam parameter // of a WM_WINDOWPOSCHANGING or WM_WINDOWPOSCHANGED message. public static WINDOWPOS FromMessage(Message msg) { // Marshal the lParam parameter to an WINDOWPOS structure, // and return the new structure return (WINDOWPOS)Marshal.PtrToStructure(msg.LParam, typeof(WINDOWPOS)); } // Replaces the original WINDOWPOS structure pointed to by the lParam // parameter of a WM_WINDOWPOSCHANGING or WM_WINDOWPSCHANGING message // with this one, so that the native window will be able to see any // changes that we have made to its values. public void UpdateMessage(Message msg) { // Marshal this updated structure back to lParam so the native // window can respond to our changes. // The old structure that it points to should be deleted, too. Marshal.StructureToPtr(this, msg.LParam, true); } } } public static class HWND { public static readonly IntPtr NOTOPMOST = new IntPtr(-2), BROADCAST = new IntPtr(0xffff), TOPMOST = new IntPtr(-1), TOP = new IntPtr(0), BOTTOM = new IntPtr(1); } public static class 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)] static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpWindowClass, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string 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(); } private void Form1_Load(object sender, EventArgs e) { IntPtr hprog = FindWindowEx( FindWindowEx( FindWindow("Progman", "Program Manager"), IntPtr.Zero, "SHELLDLL_DefView", "" ), IntPtr.Zero, "SysListView32", "FolderView" ); SetWindowLong(this.Handle, NativeMethods.GWL_HWNDPARENT, hprog); } protected override void WndProc(ref Message m) { if (_enableOverride) { if (m.Msg == NativeMethods.WM_WINDOWPOSCHANGING) { // Extract the WINDOWPOS structure corresponding to this message NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(m); wndPos.flags = wndPos.flags | NativeMethods.SetWindowPosFlags.SWP_NOZORDER; wndPos.UpdateMessage(m); } } base.WndProc(ref m); } private void timer1_Tick(object sender, EventArgs e) { SetWindowPos(Handle, HWND.BOTTOM, 0, 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 - 请试一试。它需要一些 cleanup/formatting 但你明白了:)
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; using System.Windows.Threading; namespace WpfApplication1 { /// /// Interaction logic for MainWindow.xaml /// public partial class 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, 0, 500); dispatcherTimer.Start(); } private bool _enableOverride; internal class NativeMethods { public const int WM_WINDOWPOSCHANGING = 0x46; public const int WM_WINDOWPOSCHANGED = 0x47; public const int GWL_HWNDPARENT = -8; public const int SW_SHOW = 1; [Flags] public enum 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 } public enum WindowZOrder { HWND_TOP = 0, HWND_BOTTOM = 1, HWND_TOPMOST = -1, HWND_NOTOPMOST = -2 } [StructLayout(LayoutKind.Sequential)] public struct WINDOWPOS { public IntPtr hWnd; public IntPtr hwndInsertAfter; public int x; public int y; public int cx; public int cy; public SetWindowPosFlags flags; // Returns the WINDOWPOS structure pointed to by the lParam parameter // of a WM_WINDOWPOSCHANGING or WM_WINDOWPOSCHANGED message. public static WINDOWPOS FromMessage(IntPtr lParam) { // Marshal the lParam parameter to an WINDOWPOS structure, // and return the new structure return (WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WINDOWPOS)); } // Replaces the original WINDOWPOS structure pointed to by the lParam // parameter of a WM_WINDOWPOSCHANGING or WM_WINDOWPSCHANGING message // with this one, so that the native window will be able to see any // changes that we have made to its values. public void UpdateMessage(IntPtr lParam) { // Marshal this updated structure back to lParam so the native // window can respond to our changes. // The old structure that it points to should be deleted, too. Marshal.StructureToPtr(this, lParam, true); } } } public static class HWND { public static readonly IntPtr NOTOPMOST = new IntPtr(-2), BROADCAST = new IntPtr(0xffff), TOPMOST = new IntPtr(-1), TOP = new IntPtr(0), BOTTOM = new IntPtr(1); } public static class 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)] static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpWindowClass, string lpWindowName); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string 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) { //ensure we don't overlap the taskbar. SetWindowPos(new WindowInteropHelper(this).Handle, HWND.BOTTOM, 0, 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; } private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (_enableOverride) { if (msg == NativeMethods.WM_WINDOWPOSCHANGING) { Debug.WriteLine("WM_WINDOWPOSCHANGING"); // Extract the WINDOWPOS structure corresponding to this message //lParam has the ptr to a WindowsPos structure if its our WM_WINDOWPOSCHANGING struct NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(lParam); wndPos.flags = wndPos.flags | NativeMethods.SetWindowPosFlags.SWP_NOZORDER; wndPos.UpdateMessage(lParam); //handled = true; } } return 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", "Program Manager"), IntPtr.Zero, "SHELLDLL_DefView", "" ), IntPtr.Zero, "SysListView32", "FolderView" ); SetWindowLong(hWnd, NativeMethods.GWL_HWNDPARENT, hprog); } } }