在 Win32 視窗程式設計中,在彈出式選單項目中再次彈出子選單(巢狀彈出選單)是常見需求。許多開發者嘗試自繪選單、模擬視窗或複雜的 Hook 機制,實則 Win32 API 已內建支援,極為簡單。
呼叫 TrackPopupMenuEx 時,在 fuFlags 參數中加入 TPM_RECURSE 標誌:
TrackPopupMenuEx(hMenu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RECURSE | TPM_RIGHTBUTTON,
x, y, hWnd, NULL);
| 標誌 | 作用 |
|---|---|
TPM_RECURSE | 允許遞迴彈出選單。若無此旗標,在彈出選單處理期間再次呼叫 TrackPopupMenuEx 會失敗或表現異常。 |
TPM_RIGHTBUTTON | 允許以右鍵點選選單項目觸發子選單(配合滑鼠訊息)。 |
TPM_LEFTBUTTON | 預設值,僅左鍵觸發。若需右鍵操作子選單,需指定 RIGHTBUTTON。 |
MF_POPUP 旗標,關聯子選單控制代碼(GetSubMenu 或 CreatePopupMenu 建立)。WM_CONTEXTMENU 或滑鼠右鍵訊息時,呼叫帶 TPM_RECURSE 的 TrackPopupMenuEx。TrackPopupMenu(舊版 API)而非 TrackPopupMenuEx,前者不支援 TPM_RECURSE。TPM_RIGHTBUTTON 導致右鍵無法觸發子選單。DialogBox),阻塞選單訊息泵,導致子選單無法顯示。應改用非模態或延後處理。善用 TPM_RECURSE,即可輕鬆實現專業級的多層彈出選單,無需複雜的自繪或 Hook 技術。