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

WPF 禁用視窗關閉按鈕:Win32 API 精確控制與替代方案

     編輯:關於.NET

需求單純:禁用 WPF 視窗右上角的關閉按鈕 (×),而非攔截關閉邏輯。本文提供呼叫 Win32 GetSystemMenu + EnableMenuItem 的精確實作,並說明 WPF/WinForms 取得視窗句柄的差異。

核心 P/Invoke 宣告

[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int GetSystemMenu(int hwnd, int revert);

[DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int EnableMenuItem(int menu, int ideEnableItem, int enable);

private const int SC_CLOSE = 0xF060;      // 關閉選單項目識別碼
private const int MF_BYCOMMAND = 0x00000000;
private const int MF_GRAYED = 0x00000001; // 灰化 (禁用)
private const int MF_ENABLED = 0x00000002;

禁用實作

public static void Disable(int handle) {
    int result = EnableMenuItem(GetSystemMenu(handle, 0), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
    switch (result) {
        case MF_ENABLED: break; // 原本啟用,現已禁用
        case MF_GRAYED: break;  // 原本已禁用
        case -1: throw new Exception("The Close menu item does not exist.");
        default: break;
    }
}

回傳值表示先前狀態,-1 表選單項目不存在 (異常情況)。

取得視窗句柄

使用時機

在視窗載入後呼叫 (如 Loaded 事件或 SourceInitialized),確保句柄已建立:

private void Window_Loaded(object sender, RoutedEventArgs e) {
    int handle = new WindowInteropHelper(this).Handle.ToInt32();
    CloseButton.Disable(handle);
}

關閉按鈕禁用 vs 取消關閉的差異

視窗類型取得句柄代碼
WPF Windowint handle = new WindowInteropHelper(wpfWindow).Handle.ToInt32();
WinForms Formint handle = this.Handle.ToInt32(); 或 form.Handle.ToInt32()
特性禁用按鈕 (本文)取消關閉 (Closing 事件)
視覺效果按鈕灰化不可點擊按鈕正常,點擊後攔截
Alt+F4無效觸發 Closing 可攔截
工作列右鍵關閉無效觸發 Closing 可攔截
適用場景嚴格鎖定視窗、Kiosk 模式需確認/儲存/驗證再決定是否關閉

替代方案參考

若需「確認後再關閉」而非完全禁用,請參考 Closing 事件設定 e.Cancel = true,或使用 Hide 替代 Close (視窗隱藏而非銷毀)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved