WindowStyle = None和窗口最大化黑客不能使用多个监视器

时间:2014-09-26 07:59:04

标签: c# wpf winapi window window-chrome

当窗口样式为none并且窗口最大化以使窗口覆盖任务栏时,我遇到了问题。我从here得到了一个解决方案(我从源代码中得到的代码不是他发布的代码),除了一部分外,它运行良好。如果您有两台显示器且主显示器小于辅助显示器,那么您最大化辅助显示器上的窗口,会发生这种情况(注意窗口溢出屏幕):

Window is WAY to big.

它的外观如下:(我只是将窗口调整为全屏。)

Resized Manually

虽然在这里工作:

Primary monitor

我正在做的是制作自定义镀铬物。所有代码和示例项目都已上传here。如果有人有任何其他方法可以做到这一点,我真的很感激。提前谢谢!

编辑以下是一些快速参考的代码:

private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
    {
        MINMAXINFO 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;
        System.IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

        if (monitor != System.IntPtr.Zero)
        {
            MONITORINFO 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) - 8;
            mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
            mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top) + 8;
            if (rcWorkArea.bottom == rcMonitorArea.bottom)//full screen (no taskbar)
                mmi.ptMaxSize.y--;//remove 1 px from the bottom for "Auto-hide taskbar" configuration
            mmi.ptMinTrackSize.x = (int)currentlyChangingWindow.MinWidth;
            mmi.ptMinTrackSize.y = (int)currentlyChangingWindow.MinHeight;
        }

        Marshal.StructureToPtr(mmi, lParam, true);
    }

我没有怀疑这段代码所以我真的不知道这里发生了什么。这就是我在这里的原因。

2 个答案:

答案 0 :(得分:3)

我在Windows 8.1上测试了您的代码并且问题被重现了。所以我检查了你的WmGetMinMaxInfo函数并找到了覆盖MINMAXINFO的值,WM_GETMINMAXINFO的lParam是正确的,但是在辅助监视器大于主监视器的情况下,ptMaxSize未正确反映。奇怪的。

我自己使用WindowChrome开发了自定义窗口,并在设置WindowStyle = None时经历了一些奇怪的事情。因此,我个人建议使用GlassFrameThickness = 0CornerRadius = 0代替WindowStyle = NoneAllowsTransparency = True,然后您不再需要此黑客。

所以你的CustomChrome_Initialized函数将是:

void CustomChrome_Initialized(object sender, EventArgs e)
{
  if (CurrentWindow != null)
  {
    Chrome = new WindowChrome()
    {
      GlassFrameThickness = new Thickness(0),
      CornerRadius = new CornerRadius(0),
      ResizeBorderThickness = new Thickness(ResizeGripWidth)
    };

    WindowChrome.SetWindowChrome(CurrentWindow, Chrome);

    //DropShadow
    CurrentWindow.Effect = WindowEffect;
    CurrentWindow.StateChanged += Window_StateChanged;
    Window_StateChanged(CurrentWindow, EventArgs.Empty);
  }
}

,你的Window_StateChanged函数将是:

void Window_StateChanged(object sender, EventArgs e)
{
  var window = ((Window)sender);
  if (window.WindowState == WindowState.Maximized)
  {
    window.BorderThickness = new Thickness(ResizeGripWidth);
  }
  else
  {
    window.BorderThickness = new Thickness(0);
  }
}

我不确定阴影。

答案 1 :(得分:-1)

我找到了自己问题的答案。它真的很复杂,所以如果没有人发表评论我就不会发布答案。