【问题标题】:How to make full screen mode, without covering the taskbar using :wpf c#如何制作全屏模式,而不使用覆盖任务栏:wpf c#
【发布时间】:2016-01-26 08:46:59
【问题描述】:

我需要在我的 WPF 应用程序中更改 Windows 任务栏。为此,我设置了WindowStyle="None",这意味着禁用 Windows 任务栏,并使用用于恢复、最小化和关闭应用程序的按钮制作自定义任务栏。现在我的问题是如果应用程序处于最大化模式,那么我在 Windows 上看不到开始菜单。

我在这里发现了一个类似的问题,但是当我尝试这段代码时它没有编译。 full screen mode, but don't cover the taskbar

如何创建自己的任务栏并在最大化时看到 Windows 开始菜单? xaml中有可以设置的属性窗口吗?

【问题讨论】:

    标签: c# wpf xaml taskbar startmenu


    【解决方案1】:

    你可以试试这个:

    MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
    MaxWidth = SystemParameters.MaximizedPrimaryScreenWidth;
    

    【讨论】:

    • 1屏以上的情况呢?
    • @Valerii 在这种情况下,您可以尝试使用Screen.AllScreens 集合。您可以循环该集合并访问screen.WorkingArea.Widthscreen.WorkingArea.Height。让我知道这是否有效,以便我可以编辑我的答案。
    • @Pikoh Screen 类是 System.Windows.Forms 的一部分,它与 WPF 不兼容。替代方案是 SystemParameters.WorkAreaWidthSystemParameters.WorkAreaHeight,这很有帮助,但不幸的是在多个显示场景中没有。
    • 此解决方案不适用于作为扩展屏幕附加的多个屏幕。我在下面提供了一个适用于任意数量屏幕的解决方案,并且每个屏幕都可以完美运行。我已经用 3 个(笔记本电脑主屏幕和两个扩展屏幕)对其进行了测试。
    【解决方案2】:

    在 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;
    

    【讨论】:

      【解决方案3】:

      您可以通过添加以下内容轻松地在 XAML 中添加高度约束:

      MaxHeight="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenHeight}}"
      

      进入Window的标签。

      【讨论】:

      • 最简单的解决方案!谢谢
      【解决方案4】:
      WindowStyle="None" 
      AllowsTransparency="True"  
      

      this.Top = 0;
      this.Left = 0;
      this.Width = SystemParameters.WorkArea.Width;
      this.Height = SystemParameters.WorkArea.Height;
      

      【讨论】:

        【解决方案5】:

        建议的解决方案对我有用仍然需要将像素更正为 dpi 设置器值,以使窗口具有正确的大小,无论用户设置如何:

        在xml中:

        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;
        }
        

        【讨论】:

        • 对我来说,我需要设置 MaxWidth 和 MaxHeight 而不是 Width 和 Height
        【解决方案6】:

        WPF 解决方案

        假设我们想要将 WPF 项目的 mainWindow 放置在屏幕的右下角,而不覆盖任务栏。 我们会这样写:

        public MainWindow()
            {
                InitializeComponent();
                // set position of window on screen
                this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
                this.Top = SystemParameters.WorkArea.Bottom - this.Height;
            }
        

        this = 我们的对象(MainWindow) 当我们从 PrimarySrceenWidth 中减去我们的窗口位置(左)时,我们首先要放置 left 参数。 比,我们通过从屏幕底部的工作区域中减去窗口高度来做同样的事情来获得最低点。 屏幕工作区不包括任务栏!

        享受吧!

        阿夫里

        【讨论】:

          【解决方案7】:

          我在下面的链接中找到了一个非常巧妙的解决方案,可以解决这里讨论的问题, https://codekong.wordpress.com/2010/11/10/custom-window-style-and-accounting-for-the-taskbar/

          这可以直接开箱即用。只是在此处添加此内容以供参考,以便在不久的将来帮助任何人。

          此处的现有解决方案均不适用于以扩展模式连接的多个屏幕。

          在此处粘贴提供的解决方案以防止其从博客中删除,

          需要从 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;
              }
          }
          }
          

          ~奥马尔

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-28
            • 1970-01-01
            • 1970-01-01
            • 2012-02-08
            • 1970-01-01
            • 2010-09-12
            相关资源
            最近更新 更多