开发者

How do I lock a WPF window so it can not be moved, resized,minimized, maximized or dragged

I am looking for a simple way to lock a WPF 开发者_开发技巧window. Is there a simple window style or property I can set on a WPF window to locked the window?

By lock I mean the user can not move, resize, drag, minimize or maximize the window.


Setup the window with:

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

This will prevent the user from minimizing, maximizing, or moving the Window.


To prevent a window from being moved or resized, handle the WM_WINDOWPOSCHANGING message in a WndProc hook. Using WM_WINDOWPOSCHANGING prevents the window from being moved even by Win + Shift + Left. An example of an attached property which adds this behavior is shown below.

This can be combined with WindowStyle and ResizeMode to make the window look immovable too.

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

Example use:

How do I lock a WPF window so it can not be moved, resized,minimized, maximized or dragged

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜