以编程方式最大化无边框窗口

时间:2018-06-09 08:02:03

标签: c# winforms borderless

我目前有办法完全按照要求进行操作,但结果对某些用户来说非常低效。 一些用户报告说它使它好像最小化(没有任何窗口显示但仍然在任务栏中),有些报告例如在超宽21:9它只会从1080p 16:9宽度的左边最大化,但我有一个32:9超级超级,没有任何问题。

我当前的流程:

  • 获取屏幕尺寸,不包括任务栏的加载:

    MaximizedBounds = Screen.FromHandle(mForm.Handle).WorkingArea;(mForm = Application.OpenForms [0],来自任何线程的支持等)

  • 从另一个线程/函数/类运行: Form1.mForm.Invoke(new MethodInvoker(() => Form1.mForm.WindowState = FormWindowState.Maximized));
  • 这应该会产生具有适当分辨率的最大化窗口,但它不会:/

我更喜欢的是:

  • 不需要在线加载屏幕尺寸,因此请使用官方Microsoft代码(DllImport,.NET Framework代码或msapi)中的内容来获取无边框表单的PROPER MaximizedBounds。 (formborderstyle.none)

我设置了MaximizedBounds,因为如果我不这样做,应用程序将全屏显示整个屏幕,而不是"最大化"与传统应用程序一样,但最终会更多地采用全屏视频播放器风格。

在扩展显示模式下使用我的32:9屏幕和我的4k 16:9笔记本电脑的屏幕,我设法重新创建了问题

enter image description here

重新制作步骤:

  • 打开应用程序,将其保留在首次启动的屏幕上
  • 最大化应用程序(将正常工作)
  • 取消最大化并将其移至另一个屏幕
  • 点击最大化,结果应如上所示。

这意味着,加载的最大化边界只获得一次预期的活动边界,但由于我在不同的类和不同的线程上执行Form Style更改,我实际上每次都不能编辑MaximizedBounds属性由于财产不公开,我们想要最大化。

1 个答案:

答案 0 :(得分:0)

感谢HansPassant!

找到所需的确切内容。

问题:

  • 将应用程序移动到其他监视器时,它将使用相同的边界。导致其无法正确最大化
  • 当通过WndProc()更新边界时,它仍然会在Monitor 1上尝试并最大化但超出其实际边界,使其看起来像应用程序被隐藏> :(

更新边界(将其放入Form1中):

protected override void WndProc(ref Message m) {
    if(m.Msg == 0x02E0) {
        Rectangle b = Screen.FromControl(mForm).WorkingArea; //where mForm is Application.OpenForms[0], this is specific to my applications use case.
        b.X = 0; //The bounds will try to base it on Monitor 1 for example, 1920x1080, to another 1920x1080 monitor on right, will set X to 1080, making it show up on the monitor on right, outside its bounds.
        b.Y = 0; //same as b.X
        MaximizedBounds = b; //Apply it to MaximizedBounds
        m.Result = (IntPtr)0; //Tell WndProc it did stuff
    }
    base.WndProc(ref m); //If any other messages were called, do the defaults this method does. Required even if you edited a msg.
}

更新要触发的WndProc消息的DPI意识(将其放入app.manifest,如果它不存在则生成):

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness> //Windows 10
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware> //Old-Compatibility
    </windowsSettings>
</application>

现在它不再显示越界,并且在更换显示器时最终更新了MaximizeBounds!

感谢@HansPassant的提示!