[WPF疑难]避免窗口最大化时遮盖任务栏

WPF窗口最大化时有个很不好的现象是:如果窗口的WindowStyle被直接或间接地设置为None后(比如很多情况下你会覆盖默认的窗体样式,即不采用Windows默认的边框和最大化最等按钮,来打造个性的窗体),那么最大化窗口后,窗口将铺满整个屏幕而将任务栏盖住。这往往不符合实际要求。

这里有个不错的解决方案解决了该问题,其通过对 WM_GETMINMAXINFO(MSDN: The WM_GETMINMAXINFO message is sent to a window when the size or position of the window is about to change. An application can use this message to override the window's default maximized size and position, or its default minimum or maximum tracking size.) 消息挂接一个钩子来处理。其消息代码是:0x0024(更多的消息代码可以参考本文附录)

没什么好说的,直接上代码(对你要处理的窗口调用FullScreenManager.RepairWpfWindowFullScreenBehavior方法即可):

public static class FullScreenManager
  {
    public static void RepairWpfWindowFullScreenBehavior(Window wpfWindow)
    {
      if(wpfWindow == null)
      {
        return;
      }
      if(wpfWindow.WindowState == WindowState.Maximized)
      {
        wpfWindow.WindowState = WindowState.Normal;
        wpfWindow.Loaded += delegate { wpfWindow.WindowState = WindowState.Maximized; };
      }
      wpfWindow.SourceInitialized += delegate
      {
        IntPtr handle = (new WindowInteropHelper(wpfWindow)).Handle;
        HwndSource source = HwndSource.FromHwnd(handle);
        if(source != null)
        {
          source.AddHook(WindowProc);
        }
      };
    }
    private static IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, 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)
    {
      var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
      // Adjust the maximized size and position to fit the work area of the correct monitor
      int MONITOR_DEFAULTTONEAREST = 0x00000002;
      IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
      if (monitor != IntPtr.Zero)
      {
        var monitorInfo = new MONITORINFO();
        GetMonitorInfo(monitor, 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);
      }
      Marshal.StructureToPtr(mmi, lParam, true);
    }

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索static
, lparam
, 窗口
, monitor
, IntPtr
wpf消息框
wpf 被遮盖、wpf 窗口最大化、wpf 最大化、wpf无边框窗体 最大化、wpf 禁止窗口最大化,以便于您获取更多的相关知识。

时间: 2024-09-17 03:59:44

[WPF疑难]避免窗口最大化时遮盖任务栏的相关文章

[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口

现象: 大家可以试试下面这个很有趣但会带来Defect的现象:当我们将子窗口按照ShowDialog()的方式显示出来的时候,很明显该窗口是模式化的(即主窗口等待该窗口的返回,主窗口将不相应用户输入),但如果此时将子窗口的Visibility设置成Visibility.Hidden来隐藏窗口,然后再将Visibility设置成Visibility.Visible来再次显示子窗口,此后子窗口便是非模式的了(即主窗口和子窗口一样相应用户输入) 案例: 当用户不操作软件达到一定的时间间隔后,软件会隐藏

Win7双显示器窗口最大化时不能全部显示的完美处理措施

  解决方法 1.右键点击桌面,在菜单中点击"屏幕分辨率"; 2.在多显示器那边,原先是"扩展这些显示",把它改成"只在1上显示桌面".然后点击"应用"或"确定". 3.恢复正常之后,再改回"扩展这些显示",确定即可.

[WPF疑难] 继承自定义窗口

项目中有不少的弹出窗口,按照美工的设计其外边框(包括最大化,最小化,关闭等按钮)自然不同于Window自身的,但每个弹出框的外边框都是一样的.对其中一个窗口而言,我们要取消其Window边框,并在右上角摆上三个按钮并编写其点击事件等,但若每个弹出窗口都按照这种方式做一遍就太土了.我们想避免重复劳动,最自然的联想到了"继承".但WPF给我们找了若干麻烦,被挫败了几次.今天经过2小时的奋战,终于搞定了,分享一下. 挫败1,继承时编译错误 假设我们写好的父窗口类为BaseWindow,对应B

[WPF疑难]如何禁用窗口上的关闭按钮

哈哈,主要是调用RemoveMenu这个API,所以没什么好说的,直接"干货"吧: namespace VersatileMessageBoxLib { using System; using System.Windows.Interop; using System.Runtime.InteropServices; public class CloseButton { [DllImport("user32", CharSet = CharSet.Ansi, SetL

java swing启动时窗口最大化

Java swing启动时窗口最大化 Java代码   setExtendedState( this.getExtendedState()|JFrame.MAXIMIZED_BOTH );      

.net c#开发,弹出的窗口最大化按钮是灰的,不能用,求大神指点

问题描述 .net c#开发,弹出的窗口最大化按钮是灰的,不能用,求大神指点 document.oncontextmenu = new Function("event.returnValue=false;");//禁止右键 document.onselectstart = new Function("event.returnValue=false;");//禁止选择/复制 <asp:Label ID="label1" runat="

winform中窗体最大化时 如何使窗体中内容也相应的全屏

问题描述 请教大家,winform中窗体最大化时如何使窗体中内容也相应的全屏? 解决方案 解决方案二:设置控件的Anchor属性或Dock属性解决方案三:这个很麻烦,不好处理,我也曾经尝试着根据窗体大小的比例,来改变组件的位置,失败了,老师也没有办法,解决方案四:引用1楼ojlovecd的回复: 设置控件的Anchor属性或Dock属性 正解解决方案五:引用3楼freeboy827的回复: 引用1楼ojlovecd的回复:设置控件的Anchor属性或Dock属性正解 但是界面不一定会好看了解决方

asp.net-wpf 怎么让嵌套子窗口 最大化

问题描述 wpf 怎么让嵌套子窗口 最大化 主面板有四个子窗口,点击某一个里面的按钮实现最大化 解决方案 windowsstate=maxmized 解决方案二: 子页面是Page页面,木有windowsstate

系统之家Win7旗舰版窗口最大化的巧妙限制

Win7系统中,每当用户拖动窗口时,被拖动的窗口碰到了屏幕边缘,就会自动跳到最大的现象.对于很多刚从XP系统穿越过来的用户而言,感觉整个人都不好了该怎么办呢?其实在系统设定中取消窗口最大化功能就能简单解决这个烦恼了,而且还能在在一定程度上释放系统资源,达到win7系统性能优化.因此,小编今天就以系统之家Win7旗舰版系统为例,给大家分享Win7系统中取消窗口最大化功能提升系统性能的优化方案.具体步骤如下: 1.用鼠标点击"开始"--"控制面板",进入到win7系统的