5

我们有一个在多显示器环境中运行的应用程序。用户通常会将应用程序对话框展开以跨越多个显示器。

如果用户锁定工作站,然后解锁它,我们的应用程序会被告知调整大小。

我们的用户发现这种行为令人沮丧,因为他们随后会花费一些时间来恢复以前的布局。

我们还不确定是图形驱动程序请求调整大小还是 Windows。希望通过这个问题,它会变得更清楚哪个组件负责,

(文件)资源管理器和 Firefox 等流行应用程序在此设置中的行为方式相同。仅复制:

  1. 打开资源管理器 ( Win+E)
    • 将资源管理器窗口拖动到水平大于 1 个屏幕
    • 锁定工作站 ( Win+L),
    • 开锁
    • 应用程序现在应该调整为仅在 1 个屏幕上

当工作站锁定然后解锁时,如何防止窗口调整大小?
我们是否需要对(解锁)锁定的检查进行编码?
还有另一种我们不知道的机制吗?

4

3 回答 3

1

在调整窗口大小之前,应用程序将从 Windows 获得WM_WINDOWPOSCHANGING消息。您可以拦截该消息并更改参数,从而强制窗口保持不动。您需要小心,因为当用户尝试移动或调整窗口大小时,您会收到相同的消息。也可能在它被最大化或最小化的时候。

编辑:您可以使用WTSRegisterSessionNotification 函数来获取其他消息。这些消息旨在用于快速用户切换,但锁定屏幕在 Windows 中作为系统会话实现。

于 2010-05-19T20:42:19.620 回答
1

一个类似的问题有一个答案,允许您在会话解锁后恢复 .net 应用程序中的窗口大小

有人在 SuperUser 上提出了基本相同的问题,但从用户的角度来看:当我锁定我的工作站时,如何阻止大窗口调整大小?

于 2010-05-19T20:21:00.517 回答
1

我尝试了Leif 引用的问题中给出的解决方案,发现该SessionSwitchReason.SessionUnlock事件似乎是在计算机被锁定之后而不是之前被触发的。这意味着窗口大小和位置已经被重置,因此调整大小失败。

因此,我不得不在计算机被锁定之前找到另一种存储当前大小和位置的方法。我唯一能做的就是订阅ResizeEndWinforms 应用程序并在那里更新“预锁定”大小和位置。

我还不能让它为 WPF 应用程序工作,因为 WPF 没有等效的ResizeEnd(或者我还没有找到它)和订阅SizeChanged并且LocationChanged不够好,因为这些在计算机时被触发被锁定以及覆盖大小和位置。

最后我不得不挂钩到 Windows ExitSizeMove 事件来保存当前的大小和位置。可以在此处找到有关如何挂钩此事件的详细信息:

private const int WM_EXITSIZEMOVE = 0x232;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
    source.AddHook(new HwndSourceHook(WndProc));
}

private IntPtr WndProc(IntPtr hwnd, int msg,
                       IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_EXITSIZEMOVE)
    {
        // save location and size of window

        handled = true;
    }

    return IntPtr.Zero;
}
于 2010-05-19T21:49:32.503 回答