]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/choice.cpp
exposing common used button impl class
[wxWidgets.git] / src / msw / choice.cpp
index 34dd9b817da0c8deb77c1d565a5dfb85bd532954..5ad9416212632d93fd85cfd7aae748cdb61783a5 100644 (file)
@@ -86,10 +86,7 @@ bool wxChoice::CreateAndInit(wxWindow *parent,
 
 
     // initialize the controls contents
-    for ( int i = 0; i < n; i++ )
-    {
-        Append(choices[i]);
-    }
+    Append(n, choices);
 
     // and now we may finally size the control properly (if needed)
     SetInitialSize(size);
@@ -336,7 +333,7 @@ int wxChoice::FindString(const wxString& s, bool bCase) const
    else
    {
        int pos = (int)SendMessage(GetHwnd(), CB_FINDSTRINGEXACT,
-                                  (WPARAM)-1, (LPARAM)s.wx_str());
+                                  (WPARAM)-1, wxMSW_CONV_LPARAM(s));
 
        return pos == LB_ERR ? wxNOT_FOUND : pos;
    }
@@ -363,7 +360,7 @@ void wxChoice::SetString(unsigned int n, const wxString& s)
     const bool wasSelected = static_cast<int>(n) == GetSelection();
 
     ::SendMessage(GetHwnd(), CB_DELETESTRING, n, 0);
-    ::SendMessage(GetHwnd(), CB_INSERTSTRING, n, (LPARAM)s.wx_str() );
+    ::SendMessage(GetHwnd(), CB_INSERTSTRING, n, wxMSW_CONV_LPARAM(s) );
 
     // restore the client data
     if ( oldData )
@@ -417,7 +414,7 @@ void wxChoice::DoSetItemClientData(unsigned int n, void* clientData)
 void* wxChoice::DoGetItemClientData(unsigned int n) const
 {
     LPARAM rc = SendMessage(GetHwnd(), CB_GETITEMDATA, n, 0);
-    if ( rc == CB_ERR )
+    if ( rc == CB_ERR && GetLastError() != ERROR_SUCCESS )
     {
         wxLogLastError(wxT("CB_GETITEMDATA"));
 
@@ -590,34 +587,18 @@ void wxChoice::DoSetSize(int x, int y,
 
 wxSize wxChoice::DoGetBestSize() const
 {
-    // find the widest string
-    int wChoice = 0;
-    int hChoice;
-    const unsigned int nItems = GetCount();
-    for ( unsigned int i = 0; i < nItems; i++ )
-    {
-        int wLine;
-        GetTextExtent(GetString(i), &wLine, NULL);
-        if ( wLine > wChoice )
-            wChoice = wLine;
-    }
+    // The base version returns the size of the largest string
+    wxSize best( wxChoiceBase::DoGetBestSize() );
 
-    // give it some reasonable default value if there are no strings in the
-    // list
-    if ( wChoice == 0 )
-        wChoice = 100;
+    // We just need to adjust it to account for the arrow width.
+    best.x += 5*GetCharWidth();
 
-    // the combobox should be slightly larger than the widest string
-    wChoice += 5*GetCharWidth();
+    // set height on our own
     if( HasFlag( wxCB_SIMPLE ) )
-    {
-        hChoice = SetHeightSimpleComboBox( nItems );
-    }
+        best.y = SetHeightSimpleComboBox(GetCount());
     else
-        hChoice = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight());
+        best.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(GetCharHeight());
 
-    wxSize best(wChoice, hChoice);
-    CacheBestSize(best);
     return best;
 }
 
@@ -629,6 +610,39 @@ int wxChoice::SetHeightSimpleComboBox(int nItems) const
     return EDIT_HEIGHT_FROM_CHAR_HEIGHT( cy ) * wxMin( wxMax( nItems, 3 ), 6 ) + hItem - 1;
 }
 
+// ----------------------------------------------------------------------------
+// Popup operations
+// ----------------------------------------------------------------------------
+
+void wxChoice::MSWDoPopupOrDismiss(bool show)
+{
+    wxASSERT_MSG( !HasFlag(wxCB_SIMPLE),
+                  wxT("can't popup/dismiss the list for simple combo box") );
+
+    // we *must* set focus to the combobox before showing or hiding the drop
+    // down as without this we get WM_LBUTTONDOWN messages with invalid HWND
+    // when hiding it (whether programmatically or manually) resulting in a
+    // crash when we pass them to IsDialogMessage()
+    //
+    // this can be seen in the combo page of the widgets sample under Windows 7
+    SetFocus();
+
+    ::SendMessage(GetHwnd(), CB_SHOWDROPDOWN, show, 0);
+}
+
+bool wxChoice::Show(bool show)
+{
+    if ( !wxChoiceBase::Show(show) )
+        return false;
+
+    // When hiding the combobox, we also need to hide its popup part as it
+    // doesn't happen automatically.
+    if ( !show && ::SendMessage(GetHwnd(), CB_GETDROPPEDSTATE, 0, 0) )
+        MSWDoPopupOrDismiss(false);
+
+    return true;
+}
+
 // ----------------------------------------------------------------------------
 // MSW message handlers
 // ----------------------------------------------------------------------------
@@ -761,7 +775,7 @@ bool wxChoice::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 
 WXHBRUSH wxChoice::MSWControlColor(WXHDC hDC, WXHWND hWnd)
 {
-    if ( !IsEnabled() )
+    if ( !IsThisEnabled() )
         return MSWControlColorDisabled(hDC);
 
     return wxChoiceBase::MSWControlColor(hDC, hWnd);