有没有办法更新
Screen
对象?备注:屏幕对象如(Screen s in Screen.AllScreens)
如果缩放或其他属性改变,对象不会改变。非常详细的分析可以在这里找到:Windows Screens.AllScreens在切换主显示后不更新
在评论中,看起来发送广播
PostMessage((IntPtr)HWND_BROADCAST, WM_DISPLAYCHANGE, UIntPtr.Zero, IntPtr.Zero)
会导致屏幕对象更新。
我已经尝试过,但我的屏幕对象没有更新。有没有办法强制更新?
问题是缓存静态字段在所有情况下都不能正确“清空”。
public unsafe static Screen[] AllScreens
{
get
{
if (s_screens is null)
{
if (s_multiMonitorSupport)
实际上发送请求应该清空缓存
private static void OnDisplaySettingsChanging(object? sender, EventArgs e)
{
// Now that we've responded to this event, we don't need it again until
// someone re-queries. We will re-add the event at that time.
SystemEvents.DisplaySettingsChanging -= new EventHandler(OnDisplaySettingsChanging);
// Display settings changed, so the set of screens we have is invalid.
s_screens = null;
}
感谢几个人的帮助(评论),我有一个(当前)有效的解决方案。
对我来说最有效的是调用 screen 的 private(!) 方法,该方法在事件发生时调用(但不会在所有真正需要更新的事件中调用)。不用说这是一个黑客。
MethodInfo? method = typeof(Screen).GetMethod("OnDisplaySettingsChanging", BindingFlags.Static | BindingFlags.NonPublic);
Debug.Assert(method != null, "Method OnDisplaySettingsChanging not found");
method.Invoke(obj: null, parameters: new object[] { "dummy object", EventArgs.Empty });
发送
WM_DISPLAYCHANGE
的广播也可以,但对我来说不太可靠。它是异步的,我必须等到更改首先发生。此外,我还强制其他应用程序中的许多 Screen 对象进行更新(副作用???)。
SM的完整示例在这里:https://pastebin.com/raw/4DBXthUS
在另一个问题中Windows Screens.AllScreens在切换主显示器后不会更新它也有这个评论,所以如果继续
PostMessage(HWND_BROADCAST, WM_DISPLAYCHANGE, IntPtr.Zero, IntPtr.Zero);
使用可能会更好
SendMessageTimeout()
它是发送消息,这使得使用 SendMessageTimeout() 而不是 PostMessage() 合适。 – 汉斯·帕桑特
再次感谢您的帮助。