简体   繁体   English

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

[英]Programmatically Maximize Borderless Window

I currently have a way to do exactly what im asking, but the results are very in-efficient for some users. 我目前有一种方法可以完全按照即时消息的要求进行操作,但结果对某些用户而言效率很低。 Some users reported it making it as if it minimized (no window showing ever but still in taskbar), some reported for example in an ultrawide 21:9 it would only maximize from the left of a 1080p 16:9 width, yet I have a 32:9 super-ultrawise and have had no issues. 一些用户报告说它使它看起来像是最小化的(没有窗口显示,但仍在任务栏中),例如,一些用户报告说它仅在1080p 16:9宽度的左侧才最大化,但它只有从左侧的1080p最大化。 32:9超超,没有问题。

My current flow: 我目前的流程:

  • Get the Screen Dimensions excluding the taskbar on-load: 获取屏幕尺寸,不包括加载的任务栏:

    MaximizedBounds = Screen.FromHandle(mForm.Handle).WorkingArea; (mForm = Application.OpenForms[0], for support from any thread and such) (mForm = Application.OpenForms [0],以获得来自任何线程等的支持)

  • From another thread/function/class run: Form1.mForm.Invoke(new MethodInvoker(() => Form1.mForm.WindowState = FormWindowState.Maximized)); 从另一个线程/函数/类运行: Form1.mForm.Invoke(new MethodInvoker(() => Form1.mForm.WindowState = FormWindowState.Maximized));
  • This should result in a maximized window with the proper resolution, but it doesn't :/ 这应该导致具有适当分辨率的最大化窗口,但不是:/

What I would prefer: 我更喜欢:

  • NOT require to get the screen dimensions on-load, so use something from official Microsoft Code, either DllImport's, .NET Framework Code, or msapi to get the PROPER MaximizedBounds for Borderless Forms. 不需要获取屏幕尺寸,因此请使用正式的Microsoft Code(DllImport的,.NET Framework Code或msapi)中的某些内容来获取无边界表单的PROPER MaximizedBounds。 (formborderstyle.none) (formborderstyle.none)

I set MaximizedBounds because if I don't, the application will fullscreen the entire screen, not "maximize" like traditional apps but would end up doing more of a Video Player style fullscreen. 我设置MaximizedBounds的原因是,如果不这样做,该应用程序将全屏显示整个屏幕,而不是像传统应用程序那样“最大化”,但是最终会做更多的Video Player风格的全屏显示。

Using my 32:9 screen and my 4k 16:9 laptop's screen on Extend Display mode, I managed to re-create the issue 在扩展显示模式下,使用32:9屏幕和4k 16:9笔记本电脑的屏幕,我设法重新创建了问题

在此处输入图片说明

Re-production Steps: 再生产步骤:

  • Open the application, leave it on the screen it first started in 打开应用程序,将其保留在首次启动的屏幕上
  • Maximize the application (will work fine) 最大化应用程序(可以正常工作)
  • Unmaximize and move it to the other screen 取消最大化并将其移至其他屏幕
  • Click maximize, your result should be like above. 单击最大化,您的结果应如上。

This means, the on-load Maximize Bounds only gets the active bounds once which is expected, but due to me executing the Form Style change on a different class and different thread, I cant actually edit the MaximizedBounds property on it everytime I want to maximize, due to property not being public. 这意味着,在加载时最大化边界只会获得预期的活动边界,但是由于我在不同的类和线程上执行了表单样式更改,因此每次我想最大化时,我都无法对其实际编辑MaximizedBounds属性,因为财产不公开。

Thanks to HansPassant! 感谢HansPassant!

Found out exactly whats needed. 找出确切需要什么。

Problem: 问题:

  • When moving application to other monitor, it would use the same bounds. 将应用程序移动到其他监视器时,它将使用相同的范围。 Causing it to not properly Maximize 导致无法正确最大化
  • When updating bounds via WndProc(), it would still try and maximize on Monitor 1 but outside its actual bounds, making it look like the application was hidden >:( 通过WndProc()更新边界时,它仍会尝试在Monitor 1上最大化,但超出了其实际边界,从而使该应用程序看起来像是隐藏的> :(

Updating the Bounds (put this in Form1): 更新边界(在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.
}

Updating DPI Awareness for the WndProc message to fire (put this in app.manifest, make it if it doesnt exist): 更新DPI意识以触发WndProc消息(将其放入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>

Now it no longer shows up out of bounds, and is finally updating the MaximizeBounds when changing monitors! 现在它不再显示超出范围,并最终在更改监视器时更新MaximizeBounds!

Thanks @HansPassant for the tips! 感谢@HansPassant提供的提示!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM