如何锁定WPF窗口,使其无法移动,调整大小,最小化,最大化或拖动

时间:2010-08-05 23:18:01

标签: wpf

我正在寻找一种锁定WPF窗口的简单方法。我可以在WPF窗口上设置一个简单的窗口样式或属性来锁定窗口吗?

锁定意味着用户无法移动,调整大小,拖动,最小化或最大化窗口。

2 个答案:

答案 0 :(得分:20)

使用以下命令设置窗口:

window.WindowStyle = WindowStyle.None;
window.ResizeMode = ResizeMode.NoResize;

这将阻止用户最小化,最大化或移动窗口。

答案 1 :(得分:4)

要防止窗口被移动或调整大小,请在WM_WINDOWPOSCHANGING挂钩中处理WndProc消息。使用WM_WINDOWPOSCHANGING可以防止窗口被移动,即使是 Win + Shift + Left 。添加此行为的附加属性示例如下所示。

这可以与WindowStyleResizeMode结合使用,使窗口看起来也不可移动。

using static NativeMethods;

public class WindowPos : DependencyObject
{
    public static bool GetIsLocked(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsLockedProperty);
    }

    public static void SetIsLocked(DependencyObject obj, bool value)
    {
        obj.SetValue(IsLockedProperty, value);
    }

    public static readonly DependencyProperty IsLockedProperty =
        DependencyProperty.RegisterAttached("IsLocked", typeof(bool), typeof(WindowPos), 
            new PropertyMetadata(false, IsLocked_Changed));

    private static void IsLocked_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var window = (Window)d;
        var isHooked = d.GetValue(IsHookedProperty) != null;

        if (!isHooked)
        {
            var hook = new WindowLockHook(window);
            d.SetValue(IsHookedProperty, hook);
        }
    }

    private static readonly DependencyProperty IsHookedProperty =
        DependencyProperty.RegisterAttached("IsHooked", typeof(WindowLockHook), typeof(WindowPos), 
            new PropertyMetadata(null));

    private class WindowLockHook
    {
        private readonly Window Window;

        public WindowLockHook(Window window)
        {
            this.Window = window;

            var source = PresentationSource.FromVisual(window) as HwndSource;
            if (source == null)
            {
                // If there is no hWnd, we need to wait until there is
                window.SourceInitialized += Window_SourceInitialized;
            }
            else
            {
                source.AddHook(WndProc);
            }
        }

        private void Window_SourceInitialized(object sender, EventArgs e)
        {
            var source = (HwndSource)PresentationSource.FromVisual(Window);
            source.AddHook(WndProc);
        }

        public IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_WINDOWPOSCHANGING && GetIsLocked(Window))
            {
                var wp = Marshal.PtrToStructure<WINDOWPOS>(lParam);
                wp.flags |= SWP_NOMOVE | SWP_NOSIZE;
                Marshal.StructureToPtr(wp, lParam, false);
            }

            return IntPtr.Zero;
        }
    }
}

internal static class NativeMethods
{
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct WINDOWPOS
    {
        public IntPtr hwnd;
        public IntPtr hwndInsertAfter;
        public int x;
        public int y;
        public int cx;
        public int cy;
        public int flags;
    }

    public const int
        SWP_NOMOVE = 0x0002,
        SWP_NOSIZE = 0x0001;

    public const int
        WM_WINDOWPOSCHANGING = 0x0046;
}

使用示例:

enter image description here