Reputation: 1304
I have a ComboBox in a window and i want to execute a function after changing selected item.
When i change the selected item of the combobox by mouse or keyboard,
the CBN_SELCHANGE
event in the window message WM_COMMAND
works well and my function execute.
But if i use the function ComboBox_SetCurSel
for changing the selected item ,it not works.
What window message WM_****
and combox notification do i use for processing the event changing selected item.
Upvotes: 4
Views: 2442
Reputation: 244981
In general, when you programmatically manipulate a control, the corresponding notification is not sent to its parent. The notification only gets sent when the user manipulates the control.
So, when you call ComboBox_SetCurSel
(which is a macro that performs the same task as sending the CB_SETCURSEL
message), that programmatically changes the control's current selection and therefore does not send the CBN_SELCHANGE
notification. However, CBN_SELCHANGE
does get sent if the user changes the combobox's selection.
This is called out explicitly in the "Remarks" section of the documentation for CBN_SELCHANGE
:
The
CBN_SELCHANGE
notification code is not sent when the current selection is set using theCB_SETCURSEL
message.
To work around this, you can do one of two things:
Call your event-handler method directly. For example, in MFC, you would have the framework attach an OnCbnSelChange
member function to handle the combobox's CBN_SELCHANGE
notification. After your code that called ComboBox_SetCurSel
, you would simply call that OnCbnSelChange
member function manually:
ComboBox_SetCurSel(hwndComboBox, 0); // select 1st item
this->OnCbnSelChange(); // invoke the change event-handler
Your GUI framework undoubtedly has something similar.
Manually send the CBN_SELCHANGE
notification to the control's parent. I don't really know why you would ever do this, because the default window procedure doesn't do anything interesting upon receipt of this notification; you would be much better off just calling your own handler directly.
::PostMessage(hwndParent,
WM_COMMAND,
MAKEWPARAM(IDC_COMBOBOX, CBN_SELCHANGE),
reinterpret_cast<LPARAM>(hwndComboBox);
Or, if you were doing this from a subclass of the combobox:
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));
Upvotes: 5