【问题标题】:How to determine whether a Windows application is offscreen?如何确定 Windows 应用程序是否在屏幕外?
【发布时间】:2010-09-17 19:33:33
【问题描述】:

我正在尝试为安装了LogMeIn 的用户调试一个奇怪的问题。几天后,我的应用打开的一些对话框可能会在屏幕外结束。如果我能可靠地检测到这一点,我可以以编程方式将对话框移回它们再次可见的位置。

注意:这必须适用于多台显示器并使用 win32 API。但是,如果您知道如何从 .NET 执行此操作,我可能可以从那里推断...

更新: 好奇的是,上面提到的错误与 wxWidgets 有关。如果您运行 wxWidgets 应用程序,然后走开,让屏幕保护程序消失,然后使用 LogMeIn 远程登录,然后尝试从您的应用程序打开一个对话框,如果您使用 wxDisplay::GetFromPoint(pos) 或 wxWindowBase,您将遇到问题::Center() 定位对话框。

【问题讨论】:

  • 仅供参考:右键单击任务栏中的屏幕外窗口,选择移动,然后按箭头键(它应该跳转到鼠标)。然后使用鼠标或按键完成移动。
  • 如果您认为这是 wxWidgets 中的错误,您报告了吗?

标签: c# .net c++ windows winapi


【解决方案1】:

只需使用带有 MONITOR_DEFAULTTONULL 标志的 MonitorFromWindow。如果返回值为 null,则您的窗口不可见。您随后可以传递 MONITOR_DEFAULTTONEAREST 以便能够在最近的监视器上重新定位您的窗口。

【讨论】:

  • 我最终使用了 MonitorFromPoint,它的工作原理类似于 MonitorFromWindow。
【解决方案2】:

1997 年 6 月 Microsoft Systems Journal 中有关多显示器支持的所有基础知识:

在多显示器设置上定位对象:

【讨论】:

    【解决方案3】:

    在 .NET 中,您使用 Screen.PrimaryScreen.WorkingArea 结构来获取主屏幕的边界(我认为其他显示器的 Screen.Screens[x].WorkingArea),然后使用 Left 和 Top 属性找出窗口所在的窗口(如果它不在屏幕上,Top 和 Left 将大于 [Screen].Width 和 .Height。

    【讨论】:

      【解决方案4】:

      在 .NET 中,我将在 Screen.AllScreen 中的每个屏幕上进行迭代,然后如果您想确保所有窗口都在边界 (*) 内,则调用 screen.Bounds.Contains() 并传递表单的矩形,或者如果您只想确保表单的至少一部分可见,请调用 screen.Bounds.IntersectsWith()。

      (*) 不完全在一个屏幕范围内并不意味着它不在总屏幕范围内。您还可以在每个屏幕边界上调用 Rectangle.Union 来创建一个矩形来测试表单的矩形,但是您必须注意屏幕边界的大小是否不同,因为 englobing 矩形也不完全可见。

      那是更长的答案。较短的是:我知道没有简单的方法。

      【讨论】:

        【解决方案5】:

        无论您做什么,请考虑到多个显示器可能在任何方向上距离 (0,0) 有数千个像素的坐标。我讨厌一个应用程序强制自己回到另一个屏幕,经常搞乱我当时可能正在玩的任何全屏游戏。

        【讨论】:

          【解决方案6】:

          另见How can I get the active screen dimensions?

          这是我在表单构造函数中使用的代码,它可以在您卸下笔记本电脑后快速将表单移动到可见屏幕,或者您所做的任何事情都可以让某些屏幕空间消失。供自己食用。

          if (!Screen.FromControl(this).Bounds.Contains(this.Location))
                      {
                          this.DesktopLocation = new Point(100,100);
                      }
          

          【讨论】:

            【解决方案7】:

            看起来GetMonitorInfo() 是 Danny 建议的 Win32 等价物。我不确定您将如何为系统上的所有监视器获取 HMONITOR,但看起来文档中链接的示例有一些方法。

            【讨论】:

              【解决方案8】:

              这是很久以前的事了,但是 Marin Plante 的回答让我得到了我需要的东西,所以我写了一个简单的扩展方法:

              public static class WindowLocation
              {
                  public static Boolean VisibleOnScreen(this Form form)
                  {
                      foreach (Screen screen in Screen.AllScreens)
                      {
                          if (screen.Bounds.Contains(form.Bounds)) return true;
                      }
              
                      return false;
                  }
              }
              

              可以帮助别人!

              【讨论】:

                【解决方案9】:

                嗯。这可能没有帮助,但是当我做 VB 时,你可以做 screen.width 和 screen.height,然后是 window.x 和 window.y...

                当然,我不知道多显示器如何工作。

                【讨论】:

                  猜你喜欢
                  • 2011-06-08
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-09-11
                  • 2021-10-28
                  • 1970-01-01
                  相关资源
                  最近更新 更多