Window のシステムメニューを変更するビヘイビア(C#版)

7/24 のエントリ Q048. Window の最小化・最大化ボタンを無効にするには? で公開したビヘイビアですが、諸般の事情により VB から C# で書き直すことになりました。そこで一応 C# 版も上げときます。なんかの参考になれば幸いです。

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace tenz.Tools.Presentation {

    [Flags]
    public enum WindowStyleFlag : uint
    {
        WS_NONE = 0x00000000,
        WS_SYSMENU = 0x00080000,    
        WS_MINIMIZEBOX = 0x00020000,
        WS_MAXIMIZEBOX = 0x00010000,
    }

    public class WindowMenuBehaviors {

        const int GWL_STYLE = -16;

        [DllImport ("user32")]
        private static extern uint GetWindowLong (IntPtr hWnd,int index);
        [DllImport ("user32")]
        private static extern uint SetWindowLong (IntPtr hWnd,int index, WindowStyleFlag dwLong);

        public static readonly DependencyProperty MinimizeBoxProperty =
            DependencyProperty.RegisterAttached("MinimizeBox", typeof(bool), typeof(WindowMenuBehaviors), new UIPropertyMetadata(true, SourceInitialized));
        public static readonly DependencyProperty MaximizeBoxProperty =
            DependencyProperty.RegisterAttached("MaximizeBox", typeof(bool), typeof(WindowMenuBehaviors), new UIPropertyMetadata(true, SourceInitialized));
        public static readonly DependencyProperty ControlBoxProperty =
            DependencyProperty.RegisterAttached("ControlBox", typeof(bool),  typeof(WindowMenuBehaviors), new UIPropertyMetadata(true, SourceInitialized));

        #region 最小化ボタン

            [AttachedPropertyBrowsableForType(typeof(WindowMenuBehaviors))]
            public static bool GetMinimizeBox(DependencyObject obj) {
                return (bool)obj.GetValue(MinimizeBoxProperty);
            }

            [AttachedPropertyBrowsableForType(typeof(WindowMenuBehaviors))]
            public static void SetMinimizeBox(DependencyObject obj, bool value) {
                obj.SetValue(MinimizeBoxProperty, value);
            }

        #endregion

        #region 最大化ボタン

            [AttachedPropertyBrowsableForType(typeof(WindowMenuBehaviors))]
            public static bool GetMaximizeBox(DependencyObject obj) {
                return (bool)obj.GetValue(MaximizeBoxProperty);
            }

            [AttachedPropertyBrowsableForType(typeof(WindowMenuBehaviors))]
            public static void SetMaximizeBox(DependencyObject obj, bool value) {
                obj.SetValue(MaximizeBoxProperty, value);
            }

        #endregion

        #region システムメニュー

            [AttachedPropertyBrowsableForType(typeof(WindowMenuBehaviors))]
            public static bool GetControlBox(DependencyObject obj) {
                return (bool)obj.GetValue(ControlBoxProperty);
            }

            [AttachedPropertyBrowsableForType(typeof(WindowMenuBehaviors))]
            public static void SetControlBox(DependencyObject obj, bool value) {
                obj.SetValue(ControlBoxProperty, value);
            }

        #endregion

        private static void SourceInitialized(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
            var window = sender as Window;
            if (window == null) return;

            window.SourceInitialized +=
                (obj, args) => {
                    var w = obj as Window;
                    if (w == null) return;

                    var handle = (new WindowInteropHelper(w)).Handle;
                    var original = (WindowStyleFlag)GetWindowLong(handle, GWL_STYLE);
                    var current = GetWindowStyle(w, original, e);
                    if (original != current) {
                        SetWindowLong(handle, GWL_STYLE, current);
                    }
                };
        }

        private static WindowStyleFlag GetWindowStyle(DependencyObject obj, WindowStyleFlag windowStyle, DependencyPropertyChangedEventArgs e) {

            WindowStyleFlag style = WindowStyleFlag.WS_NONE;
            bool value = false;

            if (e.Property.Name == "MinimizeBox") {
                style = WindowStyleFlag.WS_MINIMIZEBOX;
                value = (bool)obj.GetValue(MinimizeBoxProperty);

            } else if (e.Property.Name == "MaximizeBox") {
                style = WindowStyleFlag.WS_MAXIMIZEBOX;
                value = (bool)obj.GetValue(MaximizeBoxProperty);

            } else if (e.Property.Name == "ControlBox") {
                style = WindowStyleFlag.WS_SYSMENU;
                value = (bool)obj.GetValue(ControlBoxProperty);

            }

            if (value)
                windowStyle |= style;
            else
                windowStyle &= ~style;

            return windowStyle;
        }
    }
}