XAMLでウィンドウの最大化・最小化・閉じるボタン群を制御する Attached Property
Attached Property の便利さに目覚めたので、最近はこういうのは全部、Attached Properyです。
<Window x:Class="AcpAcroHook.SettingsDialog" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ... xmlns:cbh="clr-namespace:CaptionBoxesHelper" cbh:CaptionBoxesHelper.ControlBoxes="Control"> ... </Window>
ControlBoxes はフラグになっているので、 Control, Maximize, Minimize をカンマ区切りで指定できます。なので、
cbh:CaptionBoxesHelper.ControlBoxes="Control,Minimize"
みたいな感じで指定できます。
以下、ソース:
using System; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; namespace CaptionBoxesHelper { public static class CaptionBoxesHelper { public static readonly DependencyProperty ControlBoxesProperty = DependencyProperty.RegisterAttached( "ControlBoxes", typeof(ControlBoxes), typeof(CaptionBoxesHelper), new PropertyMetadata(ControlBoxes.None, controlBoxesChanged)); public static void SetControlBoxes(DependencyObject dp, ControlBoxes value) { dp.SetValue(ControlBoxesProperty, value); } public static ControlBoxes GetControlBoxes(DependencyObject dp) { return (ControlBoxes)dp.GetValue(ControlBoxesProperty); } static void controlBoxesChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { var window = o as Window; if (window == null) return; var cb = (ControlBoxes)e.NewValue; if (!window.IsLoaded) window.Loaded += (sender, ea) => updateStyleOfWindow(cb, window); else updateStyleOfWindow(cb, window); } static void updateStyleOfWindow(ControlBoxes cb, Window window) { var hwndSrc = PresentationSource.FromVisual(window) as HwndSource; var hwnd = hwndSrc.Handle; var flags = GetWindowLong(hwnd, GWL_STYLE); var newFlags = updateFlags(cb, flags); if (flags != newFlags) SetWindowLong(hwnd, GWL_STYLE, newFlags); } static uint updateFlags(ControlBoxes cb, uint flags) { if (cb.HasFlag(ControlBoxes.Minimize)) flags |= WS_MINIMIZEBOX; else flags &= ~WS_MINIMIZEBOX; if (cb.HasFlag(ControlBoxes.Maximize)) flags |= WS_MAXIMIZEBOX; else flags &= ~WS_MAXIMIZEBOX; if (cb.HasFlag(ControlBoxes.Control)) flags |= WS_SYSMENU; else flags &= ~WS_SYSMENU; return flags; } const uint WS_SYSMENU = 0x00080000; const uint WS_MINIMIZEBOX = 0x00020000; const uint WS_MAXIMIZEBOX = 0x00010000; 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, uint dwLong); } [Flags] public enum ControlBoxes { None = 0, Maximize = 1, Minimize = 2, Control = 4 } }