首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 禁用視窗系統選單完整解決方案

     編輯:關於.NET

WPF 視窗左上角圖示點擊彈出的系統選單,有時需移除特定項目(如「關閉」、「最大化」)或全部禁用。本文提供靜態工具類 SystemMenuManager,透過 Win32 API GetSystemMenu、RemoveMenu 實現精確控制,並處理 WPF 視窗句柄取得時機問題。

核心 API 宣告

[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;

兩種使用模式

1. 完全移除系統選單

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 hmenu = GetSystemMenu(helper.Handle, 0);
    int cnt = GetMenuItemCount(hmenu);
    for (int i = cnt - 1; i >= 0; i--) {
        RemoveMenu(hmenu, i, MF_DISABLED | MF_BYPOSITION);
    }
}

在 SourceInitialized 事件中執行,確保視窗句柄已建立。反向迴圈避免索引位移問題。

2. 移除特定選單項目

public static void RemoveWindowSystemMenuItem(Window window, int itemIndex) {
    if (window == null) return;
    window.SourceInitialized += delegate {
        var helper = new WindowInteropHelper(window);
        IntPtr hmenu = GetSystemMenu(helper.Handle, 0);
        RemoveMenu(hmenu, itemIndex, MF_DISABLED | MF_BYPOSITION);
        DrawMenuBar(helper.Handle); // 重繪選單列
    };
}

itemIndex 為 0 基底索引,對應選單項目順序(還原、移動、大小、最小化、最大化、分隔線、關閉...)。

重要副作用提醒

移除選單項目會同步禁用其關聯功能:

  • 移除「關閉」→ 視窗右上角 × 按鈕失效、工作列右鍵無「關閉」選項、Alt+F4 無效
  • 移除「最大化」→ 最大化按鈕與雙擊標題列最大化失效

若僅需阻止關閉而保留 UI,請改用 Closing 事件設定 e.Cancel = true。

適用場景

  • 自訂標題列視窗(WindowStyle=None),需隱藏原生系統選單
  • 嚴格流程控制視窗,禁止使用者透過系統選單關閉/最大化
  • Kiosk 模式應用程式,鎖定視窗操作行為
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved