当工作站被锁定然后解锁时,如何防止窗口大小调整?

时间:2009-12-10 15:14:20

标签: windows user-interface multiple-monitors

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

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

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

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

像(File)Explorer和Firefox这样的流行应用程序在此设置中的行为方式相同。复制只是:

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

  2. 当工作站被锁定然后解锁时,如何防止窗口调整大小?
    我们是否需要编码(un)锁定检查?
    还有其他我们不了解的机制吗?

3 个答案:

答案 0 :(得分:1)

类似的问题有一个答案,允许您restore window size in a .net application after the session is unlocked

有人在SuperUser上提出了同样的问题,但是从用户的角度来看:How can I stop big windows from resizing when I lock my workstation?

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

我还没能让它适用于WPF应用程序,因为WPF没有相当于ResizeEnd(或者我还没有找到它)并订阅SizeChanged并且LocationChanged不够好,因为当计算机被锁定并覆盖大小和位置时会触发这些内容。

最后我不得不挂钩Windows ExitSizeMove事件以保存当前的大小和位置。有关如何挂钩此活动的详细信息,请参见here

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;
}