- // For some reason, Watcom in WIN386 mode crashes in the CB_FINDSTRINGEXACT message.
- // Do it the long way instead.
- char buf[512];
- for (int i = 0; i < Number(); i++)
- {
- int len = (int)SendMessage((HWND) GetHWND(), CB_GETLBTEXT, i, (LPARAM)(LPSTR)buf);
- buf[len] = 0;
- if (strcmp(buf, (const char *)s) == 0)
- return i;
- }
- return -1;
-#else
- int pos = (int)SendMessage((HWND) GetHWND(), CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPSTR)(const char *)s);
- if (pos == LB_ERR)
- return -1;
- else
- return pos;
-#endif
+ // For some reason, Watcom in WIN386 mode crashes in the CB_FINDSTRINGEXACT message.
+ // wxChoice::Do it the long way instead.
+ unsigned int count = GetCount();
+ for ( unsigned int i = 0; i < count; i++ )
+ {
+ // as CB_FINDSTRINGEXACT is case insensitive, be case insensitive too
+ if (GetString(i).IsSameAs(s, bCase))
+ return i;
+ }
+
+ return wxNOT_FOUND;
+#else // !Watcom
+ //TODO: Evidently some MSW versions (all?) don't like empty strings
+ //passed to SendMessage, so we have to do it ourselves in that case
+ if ( s.empty() )
+ {
+ unsigned int count = GetCount();
+ for ( unsigned int i = 0; i < count; i++ )
+ {
+ if (GetString(i).empty())
+ return i;
+ }
+
+ return wxNOT_FOUND;
+ }
+ else if (bCase)
+ {
+ // back to base class search for not native search type
+ return wxItemContainerImmutable::FindString( s, bCase );
+ }
+ else
+ {
+ int pos = (int)SendMessage(GetHwnd(), CB_FINDSTRINGEXACT,
+ (WPARAM)-1, (LPARAM)s.wx_str());
+
+ return pos == LB_ERR ? wxNOT_FOUND : pos;
+ }
+#endif // Watcom/!Watcom
+}
+
+void wxChoice::SetString(unsigned int n, const wxString& s)
+{
+ 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
+
+ // we need to preserve the client data manually
+ void *oldData = NULL;
+ wxClientData *oldObjData = NULL;
+ if ( HasClientUntypedData() )
+ oldData = GetClientData(n);
+ else if ( HasClientObjectData() )
+ oldObjData = GetClientObject(n);
+
+ // and also the selection if we're going to delete the item that was
+ // selected
+ const bool wasSelected = static_cast<int>(n) == GetSelection();
+
+ ::SendMessage(GetHwnd(), CB_DELETESTRING, n, 0);
+ ::SendMessage(GetHwnd(), CB_INSERTSTRING, n, (LPARAM)s.wx_str() );
+
+ // restore the client data
+ if ( oldData )
+ SetClientData(n, oldData);
+ else if ( oldObjData )
+ SetClientObject(n, oldObjData);
+
+ // and the selection
+ if ( wasSelected )
+ SetSelection(n);
+
+ // the width could have changed so the best size needs to be recomputed
+ InvalidateBestSize();
+}
+
+wxString wxChoice::GetString(unsigned int n) const
+{
+ int len = (int)::SendMessage(GetHwnd(), CB_GETLBTEXTLEN, n, 0);
+
+ wxString str;
+ if ( len != CB_ERR && len > 0 )
+ {
+ if ( ::SendMessage
+ (
+ GetHwnd(),
+ CB_GETLBTEXT,
+ n,
+ (LPARAM)(wxChar *)wxStringBuffer(str, len)
+ ) == CB_ERR )
+ {
+ wxLogLastError(wxT("SendMessage(CB_GETLBTEXT)"));
+ }
+ }
+
+ return str;
+}
+
+// ----------------------------------------------------------------------------
+// client data
+// ----------------------------------------------------------------------------
+
+void wxChoice::DoSetItemClientData(unsigned int n, void* clientData)
+{
+ if ( ::SendMessage(GetHwnd(), CB_SETITEMDATA,
+ n, (LPARAM)clientData) == CB_ERR )
+ {
+ wxLogLastError(wxT("CB_SETITEMDATA"));
+ }