在Windows XP及更高版本中,给定一个窗口句柄(HWND),如何判断窗口的位置和大小是否不可恢复地离开窗口? 例如,如果标题栏可用于光标,则窗口可以被拖回到屏幕上。 我需要发现窗口是否实际上可见或至less可以提供给用户。 我想我也需要知道如何检测和响应分辨率的变化,以及如何处理多个显示器。 这似乎是一个相当大的交易。 我正在使用C ++和普通的SDK,所以请限制你的答案,而不是调用C#或类似的平台。
Windows使得在主监视器上确定用户工作区域的大小(即,屏幕上未被任务栏遮挡的区域)的相对简单。 调用SystemParametersInfo
函数并为第一个参数( uiAction
)指定SPI_GETWORKAREA
标志。 pvParam
参数应指向RECT
结构 ,该结构将以虚拟屏幕坐标接收工作区域的坐标。
一旦获得了描述工作区域的坐标,将它们与应用程序窗口的当前位置进行比较,以确定它是否位于这些边界内就是一件简单的事情。
支持多台显示器的愿望使事情稍微复杂一些。 SystemParametersInfo
文档建议您需要调用GetMonitorInfo
函数来获取除主GetMonitorInfo
以外的监视器的工作区域。 它填充名为MONITORINFOEX
的结构,其中包含成员rcWork
,该成员定义了该监视器的工作区域,再次以虚拟屏幕坐标表示为RECT
结构。
要做到这一点,您需要枚举用户连接到系统的所有监视器,并使用GetMonitorInfo
检索每个GetMonitorInfo
的工作区域。
在互联网上有几个这样的例子:
最后,你提到想要检测分辨率的变化。 这比你想象的要简单得多。 如您所知,如果您已经完成了Windows编程,操作系统与您的应用程序进行通信的主要方式是将消息发送到WindowProc
函数 。
在这种情况下,您需要监视WM_DISPLAYCHANGE
消息 ,该消息在显示分辨率发生变化时发送到所有窗口。 wParam
包含以像素为单位的新图像深度; lParam
的低位字指定水平分辨率, lParam
的高位字指定屏幕的垂直分辨率。
可见性检查非常简单。
RECT rtDesktop, rtView; GetWindowRect( GetDesktopWindow(), &rtDesktop ); GetWindowRect( m_hWnd, &rtView ); HRGN rgn = CreateRectRgn( rtDesktop.left, rtDesktop.top, rtDesktop.right, rtDesktop.bottom ); BOOL viewIsVisible = RectInRegion( rgn, &rtView ); DeleteObject(rgn);
您不必使用RectInRegion,我用它来缩短代码。
如果处理WM_SETTINGCHANGE消息,显示,分辨率更改监视也很容易。
http://msdn.microsoft.com/en-us/library/ms725497(v=vs.85).aspx
UPDATE
正如@Cody Gray指出的,我认为WM_DISPLAYCHANGE比WM_SETTINGCHANGE更合适。 但MFC 9.0库使用WM_SETTINGCHANGE。