如何在不使用 :wpf c# 覆盖任务栏的情况下制作全屏模式
How to make full screen mode, without covering the taskbar using :wpf c#
我需要在我的 WPF 应用程序中更改 windows 任务栏。为此,我设置了 WindowStyle="None"
,这意味着禁用 windows 任务栏,并使用用于恢复、最小化和关闭应用程序的按钮制作自定义任务栏。现在我的问题是,如果应用程序处于最大化模式,那么我在 windows 上看不到开始菜单。
我在这里发现了一个类似的问题,但是当我尝试这段代码时它没有编译。 full screen mode, but don't cover the taskbar
如何创建自己的任务栏并在最大化时看到 windows 开始菜单? xaml里面有属性window可以设置吗?
你可以试试这个:
MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
在 CodeProject 上找到了可能有帮助的解决方案:http://www.codeproject.com/Articles/107994/Taskbar-with-Window-Maximized-and-WindowState-to-N
WindowStyle="None"
WindowState="Maximized"
ResizeMode="NoResize"
和
this.Width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
this.Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
this.Left = 0;
this.Top = 0;
this.WindowState = WindowState.Normal;
WindowStyle="None"
AllowsTransparency="True"
和
this.Top = 0;
this.Left = 0;
this.Width = SystemParameters.WorkArea.Width;
this.Height = SystemParameters.WorkArea.Height;
建议的解决方案对我有效但仍然需要将像素校正为 dpi setter 值 window 以具有正确的尺寸,无论用户设置如何:
在 xaml 中:
WindowStyle="None" WindowState="Maximized" ResizeMode="NoResize"
在代码中:
public MainWindow()
{
InitializeComponent();
var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
var pixelWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width ;
var pixelHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
var pixelToDPI = 96.0 / graphics.DpiX ;
this.Width = pixelWidth * pixelToDPI;
this.Height = pixelHeight * pixelToDPI;
this.Left = 0;
this.Top = 0;
this.WindowState = WindowState.Normal;
}
WPF 的解决方案
假设我们想要将 WPF 项目的主窗口放置在屏幕的 bottom-right 处,但不覆盖任务栏。
我们将这样写:
public MainWindow()
{
InitializeComponent();
// set position of window on screen
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
this.Top = SystemParameters.WorkArea.Bottom - this.Height;
}
this = 我们的对象(主窗口)
当我们从 PrimarySrceenWidth 中减去我们的 window 位置(左)时,我们首先要放置左参数。
然后,我们通过从屏幕底部的工作区域中减去 windows 高度来获得最低点。
屏幕工作区不包含任务栏!
尽情享受吧!
阿芙丽
您可以通过添加以下内容轻松地在 XAML 中添加对高度的限制:
MaxHeight="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenHeight}}"
进入Window的标签。
我在下面 link 的讨论中找到了一个非常巧妙的解决方案来解决这个问题,
https://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/
开箱即用。刚刚在此处添加此内容以供参考,以在不久的将来帮助任何人。
None 的现有解决方案适用于以扩展模式连接的多个屏幕。
将提供的解决方案粘贴到此处以防止其从博客中删除,
需要从 XAML 或后面的代码绑定 SourceInitialized 事件,
this.SourceInitialized += new EventHandler(Window1_SourceInitialized);
虽然这是事件回调的源代码,
void Window1_SourceInitialized(object sender, EventArgs e)
{
WindowSizing.WindowInitialized(this);
}
这是 WindowSizing.cs、
的代码
using System;
using System.Runtime.InteropServices;
using System.Windows;
namespace OfficeStyleWindowProject
{
public static class WindowSizing
{
const int MONITOR_DEFAULTTONEAREST = 0x00000002;
#region DLLImports
[DllImport("shell32", CallingConvention = CallingConvention.StdCall)]
public static extern int SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
[DllImport("user32", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32")]
internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
[DllImport("user32")]
internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
#endregion
private static MINMAXINFO AdjustWorkingAreaForAutoHide(IntPtr monitorContainingApplication, MINMAXINFO mmi)
{
IntPtr hwnd = FindWindow("Shell_TrayWnd", null);
if (hwnd == null) return mmi;
IntPtr monitorWithTaskbarOnIt = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (!monitorContainingApplication.Equals(monitorWithTaskbarOnIt)) return mmi;
APPBARDATA abd = new APPBARDATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = hwnd;
SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref abd);
int uEdge = GetEdge(abd.rc);
bool autoHide = System.Convert.ToBoolean(SHAppBarMessage((int)ABMsg.ABM_GETSTATE, ref abd));
if (!autoHide) return mmi;
switch (uEdge)
{
case (int)ABEdge.ABE_LEFT:
mmi.ptMaxPosition.x += 2;
mmi.ptMaxTrackSize.x -= 2;
mmi.ptMaxSize.x -= 2;
break;
case (int)ABEdge.ABE_RIGHT:
mmi.ptMaxSize.x -= 2;
mmi.ptMaxTrackSize.x -= 2;
break;
case (int)ABEdge.ABE_TOP:
mmi.ptMaxPosition.y += 2;
mmi.ptMaxTrackSize.y -= 2;
mmi.ptMaxSize.y -= 2;
break;
case (int)ABEdge.ABE_BOTTOM:
mmi.ptMaxSize.y -= 2;
mmi.ptMaxTrackSize.y -= 2;
break;
default:
return mmi;
}
return mmi;
}
private static int GetEdge(RECT rc)
{
int uEdge = -1;
if (rc.top == rc.left && rc.bottom > rc.right)
uEdge = (int)ABEdge.ABE_LEFT;
else if (rc.top == rc.left && rc.bottom < rc.right)
uEdge = (int)ABEdge.ABE_TOP;
else if (rc.top > rc.left)
uEdge = (int)ABEdge.ABE_BOTTOM;
else
uEdge = (int)ABEdge.ABE_RIGHT;
return uEdge;
}
public static void WindowInitialized(Window window)
{
IntPtr handle = (new System.Windows.Interop.WindowInteropHelper(window)).Handle;
System.Windows.Interop.HwndSource.FromHwnd(handle).AddHook(new System.Windows.Interop.HwndSourceHook(WindowProc));
}
private static IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
{
switch (msg)
{
case 0x0024:
WmGetMinMaxInfo(hwnd, lParam);
handled = true;
break;
}
return (IntPtr)0;
}
private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitorContainingApplication != System.IntPtr.Zero)
{
MONITORINFO monitorInfo = new MONITORINFO();
GetMonitorInfo(monitorContainingApplication, monitorInfo);
RECT rcWorkArea = monitorInfo.rcWork;
RECT rcMonitorArea = monitorInfo.rcMonitor;
mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x; //maximum drag X size for the window
mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y; //maximum drag Y size for the window
mmi.ptMinTrackSize.x = 800; //minimum drag X size for the window
mmi.ptMinTrackSize.y = 600; //minimum drag Y size for the window
mmi = AdjustWorkingAreaForAutoHide(monitorContainingApplication, mmi); //need to adjust sizing if taskbar is set to autohide
}
Marshal.StructureToPtr(mmi, lParam, true);
}
public enum ABEdge
{
ABE_LEFT = 0,
ABE_TOP = 1,
ABE_RIGHT = 2,
ABE_BOTTOM = 3
}
public enum ABMsg
{
ABM_NEW = 0,
ABM_REMOVE = 1,
ABM_QUERYPOS = 2,
ABM_SETPOS = 3,
ABM_GETSTATE = 4,
ABM_GETTASKBARPOS = 5,
ABM_ACTIVATE = 6,
ABM_GETAUTOHIDEBAR = 7,
ABM_SETAUTOHIDEBAR = 8,
ABM_WINDOWPOSCHANGED = 9,
ABM_SETSTATE = 10
}
[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA
{
public int cbSize;
public IntPtr hWnd;
public int uCallbackMessage;
public int uEdge;
public RECT rc;
public bool lParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MONITORINFO
{
public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
public RECT rcMonitor = new RECT();
public RECT rcWork = new RECT();
public int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
public POINT(int x, int y)
{
this.x = x;
this.y = y;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
}
}
~乌马尔
我需要在我的 WPF 应用程序中更改 windows 任务栏。为此,我设置了 WindowStyle="None"
,这意味着禁用 windows 任务栏,并使用用于恢复、最小化和关闭应用程序的按钮制作自定义任务栏。现在我的问题是,如果应用程序处于最大化模式,那么我在 windows 上看不到开始菜单。
我在这里发现了一个类似的问题,但是当我尝试这段代码时它没有编译。 full screen mode, but don't cover the taskbar
如何创建自己的任务栏并在最大化时看到 windows 开始菜单? xaml里面有属性window可以设置吗?
你可以试试这个:
MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
在 CodeProject 上找到了可能有帮助的解决方案:http://www.codeproject.com/Articles/107994/Taskbar-with-Window-Maximized-and-WindowState-to-N
WindowStyle="None"
WindowState="Maximized"
ResizeMode="NoResize"
和
this.Width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
this.Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
this.Left = 0;
this.Top = 0;
this.WindowState = WindowState.Normal;
WindowStyle="None"
AllowsTransparency="True"
和
this.Top = 0;
this.Left = 0;
this.Width = SystemParameters.WorkArea.Width;
this.Height = SystemParameters.WorkArea.Height;
建议的解决方案对我有效但仍然需要将像素校正为 dpi setter 值 window 以具有正确的尺寸,无论用户设置如何:
在 xaml 中:
WindowStyle="None" WindowState="Maximized" ResizeMode="NoResize"
在代码中:
public MainWindow()
{
InitializeComponent();
var graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero);
var pixelWidth = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width ;
var pixelHeight = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
var pixelToDPI = 96.0 / graphics.DpiX ;
this.Width = pixelWidth * pixelToDPI;
this.Height = pixelHeight * pixelToDPI;
this.Left = 0;
this.Top = 0;
this.WindowState = WindowState.Normal;
}
WPF 的解决方案
假设我们想要将 WPF 项目的主窗口放置在屏幕的 bottom-right 处,但不覆盖任务栏。 我们将这样写:
public MainWindow()
{
InitializeComponent();
// set position of window on screen
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
this.Top = SystemParameters.WorkArea.Bottom - this.Height;
}
this = 我们的对象(主窗口) 当我们从 PrimarySrceenWidth 中减去我们的 window 位置(左)时,我们首先要放置左参数。 然后,我们通过从屏幕底部的工作区域中减去 windows 高度来获得最低点。 屏幕工作区不包含任务栏!
尽情享受吧!
阿芙丽
您可以通过添加以下内容轻松地在 XAML 中添加对高度的限制:
MaxHeight="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenHeight}}"
进入Window的标签。
我在下面 link 的讨论中找到了一个非常巧妙的解决方案来解决这个问题, https://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/
开箱即用。刚刚在此处添加此内容以供参考,以在不久的将来帮助任何人。
None 的现有解决方案适用于以扩展模式连接的多个屏幕。
将提供的解决方案粘贴到此处以防止其从博客中删除,
需要从 XAML 或后面的代码绑定 SourceInitialized 事件,
this.SourceInitialized += new EventHandler(Window1_SourceInitialized);
虽然这是事件回调的源代码,
void Window1_SourceInitialized(object sender, EventArgs e)
{
WindowSizing.WindowInitialized(this);
}
这是 WindowSizing.cs、
的代码using System;
using System.Runtime.InteropServices;
using System.Windows;
namespace OfficeStyleWindowProject
{
public static class WindowSizing
{
const int MONITOR_DEFAULTTONEAREST = 0x00000002;
#region DLLImports
[DllImport("shell32", CallingConvention = CallingConvention.StdCall)]
public static extern int SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
[DllImport("user32", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32")]
internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
[DllImport("user32")]
internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
#endregion
private static MINMAXINFO AdjustWorkingAreaForAutoHide(IntPtr monitorContainingApplication, MINMAXINFO mmi)
{
IntPtr hwnd = FindWindow("Shell_TrayWnd", null);
if (hwnd == null) return mmi;
IntPtr monitorWithTaskbarOnIt = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (!monitorContainingApplication.Equals(monitorWithTaskbarOnIt)) return mmi;
APPBARDATA abd = new APPBARDATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = hwnd;
SHAppBarMessage((int)ABMsg.ABM_GETTASKBARPOS, ref abd);
int uEdge = GetEdge(abd.rc);
bool autoHide = System.Convert.ToBoolean(SHAppBarMessage((int)ABMsg.ABM_GETSTATE, ref abd));
if (!autoHide) return mmi;
switch (uEdge)
{
case (int)ABEdge.ABE_LEFT:
mmi.ptMaxPosition.x += 2;
mmi.ptMaxTrackSize.x -= 2;
mmi.ptMaxSize.x -= 2;
break;
case (int)ABEdge.ABE_RIGHT:
mmi.ptMaxSize.x -= 2;
mmi.ptMaxTrackSize.x -= 2;
break;
case (int)ABEdge.ABE_TOP:
mmi.ptMaxPosition.y += 2;
mmi.ptMaxTrackSize.y -= 2;
mmi.ptMaxSize.y -= 2;
break;
case (int)ABEdge.ABE_BOTTOM:
mmi.ptMaxSize.y -= 2;
mmi.ptMaxTrackSize.y -= 2;
break;
default:
return mmi;
}
return mmi;
}
private static int GetEdge(RECT rc)
{
int uEdge = -1;
if (rc.top == rc.left && rc.bottom > rc.right)
uEdge = (int)ABEdge.ABE_LEFT;
else if (rc.top == rc.left && rc.bottom < rc.right)
uEdge = (int)ABEdge.ABE_TOP;
else if (rc.top > rc.left)
uEdge = (int)ABEdge.ABE_BOTTOM;
else
uEdge = (int)ABEdge.ABE_RIGHT;
return uEdge;
}
public static void WindowInitialized(Window window)
{
IntPtr handle = (new System.Windows.Interop.WindowInteropHelper(window)).Handle;
System.Windows.Interop.HwndSource.FromHwnd(handle).AddHook(new System.Windows.Interop.HwndSourceHook(WindowProc));
}
private static IntPtr WindowProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
{
switch (msg)
{
case 0x0024:
WmGetMinMaxInfo(hwnd, lParam);
handled = true;
break;
}
return (IntPtr)0;
}
private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitorContainingApplication != System.IntPtr.Zero)
{
MONITORINFO monitorInfo = new MONITORINFO();
GetMonitorInfo(monitorContainingApplication, monitorInfo);
RECT rcWorkArea = monitorInfo.rcWork;
RECT rcMonitorArea = monitorInfo.rcMonitor;
mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);
mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);
mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x; //maximum drag X size for the window
mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y; //maximum drag Y size for the window
mmi.ptMinTrackSize.x = 800; //minimum drag X size for the window
mmi.ptMinTrackSize.y = 600; //minimum drag Y size for the window
mmi = AdjustWorkingAreaForAutoHide(monitorContainingApplication, mmi); //need to adjust sizing if taskbar is set to autohide
}
Marshal.StructureToPtr(mmi, lParam, true);
}
public enum ABEdge
{
ABE_LEFT = 0,
ABE_TOP = 1,
ABE_RIGHT = 2,
ABE_BOTTOM = 3
}
public enum ABMsg
{
ABM_NEW = 0,
ABM_REMOVE = 1,
ABM_QUERYPOS = 2,
ABM_SETPOS = 3,
ABM_GETSTATE = 4,
ABM_GETTASKBARPOS = 5,
ABM_ACTIVATE = 6,
ABM_GETAUTOHIDEBAR = 7,
ABM_SETAUTOHIDEBAR = 8,
ABM_WINDOWPOSCHANGED = 9,
ABM_SETSTATE = 10
}
[StructLayout(LayoutKind.Sequential)]
public struct APPBARDATA
{
public int cbSize;
public IntPtr hWnd;
public int uCallbackMessage;
public int uEdge;
public RECT rc;
public bool lParam;
}
[StructLayout(LayoutKind.Sequential)]
public struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class MONITORINFO
{
public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
public RECT rcMonitor = new RECT();
public RECT rcWork = new RECT();
public int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
public POINT(int x, int y)
{
this.x = x;
this.y = y;
}
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
}
}
~乌马尔