我在窗口中有一個ComboBox,並且我想在更改所選項目後執行一個函數。 當我通過鼠標或鍵盤更改組合框的選定項目時, 窗口消息WM_COMMAND
中的CBN_SELCHANGE
事件運行良好,並執行我的函數。當我使用ComboBox_SetCurSel函數時,CBN_SELCHANGE通知不起作用
但是,如果我使用功能ComboBox_SetCurSel
更改選定的項目,它不起作用。
什麼窗口消息WM_****
和combox通知我用於處理事件更改選定的項目。
我在窗口中有一個ComboBox,並且我想在更改所選項目後執行一個函數。 當我通過鼠標或鍵盤更改組合框的選定項目時, 窗口消息WM_COMMAND
中的CBN_SELCHANGE
事件運行良好,並執行我的函數。當我使用ComboBox_SetCurSel函數時,CBN_SELCHANGE通知不起作用
但是,如果我使用功能ComboBox_SetCurSel
更改選定的項目,它不起作用。
什麼窗口消息WM_****
和combox通知我用於處理事件更改選定的項目。
一般情況下,當你編程操縱控制,相應的通知是不發送到它的父。只有當用戶操縱該控件時纔會發送通知。
所以,當你調用ComboBox_SetCurSel
(這是執行相同的任務發送CB_SETCURSEL
消息宏),以編程方式改變控件的當前選擇,因此並沒有發送的CBN_SELCHANGE
通知。但是,如果用戶更改了組合框的選擇,則CBN_SELCHANGE
會發送。
這是the documentation for CBN_SELCHANGE
「備註」部分中明確地叫了一聲:在當前的選擇是使用CB_SETCURSEL
消息集不發送
的
CBN_SELCHANGE
通知代碼。
要解決這個問題,你可以做兩件事情之一:
直接打電話給你的事件處理程序方法。例如,在MFC中,您可以讓該框架附加一個OnCbnSelChange
成員函數來處理組合框的CBN_SELCHANGE
通知。你的代碼調用ComboBox_SetCurSel
後,您只需調用手動OnCbnSelChange
成員函數:
ComboBox_SetCurSel(hwndComboBox, 0); // select 1st item
this->OnCbnSelChange(); // invoke the change event-handler
你的GUI框架無疑具有類似的東西。
手動發送CBN_SELCHANGE
通知給控件的父級。我不知道爲什麼你會這樣做,因爲默認的窗口過程在收到這個通知後沒有做任何有趣的事情;你直接調用你自己的處理程序會好得多。
::PostMessage(hwndParent,
WM_COMMAND,
MAKEWPARAM(IDC_COMBOBOX, CBN_SELCHANGE),
reinterpret_cast<LPARAM>(hwndComboBox);
或者,如果你是從組合框的子類,這樣做:
HWND hwndParent = ::GetAncestor(hwndComboBox, GA_PARENT);
int ctrlID = static_cast<int>(::GetWindowLongPtr(hwndComboBox, GWLP_ID));
::PostMessage(hwndParent,
WM_COMMAND,
MAKEWPARAM(ctrlID, CBN_SELCHANGE),
reinterpret_cast<LPARAM>(hwndComboBox));
謝謝you.It運作良好。 – SaeidMo7
「我真的不知道爲什麼你會這麼做,因爲一個組合框的默認窗口過程在收到此通知後不會做任何有趣的事情。」但是,您並沒有將消息發送給組合框,而是將它發送給它到組合框的父代,它具有處理通知的代碼。注意不要把所有這些術語混淆在一起= P(我會親自拼出代碼示例與組合框相關,而不是其父代:SendMessage(GetAncestor(hwnd,GA_PARENT),WM_COMMAND,MAKEWPARAM(GetWindowLongPtr(hwnd,GWLP_ID ),CBN_SELCHANGE),(LPARAM)hwnd);') – andlabs
@和你說得對,扔「組合框」沒有任何意義。我應該只是說默認的窗口過程。我想這也是有道理的,以顯示如何在組合框方面做到這一點。我想有人閱讀,可以從所提供的事實中輕鬆推斷出來。 –