WindowBehavior.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Windows;
  4. using System.Windows.Interop;
  5. namespace InABox.WPF;
  6. public class WindowBehavior
  7. {
  8. private static readonly Type OwnerType = typeof (WindowBehavior);
  9. #region HideCloseButton (attached property)
  10. public static readonly DependencyProperty HideCloseButtonProperty =
  11. DependencyProperty.RegisterAttached(
  12. "HideCloseButton",
  13. typeof (bool),
  14. OwnerType,
  15. new FrameworkPropertyMetadata(false, new PropertyChangedCallback(HideCloseButtonChangedCallback)));
  16. [AttachedPropertyBrowsableForType(typeof(Window))]
  17. public static bool GetHideCloseButton(Window obj) {
  18. return (bool)obj.GetValue(HideCloseButtonProperty);
  19. }
  20. [AttachedPropertyBrowsableForType(typeof(Window))]
  21. public static void SetHideCloseButton(Window obj, bool value) {
  22. obj.SetValue(HideCloseButtonProperty, value);
  23. }
  24. private static void HideCloseButtonChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
  25. {
  26. var window = d as Window;
  27. if (window == null) return;
  28. var hideCloseButton = (bool)e.NewValue;
  29. if (hideCloseButton && !GetIsHiddenCloseButton(window)) {
  30. if (!window.IsLoaded) {
  31. window.Loaded += HideWhenLoadedDelegate;
  32. }
  33. else {
  34. HideCloseButton(window);
  35. }
  36. SetIsHiddenCloseButton(window, true);
  37. }
  38. else if (!hideCloseButton && GetIsHiddenCloseButton(window)) {
  39. if (!window.IsLoaded) {
  40. window.Loaded -= ShowWhenLoadedDelegate;
  41. }
  42. else {
  43. ShowCloseButton(window);
  44. }
  45. SetIsHiddenCloseButton(window, false);
  46. }
  47. }
  48. #region Win32 imports
  49. private const int GWL_STYLE = -16;
  50. private const int WS_SYSMENU = 0x80000;
  51. [DllImport("user32.dll", SetLastError = true)]
  52. private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
  53. [DllImport("user32.dll")]
  54. private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
  55. #endregion
  56. private static readonly RoutedEventHandler HideWhenLoadedDelegate = (sender, args) => {
  57. if (sender is Window == false) return;
  58. var w = (Window)sender;
  59. HideCloseButton(w);
  60. w.Loaded -= HideWhenLoadedDelegate;
  61. };
  62. private static readonly RoutedEventHandler ShowWhenLoadedDelegate = (sender, args) => {
  63. if (sender is Window == false) return;
  64. var w = (Window)sender;
  65. ShowCloseButton(w);
  66. w.Loaded -= ShowWhenLoadedDelegate;
  67. };
  68. private static void HideCloseButton(Window w) {
  69. var hwnd = new WindowInteropHelper(w).Handle;
  70. SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
  71. }
  72. private static void ShowCloseButton(Window w) {
  73. var hwnd = new WindowInteropHelper(w).Handle;
  74. SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_SYSMENU);
  75. }
  76. #endregion
  77. #region IsHiddenCloseButton (readonly attached property)
  78. private static readonly DependencyPropertyKey IsHiddenCloseButtonKey =
  79. DependencyProperty.RegisterAttachedReadOnly(
  80. "IsHiddenCloseButton",
  81. typeof (bool),
  82. OwnerType,
  83. new FrameworkPropertyMetadata(false));
  84. public static readonly DependencyProperty IsHiddenCloseButtonProperty =
  85. IsHiddenCloseButtonKey.DependencyProperty;
  86. [AttachedPropertyBrowsableForType(typeof(Window))]
  87. public static bool GetIsHiddenCloseButton(Window obj) {
  88. return (bool)obj.GetValue(IsHiddenCloseButtonProperty);
  89. }
  90. private static void SetIsHiddenCloseButton(Window obj, bool value) {
  91. obj.SetValue(IsHiddenCloseButtonKey, value);
  92. }
  93. #endregion
  94. }