X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c11f04122f0f85889165d0bacf7a470fbf3e6fbf..d7b284e5c62523c9a43e26977672b4ff7c5b8981:/src/msw/choice.cpp diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp index e35fab7117..be319a9132 100644 --- a/src/msw/choice.cpp +++ b/src/msw/choice.cpp @@ -239,7 +239,7 @@ int wxChoice::DoAppend(const wxString& item) int wxChoice::DoInsert(const wxString& item, int pos) { wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); - wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index")); + wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); int n = (int)SendMessage(GetHwnd(), CB_INSERTSTRING, pos, (LPARAM)item.c_str()); if ( n == CB_ERR ) @@ -258,7 +258,7 @@ int wxChoice::DoInsert(const wxString& item, int pos) void wxChoice::Delete(int n) { - wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") ); + wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") ); if ( HasClientObjectData() ) { @@ -326,9 +326,9 @@ void wxChoice::SetSelection(int n) // string list functions // ---------------------------------------------------------------------------- -int wxChoice::GetCount() const +size_t wxChoice::GetCount() const { - return (int)SendMessage(GetHwnd(), CB_GETCOUNT, 0, 0); + return (size_t)SendMessage(GetHwnd(), CB_GETCOUNT, 0, 0); } int wxChoice::FindString(const wxString& s, bool bCase) const @@ -336,8 +336,8 @@ int wxChoice::FindString(const wxString& s, bool bCase) const #if defined(__WATCOMC__) && defined(__WIN386__) // For some reason, Watcom in WIN386 mode crashes in the CB_FINDSTRINGEXACT message. // wxChoice::Do it the long way instead. - int count = GetCount(); - for ( int i = 0; i < count; i++ ) + size_t count = GetCount(); + for ( size_t i = 0; i < count; i++ ) { // as CB_FINDSTRINGEXACT is case insensitive, be case insensitive too if ( GetString(i).IsSameAs(s, bCase) ) @@ -350,8 +350,8 @@ int wxChoice::FindString(const wxString& s, bool bCase) const //passed to SendMessage, so we have to do it ourselves in that case if ( s.empty() ) { - int count = GetCount(); - for ( int i = 0; i < count; i++ ) + size_t count = GetCount(); + for ( size_t i = 0; i < count; i++ ) { if ( GetString(i).empty() ) return i; @@ -376,8 +376,7 @@ int wxChoice::FindString(const wxString& s, bool bCase) const void wxChoice::SetString(int n, const wxString& s) { - wxCHECK_RET( n >= 0 && n < GetCount(), - wxT("invalid item index in wxChoice::SetString") ); + wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::SetString") ); // we have to delete and add back the string as there is no way to change a // string in place @@ -507,10 +506,13 @@ void wxChoice::DoSetSize(int x, int y, { int heightOrig = height; + int widthCurrent, heightCurrent; + DoGetSize(&widthCurrent, &heightCurrent); + // the height which we must pass to Windows should be the total height of // the control including the drop down list while the height given to us // is, of course, just the height of the permanently visible part of it - if ( height != wxDefaultCoord ) + if ( height != wxDefaultCoord && height != heightCurrent ) { // don't make the drop down list too tall, arbitrarily limit it to 40 // items max and also don't leave it empty @@ -524,8 +526,28 @@ void wxChoice::DoSetSize(int x, int y, const int hItem = SendMessage(GetHwnd(), CB_GETITEMHEIGHT, 0, 0); height += hItem*(nItems + 1); } - else + else // keep the same height as now { + // normally wxWindow::DoSetSize() checks if we set the same size as the + // window already has and does nothing in this case, but for us the + // check fails as the size we pass to it includes the dropdown while + // the size returned by our GetSize() does not, so test if the size + // didn't really change ourselves here + if ( width == wxDefaultCoord || width == widthCurrent ) + { + // size doesn't change, what about position? + int xCurrent, yCurrent; + DoGetPosition(&xCurrent, &yCurrent); + const bool defMeansUnchanged = !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE); + if ( ((x == wxDefaultCoord && defMeansUnchanged) || x == xCurrent) + && + ((y == wxDefaultCoord && defMeansUnchanged) || y == yCurrent) ) + { + // nothing changes, nothing to do + return; + } + } + // We cannot pass wxDefaultCoord as height to wxControl. wxControl uses // wxGetWindowRect() to determine the current height of the combobox, // and then again sets the combobox's height to that value. Unfortunately, @@ -533,12 +555,15 @@ void wxChoice::DoSetSize(int x, int y, // on Win2K), so this would result in a combobox with dropdown height of // 1 pixel. We have to determine the default height ourselves and call // wxControl with that value instead. - int w, h; + // + // Also notice that sometimes CB_GETDROPPEDCONTROLRECT seems to return + // wildly incorrect values (~32000) which looks like a bug in it, just + // ignore them in this case RECT r; - DoGetSize(&w, &h); - if (::SendMessage(GetHwnd(), CB_GETDROPPEDCONTROLRECT, 0, (LPARAM) &r) != 0) + if ( ::SendMessage(GetHwnd(), CB_GETDROPPEDCONTROLRECT, 0, (LPARAM) &r) + && r.bottom < 30000 ) { - height = h + r.bottom - r.top; + height = heightCurrent + r.bottom - r.top; } }