需求:使用者點擊 CComboBox 下拉箭頭時,彈出自訂選擇對話框,選完後將結果寫入 ComboBox 編輯框,**並自動收回下拉列表**。
初期嘗試在 CBN_DROPDOWN 通知處理函數中直接呼叫:
// 失效嘗試 m_combo.SendMessage(CB_SHOWDROPDOWN, FALSE, 0); m_combo.SendMessage(WM_KILLFOCUS, 0, 0); m_combo.SendMessage(WM_KEYDOWN, VK_ESCAPE, 0);
全部無效,下拉列表依然停留展開。
經測試發現:**CBN_DROPDOWN 通知發送時,下拉列表尚未真正彈出**;通知處理完畢後,系統才真正建立並顯示列表框。因此在通知處理中嘗試收回屬於「過早操作」,無效果。
OnKillFocus 中呼叫 CB_SHOWDROPDOWN(FALSE)KillFocus,導致時序錯亂。void CMyDialog::OnCbnDropdownCombo()
{
// 1. 彈出自訂選擇對話框
CSelectDlg dlg;
if (dlg.DoModal() == IDOK)
{
// 2. 更新 ComboBox 內容
m_combo.ResetContent();
m_combo.AddString(dlg.GetSelectedText());
m_combo.SetCurSel(0);
}
// 3. 關鍵:投遞 ESC 鍵訊息,讓系統在通知處理完畢後自動收回下拉框
m_combo.PostMessage(WM_KEYDOWN, VK_ESCAPE, 0);
}
| 關鍵字 | 說明 |
|---|---|
PostMessage 而非 SendMessage | 投遞到訊息佇列,**等待當前通知處理結束、下拉框真正建立後** 再處理 ESC |
VK_ESCAPE | 系統原生支援:ComboBox 收到 ESC 會自動呼叫 CB_SHOWDROPDOWN(FALSE) |
| 時序 | 通知處理 → 系統建立列表框 → 訊息泵處理 ESC → 列表框收回 |
CComboBox (CBS_DROPDOWN / CBS_DROPDOWNLIST)CBN_DROPDOWN / CBN_SELCHANGE 等通知中強制收回下拉框的場景