+// ----------------------------------------------------------------------------
+// client data
+// ----------------------------------------------------------------------------
+
+void wxChoice::DoSetItemClientData(unsigned int n, void* clientData)
+{
+ if ( ::SendMessage(GetHwnd(), CB_SETITEMDATA,
+ n, (LPARAM)clientData) == CB_ERR )
+ {
+ wxLogLastError(wxT("CB_SETITEMDATA"));
+ }
+}
+
+void* wxChoice::DoGetItemClientData(unsigned int n) const
+{
+ LPARAM rc = SendMessage(GetHwnd(), CB_GETITEMDATA, n, 0);
+ if ( rc == CB_ERR )
+ {
+ wxLogLastError(wxT("CB_GETITEMDATA"));
+
+ // unfortunately, there is no way to return an error code to the user
+ rc = (LPARAM) NULL;
+ }
+
+ return (void *)rc;
+}
+
+// ----------------------------------------------------------------------------
+// wxMSW-specific geometry management
+// ----------------------------------------------------------------------------
+
+namespace
+{
+
+// there is a difference between the height passed to CB_SETITEMHEIGHT and the
+// real height of the combobox; it is probably not constant for all Windows
+// versions/settings but right now I don't know how to find what it is so it is
+// temporarily hardcoded to its value under XP systems with normal fonts sizes
+const int COMBO_HEIGHT_ADJ = 6;
+
+} // anonymous namespace
+
+void wxChoice::MSWUpdateVisibleHeight()
+{
+ if ( m_heightOwn != wxDefaultCoord )
+ {
+ ::SendMessage(GetHwnd(), CB_SETITEMHEIGHT,
+ (WPARAM)-1, m_heightOwn - COMBO_HEIGHT_ADJ);
+ }
+}
+
+#if wxUSE_DEFERRED_SIZING
+void wxChoice::MSWEndDeferWindowPos()
+{
+ // we can only set the height of the choice itself now as it is reset to
+ // default every time the control is resized
+ MSWUpdateVisibleHeight();
+
+ wxChoiceBase::MSWEndDeferWindowPos();
+}
+#endif // wxUSE_DEFERRED_SIZING
+
+void wxChoice::MSWUpdateDropDownHeight()
+{
+ // be careful to not change the width here
+ DoSetSize(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, GetSize().y,
+ wxSIZE_USE_EXISTING);
+}
+
+void wxChoice::DoMoveWindow(int x, int y, int width, int height)
+{
+ // here is why this is necessary: if the width is negative, the combobox
+ // window proc makes the window of the size width*height instead of
+ // interpreting height in the usual manner (meaning the height of the drop
+ // down list - usually the height specified in the call to MoveWindow()
+ // will not change the height of combo box per se)
+ //
+ // this behaviour is not documented anywhere, but this is just how it is
+ // here (NT 4.4) and, anyhow, the check shouldn't hurt - however without
+ // the check, constraints/sizers using combos may break the height
+ // constraint will have not at all the same value as expected
+ if ( width < 0 )
+ return;
+
+ wxControl::DoMoveWindow(x, y, width, height);
+}
+
+void wxChoice::DoGetSize(int *w, int *h) const
+{
+ wxControl::DoGetSize(w, h);
+
+ // this is weird: sometimes, the height returned by Windows is clearly the
+ // total height of the control including the drop down list -- but only
+ // sometimes, and sometimes it isn't so work around this here by using our
+ // own stored value if we have it
+ if ( h && m_heightOwn != wxDefaultCoord )
+ *h = m_heightOwn;
+}
+