您需要位于桌面上方、应用下方并隐藏任务栏。
我首先尝试通过Hide TaskBar in WinForms Application隐藏任务栏
其次,通过使用 HWND_BOTTOM 将窗口设置为最底部。
有一些古怪的行为最好在多个操作系统的Setting a Windows form to be bottommost进行测试
编辑 - 好吧,因为任务栏不断出现,所以有点摆弄。加载的时候会有闪烁,然后就退到后面了。其中一些可以优化,但我会把它留给你 - 但这是一个工作演示。我已经测试过移动任务栏和多个桌面 - 一切似乎都正常。您还需要防止窗口关闭(如果您想要这种行为),但例如连接到 WM_CLOSE 。并忽略它(仍然不会阻止某人使用任务管理器,在这种情况下,您需要像观察者进程这样的东西,并且两个进程互相监视以检测另一个何时关闭)。我从几篇 SO 帖子和一些玩弄的文章中编译了这个。
窗口属性
在任务栏中显示 = false
WindowState = 最大化
控制框 = 假
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;
命名空间桌面替换
{
公共部分类Form1:表格
{
私人布尔_enableOverride;
内部类 NativeMethods
{
公共常量 int WM_WINDOWPOSCHANGING = 0x46;
公共常量 int WM_WINDOWPOSCHANGED = 0x47;
公共常量 int GWL_HWNDPARENT = -8;
公共常量 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
{
公共 IntPtr hWnd;
公共 IntPtr hwndInsertAfter;
公共整数 x;
公共整数 y;
公共 int cx;
公共信息;
公共 SetWindowPosFlags 标志;
// 返回lParam参数指向的WINDOWPOS结构
// WM_WINDOWPOSCHANGING 或 WM_WINDOWPOSCHANGED 消息。
公共静态WINDOWPOS FromMessage(消息消息)
{
// 将 lParam 参数编组到 WINDOWPOS 结构,
// 并返回新结构
返回 (WINDOWPOS)Marshal.PtrToStructure(msg.LParam, typeof(WINDOWPOS));
}
//替换lParam指向的原始WINDOWPOS结构
// WM_WINDOWPOSCHANGING 或 WM_WINDOWPSCHANGING 消息的参数
// 有了这个,这样本机窗口就可以看到任何
// 我们对其值所做的更改。
公共无效更新消息(消息消息)
{
// 将此更新后的结构封送回 lParam,以便原生
// 窗口可以响应我们的更改。
// 它指向的旧结构也应该被删除。
Marshal.StructureToPtr(this, msg.LParam, true);
}
}
}
公共静态类 HWND
{
公共静态只读 IntPtr
NOTOPMOST = 新的 IntPtr(-2),
广播 = 新的 IntPtr(0xffff),
TOPMOST = 新的 IntPtr(-1),
TOP = 新的 IntPtr(0),
底部 = 新的 IntPtr(1);
}
公共静态类 SWP
{
公共静态只读 int
噪声 = 0x0001,
NOMOVE = 0x0002,
NOZORDER = 0x0004,
NOREDRAW = 0x0008,
无激活 = 0x0010,
画框 = 0x0020,
FRAMECHANGED = 0x0020,
显示窗口 = 0x0040,
隐藏窗口 = 0x0080,
NOCOPYBITS = 0x0100,
NOOWNERZORDER = 0x0200,
NOREPOSITION = 0x0200,
NOSENDCHANGING = 0x0400,
延迟 = 0x2000,
ASYNCWINDOWPOS = 0x4000;
}
[DllImport("user32.dll", SetLastError = true)]
静态外部 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);
公共表格1()
{
初始化组件();
}
私人无效Form1_Load(对象发送者,EventArgs e)
{
IntPtr hprog = FindWindowEx(
查找窗口Ex(
FindWindow("Progman", "程序管理器"),
IntPtr.Zero, "SHELLDLL_DefView", ""
),
IntPtr.Zero, "SysListView32", "FolderView"
);
SetWindowLong(this.Handle, NativeMethods.GWL_HWNDPARENT, hprog);
}
受保护的覆盖无效 WndProc(参考消息 m)
{
如果(_enableOverride)
{
if (m.Msg == NativeMethods.WM_WINDOWPOSCHANGING)
{
// 提取该消息对应的WINDOWPOS结构
NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(m);
wndPos.flags = wndPos.flags | NativeMethods.SetWindowPosFlags.SWP_NOZORDER;
wndPos.UpdateMessage(m);
}
}
base.WndProc(参考 m);
}
private void timer1_Tick(对象发送者,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 = 真;
}
}
}
既然您使用的是 WPF - 请尝试一下。它需要一些清理/格式化,但你明白了:)
使用系统;
使用 System.Diagnostics;
使用 System.Runtime.InteropServices;
使用 System.Windows;
使用 System.Windows.Interop;
使用 System.Windows.Threading;
命名空间 WpfApplication1
{
///
/// MainWindow.xaml 的交互逻辑
///
公共部分类 MainWindow : 窗口
{
公共主窗口()
{
this.SourceInitialized += MainWindow_SourceInitialized;
this.WindowStyle = WindowStyle.None;
this.Loaded += Window_Loaded;
this.WindowState = WindowState.Maximized;
初始化组件();
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 500);
dispatcherTimer.Start();
}
私人布尔_enableOverride;
内部类 NativeMethods
{
公共常量 int WM_WINDOWPOSCHANGING = 0x46;
公共常量 int WM_WINDOWPOSCHANGED = 0x47;
公共常量 int GWL_HWNDPARENT = -8;
公共常量 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
{
公共 IntPtr hWnd;
公共 IntPtr hwndInsertAfter;
公共整数 x;
公共整数 y;
公共 int cx;
公共信息;
公共 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 消息的参数
// 有了这个,这样本机窗口就可以看到任何
// 我们对其值所做的更改。
公共无效更新消息(IntPtr lParam)
{
// 将此更新后的结构封送回 lParam,以便原生
// 窗口可以响应我们的更改。
// 它指向的旧结构也应该被删除。
Marshal.StructureToPtr(this, lParam, true);
}
}
}
公共静态类 HWND
{
公共静态只读 IntPtr
NOTOPMOST = 新的 IntPtr(-2),
广播 = 新的 IntPtr(0xffff),
TOPMOST = 新的 IntPtr(-1),
TOP = 新的 IntPtr(0),
底部 = 新的 IntPtr(1);
}
公共静态类 SWP
{
公共静态只读 int
噪声 = 0x0001,
NOMOVE = 0x0002,
NOZORDER = 0x0004,
NOREDRAW = 0x0008,
无激活 = 0x0010,
画框 = 0x0020,
FRAMECHANGED = 0x0020,
显示窗口 = 0x0040,
隐藏窗口 = 0x0080,
NOCOPYBITS = 0x0100,
NOOWNERZORDER = 0x0200,
NOREPOSITION = 0x0200,
NOSENDCHANGING = 0x0400,
延迟 = 0x2000,
ASYNCWINDOWPOS = 0x4000;
}
[DllImport("user32.dll", SetLastError = true)]
静态外部 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)
{
//确保我们不重叠任务栏。
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 = 真;
}
私人 IntPtr WndProc(IntPtr hwnd,int msg,IntPtr wParam,IntPtr lParam,ref bool 处理)
{
如果(_enableOverride)
{
if (msg == NativeMethods.WM_WINDOWPOSCHANGING)
{
Debug.WriteLine("WM_WINDOWPOSCHANGING");
// 提取该消息对应的WINDOWPOS结构
//lParam 有指向 WindowsPos 结构的指针,如果它是我们的 WM_WINDOWPOSCHANGING 结构
NativeMethods.WINDOWPOS wndPos = NativeMethods.WINDOWPOS.FromMessage(lParam);
wndPos.flags = wndPos.flags | NativeMethods.SetWindowPosFlags.SWP_NOZORDER;
wndPos.UpdateMessage(lParam);
//处理=真;
}
}
返回 IntPtr.Zero;
}
私人无效MainWindow_SourceInitialized(对象发送者,EventArgs e)
{
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}
私人无效Window_Loaded(对象发送者,RoutedEventArgs e)
{
IntPtr hWnd = new WindowInteropHelper(this).Handle;
IntPtr hprog = FindWindowEx(
查找窗口Ex(
FindWindow("Progman", "程序管理器"),
IntPtr.Zero, "SHELLDLL_DefView", ""
),
IntPtr.Zero, "SysListView32", "FolderView"
);
SetWindowLong(hWnd, NativeMethods.GWL_HWNDPARENT, hprog);
}
}
}