+ wxString value;
+ int sel = -1;
+ switch ( param )
+ {
+ case CBN_SELCHANGE:
+ sel = GetSelection();
+ if ( sel > -1 )
+ {
+ value = GetString(sel);
+
+ wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, GetId());
+ event.SetInt(sel);
+ event.SetEventObject(this);
+ event.SetString(value);
+ ProcessCommand(event);
+ }
+ else
+ {
+ break;
+ }
+
+ // fall through: for compability with wxGTK, also send the text
+ // update event when the selection changes (this also seems more
+ // logical as the text does change)
+
+ case CBN_EDITCHANGE:
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId());
+
+ // if sel != -1, value was initialized above (and we can't use
+ // GetValue() here as it would return the old selection and we
+ // want the new one)
+ if ( sel == -1 )
+ {
+ value = GetValue();
+ }
+ else // we're synthesizing text updated event from sel change
+ {
+ // we need to do this because the user code expects
+ // wxComboBox::GetValue() to return the new value from
+ // "text updated" handler but it hadn't been updated yet
+ SetValue(value);
+ }
+
+ event.SetString(value);
+ event.SetEventObject(this);
+ ProcessCommand(event);
+ }
+ break;
+ }
+
+ // there is no return value for the CBN_ notifications, so always return
+ // FALSE from here to pass the message to DefWindowProc()
+ return FALSE;
+}
+
+WXHWND wxComboBox::GetEditHWND() const
+{
+ // this function should not be called for wxCB_READONLY controls, it is
+ // the callers responsability to check this
+ wxASSERT_MSG( !(GetWindowStyle() & wxCB_READONLY),
+ _T("read-only combobox doesn't have any edit control") );
+
+ POINT pt;
+ pt.x = pt.y = 4;
+ HWND hwndEdit = ::ChildWindowFromPoint(GetHwnd(), pt);
+ if ( !hwndEdit || hwndEdit == GetHwnd() )
+ {
+ wxFAIL_MSG(_T("not read only combobox without edit control?"));
+ }
+
+ return (WXHWND)hwndEdit;
+}
+
+bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
+ const wxString& value,
+ const wxPoint& pos,
+ const wxSize& size,
+ int n, const wxString choices[],
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ // pretend that wxComboBox is hidden while it is positioned and resized and
+ // show it only right before leaving this method because otherwise there is
+ // some noticeable flicker while the control rearranges itself
+ m_isShown = FALSE;
+
+ // first create wxWin object
+ if ( !CreateControl(parent, id, pos, size, style, validator, name) )
+ return FALSE;
+
+ // get the right style
+ long msStyle = WS_TABSTOP | WS_VSCROLL | WS_HSCROLL |
+ CBS_AUTOHSCROLL | CBS_NOINTEGRALHEIGHT /* | WS_CLIPSIBLINGS */;
+ if ( style & wxCB_READONLY )
+ msStyle |= CBS_DROPDOWNLIST;
+ else if ( style & wxCB_SIMPLE )
+ msStyle |= CBS_SIMPLE; // A list (shown always) and edit control
+ else
+ msStyle |= CBS_DROPDOWN;
+
+ if ( style & wxCB_SORT )
+ msStyle |= CBS_SORT;
+
+ if ( style & wxCLIP_SIBLINGS )
+ msStyle |= WS_CLIPSIBLINGS;
+
+
+ // and now create the MSW control
+ if ( !MSWCreateControl(_T("COMBOBOX"), msStyle) )
+ return FALSE;
+
+ // A choice/combobox normally has a white background (or other, depending
+ // on global settings) rather than inheriting the parent's background colour.
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+
+ for ( int i = 0; i < n; i++ )
+ {
+ Append(choices[i]);
+ }
+
+ if ( !value.IsEmpty() )
+ {
+ SetValue(value);
+ }
+
+ // do this after appending the values to the combobox so that autosizing
+ // works correctly
+ SetSize(pos.x, pos.y, size.x, size.y);
+
+ // a (not read only) combobox is, in fact, 2 controls: the combobox itself
+ // and an edit control inside it and if we want to catch events from this
+ // edit control, we must subclass it as well
+ if ( !(style & wxCB_READONLY) )