系統選單(標題列左上角圖示或 Alt+Space 呼出)預設由 Windows 管理,若需加入自訂命令(如「關於」、「退出」)、修改既有項目文字或刪除項目,必須攔截 WM_SYSCOMMAND 並手動處理。本文以典型 MFC 對話框專案為例,完整示範系統選單客製化全流程。
#define IDM_ABOUT 16
#define IDM_EXIT 17
// 系統選單保留 ID 範圍:0xF000 以上
// 自訂命令 ID 必須 < 0xF000,且 (ID & 0xFFF0) == ID 以相容 Win95
OnInitDialog)BOOL CMyDlg::OnInitDialog() {
CDialog::OnInitDialog();
ASSERT((IDM_ABOUT & 0xFFF0) == IDM_ABOUT);
ASSERT(IDM_ABOUT < 0xF000);
ASSERT((IDM_EXIT & 0xFFF0) == IDM_EXIT);
ASSERT(IDM_EXIT < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE); // FALSE=取得現有選單,TRUE=重置為預設
if (pSysMenu) {
pSysMenu->AppendMenu(MF_STRING, IDM_EXIT, _T("退出(&X)"));
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUT, _T("關於(&A)..."));
}
return TRUE;
}
OnSysCommand)void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam) {
switch (nID & 0xFFF0) { // 同樣需 & 0xFFF0 相容 Win95
case IDM_ABOUT:
CAboutDlg().DoModal(); break;
case IDM_EXIT:
::PostQuitMessage(0); break; // 真正結束程式
case SC_CLOSE: // 原「關閉」改為隱藏視窗(配合系統托盤)
OnClose(); break;
default:
CDialog::OnSysCommand(nID, lParam); // 其餘交給預設處理
}
}
| 命令 | 說明 |
|---|---|
| SC_CLOSE | 關閉視窗 |
| SC_MAXIMIZE / SC_ZOOM | 最大化 |
| SC_MINIMIZE / SC_ICON | 最小化 |
| SC_MOVE | 移動視窗 |
| SC_RESTORE | 還原視窗 |
| SC_SIZE | 調整視窗大小 |
// 修改「關閉」為「隱藏」
pSysMenu->ModifyMenu(SC_CLOSE, MF_BYCOMMAND, IDM_HIDE, _T("隱藏(&H)"));
// 或依位置修改(索引 0 為第一項)
pSysMenu->ModifyMenu(0, MF_BYPOSITION, IDM_HIDE, _T("隱藏(&H)"));
// 刪除「關閉」命令
pSysMenu->RemoveMenu(SC_CLOSE, MF_BYCOMMAND);
// 刪除第一項
pSysMenu->RemoveMenu(0, MF_BYPOSITION);
適用於需常駐系統托盤、最小化至托盤而非工作列、或需在工作列右鍵選單提供快速命令的小型工具程式。範例程式同時示範第三方托盤類別整合,達成「關閉鈕隱藏視窗、托盤圖示還原/退出」的經典行為。