如何在WPF窗口中隐藏关闭按钮? 您所在的位置:网站首页 nova4隐藏退出 如何在WPF窗口中隐藏关闭按钮?

如何在WPF窗口中隐藏关闭按钮?

2023-03-22 02:04| 来源: 网络整理| 查看: 265

下面是关于禁用关闭和最大化/最小化按钮的内容,它实际上并没有删除按钮(但确实删除了菜单项!)。标题栏上的按钮以禁用/灰色状态绘制。(我还没有准备好自己接管所有的功能^^)

这与Virgoss解决方案略有不同,因为它删除了菜单项(如果需要,还会删除尾随分隔符),而不仅仅是禁用它们。它与Joe Whites的解决方案不同,因为它不会禁用整个系统菜单,因此,在我的情况下,我可以保留最小化按钮和图标。

下面的代码还支持禁用最大化/最小化按钮,因为与关闭按钮不同,从菜单中删除条目不会导致系统将按钮呈现为“禁用”,即使删除菜单项确实会禁用按钮的功能。

这对我很管用。YMMV.

using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using Window = System.Windows.Window; using WindowInteropHelper = System.Windows.Interop.WindowInteropHelper; using Win32Exception = System.ComponentModel.Win32Exception; namespace Channelmatter.Guppy { public class WindowUtil { const int MF_BYCOMMAND = 0x0000; const int MF_BYPOSITION = 0x0400; const uint MFT_SEPARATOR = 0x0800; const uint MIIM_FTYPE = 0x0100; [DllImport("user32", SetLastError=true)] private static extern uint RemoveMenu(IntPtr hMenu, uint nPosition, uint wFlags); [DllImport("user32", SetLastError=true)] private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [DllImport("user32", SetLastError=true)] private static extern int GetMenuItemCount(IntPtr hWnd); [StructLayout(LayoutKind.Sequential)] public struct MenuItemInfo { public uint cbSize; public uint fMask; public uint fType; public uint fState; public uint wID; public IntPtr hSubMenu; public IntPtr hbmpChecked; public IntPtr hbmpUnchecked; public IntPtr dwItemData; // ULONG_PTR public IntPtr dwTypeData; public uint cch; public IntPtr hbmpItem; }; [DllImport("user32", SetLastError=true)] private static extern int GetMenuItemInfo( IntPtr hMenu, uint uItem, bool fByPosition, ref MenuItemInfo itemInfo); public enum MenuCommand : uint { SC_CLOSE = 0xF060, SC_MAXIMIZE = 0xF030, } public static void WithSystemMenu (Window win, Action action) { var interop = new WindowInteropHelper(win); IntPtr hMenu = GetSystemMenu(interop.Handle, false); if (hMenu == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to get system menu"); } else { action(hMenu); } } // Removes the menu item for the specific command. // This will disable and gray the Close button and disable the // functionality behind the Maximize/Minimuze buttons, but it won't // gray out the Maximize/Minimize buttons. It will also not stop // the default Alt+F4 behavior. public static void RemoveMenuItem (Window win, MenuCommand command) { WithSystemMenu(win, (hMenu) => { if (RemoveMenu(hMenu, (uint)command, MF_BYCOMMAND) == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to remove menu item"); } }); } public static bool RemoveTrailingSeparator (Window win) { bool result = false; // Func not in .NET3 :-/ WithSystemMenu(win, (hMenu) => { result = RemoveTrailingSeparator(hMenu); }); return result; } // Removes the final trailing separator of a menu if it exists. // Returns true if a separator is removed. public static bool RemoveTrailingSeparator (IntPtr hMenu) { int menuItemCount = GetMenuItemCount(hMenu); if (menuItemCount < 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to get menu item count"); } if (menuItemCount == 0) { return false; } else { uint index = (uint)(menuItemCount - 1); MenuItemInfo itemInfo = new MenuItemInfo { cbSize = (uint)Marshal.SizeOf(typeof(MenuItemInfo)), fMask = MIIM_FTYPE, }; if (GetMenuItemInfo(hMenu, index, true, ref itemInfo) == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to get menu item info"); } if (itemInfo.fType == MFT_SEPARATOR) { if (RemoveMenu(hMenu, index, MF_BYPOSITION) == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to remove menu item"); } return true; } else { return false; } } } private const int GWL_STYLE = -16; [Flags] public enum WindowStyle : int { WS_MINIMIZEBOX = 0x00020000, WS_MAXIMIZEBOX = 0x00010000, } // Don't use this version for dealing with pointers [DllImport("user32", SetLastError=true)] private static extern int SetWindowLong (IntPtr hWnd, int nIndex, int dwNewLong); // Don't use this version for dealing with pointers [DllImport("user32", SetLastError=true)] private static extern int GetWindowLong (IntPtr hWnd, int nIndex); public static int AlterWindowStyle (Window win, WindowStyle orFlags, WindowStyle andNotFlags) { var interop = new WindowInteropHelper(win); int prevStyle = GetWindowLong(interop.Handle, GWL_STYLE); if (prevStyle == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to get window style"); } int newStyle = (prevStyle | (int)orFlags) & ~((int)andNotFlags); if (SetWindowLong(interop.Handle, GWL_STYLE, newStyle) == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to set window style"); } return prevStyle; } public static int DisableMaximizeButton (Window win) { return AlterWindowStyle(win, 0, WindowStyle.WS_MAXIMIZEBOX); } } }

用法:必须在初始化源之后执行此操作。一个不错的方法是使用窗口的SourceInitialized事件:

Window win = ...; /* the Window :-) */ WindowUtil.DisableMaximizeButton(win); WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_MAXIMIZE); WindowUtil.RemoveMenuItem(win, WindowUtil.MenuCommand.SC_CLOSE); while (WindowUtil.RemoveTrailingSeparator(win)) { //do it here }

要禁用Alt+F4功能,最简单的方法就是连接取消事件,并在您确实想要关闭窗口时设置一个标志。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有