[WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu)

                      [WPF疑难]如何禁用WPF窗口的系统菜单(SystemMenu)

                                      周银辉

 点击窗口左上角图标时弹出来的菜单也就是这里所说的系统菜单(SystemMenu),有时需要禁用(移除)其中的某些或全部菜单项。刚才也有网友问到了这一点,OK,贴代码:

要全部禁用(移除)菜单项请调用SystemMenuManager.RemoveWindowSystemMenu(Window window)方法,想部分禁用(移除)菜单项则调用SystemMenuManager.RemoveWindowSystemMenuItem(Window window, int itemIndex)方法。
值得注意的是禁用了其中的菜单项那么与之相关联的功能也会被禁用,比如将“关闭”从其中移除,那么窗口的右上角的关闭按钮也会被禁用,在任务栏的窗口图标上右击也不会出现相应的项目

public static class SystemMenuManager
    {
        [DllImport("user32.dll", EntryPoint = "GetSystemMenu")]
        private static extern IntPtr GetSystemMenu(IntPtr hwnd, int revert);

        [DllImport("user32.dll", EntryPoint = "GetMenuItemCount")]
        private static extern int GetMenuItemCount(IntPtr hmenu);

        [DllImport("user32.dll", EntryPoint = "RemoveMenu")]
        private static extern int RemoveMenu(IntPtr hmenu, int npos, int wflags);

        [DllImport("user32.dll", EntryPoint = "DrawMenuBar")]
        private static extern int DrawMenuBar(IntPtr hwnd);

        private const int MF_BYPOSITION = 0x0400;
        private const int MF_DISABLED = 0x0002;

        public static void RemoveWindowSystemMenu(Window window)
        {
            if(window == null)
            {
                return;
            }

            window.SourceInitialized += window_SourceInitialized;

        }

        static void window_SourceInitialized(object sender, EventArgs e)
        {
            var window = (Window) sender;

            var helper = new WindowInteropHelper(window);
            IntPtr windowHandle = helper.Handle; //Get the handle of this window
            IntPtr hmenu = GetSystemMenu(windowHandle, 0);
            int cnt = GetMenuItemCount(hmenu);

            for (int i = cnt - 1; i >= 0; i--)
            {
                RemoveMenu(hmenu, i, MF_DISABLED | MF_BYPOSITION);
            }
        }

        public static void RemoveWindowSystemMenuItem(Window window, int itemIndex)
        {
            if (window == null)
            {
                return;
            }

            window.SourceInitialized += delegate
                                            {
                                                var helper = new WindowInteropHelper(window);
                                                IntPtr windowHandle = helper.Handle; //Get the handle of this window
                                                IntPtr hmenu = GetSystemMenu(windowHandle, 0);

                                                //remove the menu item
                                                RemoveMenu(hmenu, itemIndex, MF_DISABLED | MF_BYPOSITION);

                                                DrawMenuBar(windowHandle); //Redraw the menu bar
                                            };

           

        }
    }
posted @   周银辉  阅读(7597)  评论(10编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示