+
+ // 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;
+}
+
+// ----------------------------------------------------------------------------
+// wxComboBox creation
+// ----------------------------------------------------------------------------
+
+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;
+
+ if ( !CreateAndInit(parent, id, pos, size, n, choices, style,
+ validator, name) )
+ return FALSE;
+
+ // we shouldn't call SetValue() for an empty string because this would
+ // (correctly) result in an assert with a read only combobox and is useless
+ // for the other ones anyhow
+ if ( !value.empty() )
+ SetValue(value);
+
+ // 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) )
+ {
+ gs_wndprocEdit = wxSetWindowProc((HWND)GetEditHWND(),
+ wxComboEditWndProc);
+ }
+
+ // and finally, show the control
+ Show(TRUE);
+
+ return TRUE;
+}
+
+bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
+ const wxString& value,
+ const wxPoint& pos,
+ const wxSize& size,
+ const wxArrayString& choices,
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ wxCArrayString chs(choices);
+ return Create(parent, id, value, pos, size, chs.GetCount(),
+ chs.GetStrings(), style, validator, name);
+}
+
+WXDWORD wxComboBox::MSWGetStyle(long style, WXDWORD *exstyle) const
+{
+ // we never have an external border
+ WXDWORD msStyle = wxChoice::MSWGetStyle
+ (
+ (style & ~wxBORDER_MASK) | wxBORDER_NONE, exstyle
+ );
+
+ // remove the style always added by wxChoice
+ msStyle &= ~CBS_DROPDOWNLIST;
+
+ if ( style & wxCB_READONLY )
+ msStyle |= CBS_DROPDOWNLIST;
+#ifndef __WXWINCE__
+ else if ( style & wxCB_SIMPLE )
+ msStyle |= CBS_SIMPLE; // A list (shown always) and edit control
+#endif
+ else
+ msStyle |= CBS_DROPDOWN;
+
+ // there is no reason to not always use CBS_AUTOHSCROLL, so do use it
+ msStyle |= CBS_AUTOHSCROLL;
+
+ // NB: we used to also add CBS_NOINTEGRALHEIGHT here but why?
+
+ return msStyle;
+}
+
+// ----------------------------------------------------------------------------
+// wxComboBox text control-like methods
+// ----------------------------------------------------------------------------
+
+void wxComboBox::SetValue(const wxString& value)
+{
+ if ( HasFlag(wxCB_READONLY) )
+ SetStringSelection(value);
+ else
+ SetWindowText(GetHwnd(), value.c_str());