首先,对这么长的帖子表示抱歉。
关于如何限制 WM_DISPLAYCHANGE 消息的发布范围有什么建议吗?
设想:
Screen.AllScreens
返回在客户端上检测到的所有监视器的坐标和分辨率的数组。如果在工作站锁定时启动应用程序(在夜间应用程序重新启动期间),Screen.AllScreens
仅返回一个详细说明单个屏幕的元素,并将所有多个显示器的尺寸作为一个元素。
随后,在这种情况下,当用户解锁工作站并开始使用应用程序时,正在使用的 Infragistics 控件 (UltraWinDock) 不允许将浮动窗口拖动到主屏幕之外,因为Screen.AllScreens
属性不返回系统的真实监视器配置。基础设施控制实际上着眼于Screen.PrimaryScreen.Bounds
,但是Screen.PrimaryScreen
属性依次调用缓存的Screen.AllScreens
数组,它返回一个巨大的主屏幕!
当应用程序正常启动时(工作站解锁),控制功能正常。
我能看到的唯一方法Screen.AllScreens
被重置,并且可以通过刷新SystemEvents.DisplayChanging
正在引发的事件,
此时内部字段设置为空。 (Screen.AllScreens
挂钩到这个事件。)Screen.AllScreens
然后将在下次调用时重新填充。
据我所知,SystemEvents.DisplayChanging
事件可以通过WM_DISPLAYCHANGE
WMI 消息。
我管理解决方法的方法是调用:
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int nIndex);
参数为SM_CMONITORS http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385%28v=vs.85%29.aspx它代表系统上的显示器数量。无论工作站是否锁定,这似乎总是返回当前显示器的实际数量。
然后我评估长度是否Screen.AllScreens
数组小于结果GetSystemMetrics(SM_CMONITORS)
如果是的话,我就加入SystemEvents.SessionSwitch
静态事件并检查SessionSwitchEventArgs.Reason
财产,价值为SessionUnlock
。
当工作站解锁时,会收到此事件并且满足条件,因此我使用 P/Invoke 方法发布一条消息
[DllImport("user32.dll")]
public static extern bool PostMessage(IntPtr hWnd, uint wMsg, UIntPtr wParam, IntPtr lParam);
具有以下参数:
PostMessage(HWND_BROADCAST, WM_DISPLAYCHANGE,UIntPtr.Zero,IntPtr.Zero)
这非常有效,并且达到了预期的结果! Screen.AllScreens
已重置并且 Infragistics 控制功能正常。
在我看来,它就像一个不起眼的错误Screen.AllScreens
当应用程序在锁定的工作站上启动然后解锁时,不会重新评估自身。
我承认这是一个罕见的问题,但仍然是一个问题。
For the WM_DISPLAYCHANGE http://msdn.microsoft.com/en-us/library/dd145210%28v=vs.85%29.aspxmessage、lParam 和 wParam 描述如下:
wParam