]> git.saurik.com Git - wxWidgets.git/commitdiff
multiple fixes to wxChoice/wxCombobox height getting/setting (replaces patches 888171...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Feb 2004 18:42:56 +0000 (18:42 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Feb 2004 18:42:56 +0000 (18:42 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25574 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/msw/choice.h
src/msw/choice.cpp

index 7554eb47e5609f1dc3bfcda080cea14e6d5d70d4..2d613b905631554463404d16efc429f3935270dd 100644 (file)
@@ -35,6 +35,9 @@ INCOMPATIBLE CHANGES SINCE 2.4.x
   (when WXWIN_COMPATIBILITY_2_4 == 0)
 - wxID_SEPARATOR (id used for the menu separators) value changed from -1 to -2
 - wxGetNumberFromUser() is now in separate wx/numdlg.h, not wx/textdlg.h
+- wxChoice and wxCombobox now handle their size in the same way as in all the
+  other ports under MSW, new code is actually correct but different from weird
+  stuff they were doing before so the behaviour of your programs might change
 
 
 DEPRECATED METHODS SINCE 2.4.x
index ab7016061f66e83770bacaf0ad30c94f01cd02b3..ce9d5b58e2a69a4b6579b09b52e8366c2d21a76a 100644 (file)
@@ -96,10 +96,14 @@ protected:
 
     // MSW implementation
     virtual wxSize DoGetBestSize() const;
+    virtual void DoGetSize(int *w, int *h) const;
     virtual void DoSetSize(int x, int y,
                            int width, int height,
                            int sizeFlags = wxSIZE_AUTO);
 
+    // get the real height of the control
+    int GetVisibleHeight() const;
+
     // free all memory we have (used by Clear() and dtor)
     void Free();
 
index 220f7c8cfd555c259865017f15d6ad3defe025b0..4d1df2c1a42f6313348740c7a820ca0d5ffd33ea 100644 (file)
@@ -118,7 +118,7 @@ bool wxChoice::Create(wxWindow *parent,
     if ( !CreateControl(parent, id, pos, size, style, validator, name) )
         return FALSE;
 
-    long msStyle = WS_CHILD | CBS_DROPDOWNLIST | WS_TABSTOP | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL /* | WS_CLIPSIBLINGS */;
+    long msStyle = WS_CHILD | CBS_DROPDOWNLIST | WS_TABSTOP | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL;
     if ( style & wxCB_SORT )
         msStyle |= CBS_SORT;
 
@@ -367,6 +367,11 @@ wxClientData* wxChoice::DoGetItemClientObject( int n ) const
 // wxMSW specific helpers
 // ----------------------------------------------------------------------------
 
+int wxChoice::GetVisibleHeight() const
+{
+    return ::SendMessage(GetHwnd(), CB_GETITEMHEIGHT, (WPARAM)-1, 0);
+}
+
 void wxChoice::DoMoveWindow(int x, int y, int width, int height)
 {
     // here is why this is necessary: if the width is negative, the combobox
@@ -385,29 +390,65 @@ void wxChoice::DoMoveWindow(int x, int y, int width, int height)
     wxControl::DoMoveWindow(x, y, width, height);
 }
 
+void wxChoice::DoGetSize(int *w, int *h) const
+{
+    wxControl::DoGetSize(w, h);
+
+    // we need to return only the height of the visible part, not the entire
+    // height in the Windows sense which includes the height of the drop down
+    // list as well
+    if ( h )
+        *h = GetVisibleHeight();
+}
+
 void wxChoice::DoSetSize(int x, int y,
-                         int width, int WXUNUSED(height),
+                         int width, int height,
                          int sizeFlags)
 {
-    // Ignore height parameter because height doesn't mean 'initially
-    // displayed' height, it refers to the drop-down menu as well. The
-    // wxWindows interpretation is different; also, getting the size returns
-    // the _displayed_ size (NOT the drop down menu size) so
-    // setting-getting-setting size would not work.
+    int heightOrig = height;
 
-    wxControl::DoSetSize(x, y, width, -1, sizeFlags);
+    // 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 != -1 )
+    {
+        // don't make the drop down list too tall, arbitrarily limit it to 40
+        // items max and also don't leave it empty
+        size_t nItems = GetCount();
+        if ( !nItems )
+            nItems = 9;
+        else if ( nItems > 39 )
+            nItems = 39;
+
+        // add space for the drop down list
+        const int hItem = SendMessage(GetHwnd(), CB_GETITEMHEIGHT, 0, 0);
+        height += hItem*(nItems + 1);
+    }
+
+    wxControl::DoSetSize(x, y, width, height, sizeFlags);
+
+    // if the height specified for the visible part of the control is
+    // different from the current one, we need to change it separately
+    // as it is not affected by normal WM_SETSIZE
+    if ( height != -1 )
+    {
+        const int hVisibleCurrent = GetVisibleHeight();
+        if ( hVisibleCurrent != heightOrig )
+        {
+            SendMessage(GetHwnd(), CB_SETITEMHEIGHT, (WPARAM)-1, heightOrig);
+        }
+    }
 }
 
 wxSize wxChoice::DoGetBestSize() const
 {
     // find the widest string
-    int wLine;
     int wChoice = 0;
-    int nItems = GetCount();
-    for ( int i = 0; i < nItems; i++ )
+    const size_t nItems = GetCount();
+    for ( size_t i = 0; i < nItems; i++ )
     {
-        wxString str(GetString(i));
-        GetTextExtent(str, &wLine, NULL);
+        int wLine;
+        GetTextExtent(GetString(i), &wLine, NULL);
         if ( wLine > wChoice )
             wChoice = wLine;
     }
@@ -417,17 +458,10 @@ wxSize wxChoice::DoGetBestSize() const
     if ( wChoice == 0 )
         wChoice = 100;
 
-    // the combobox should be larger than the widest string
-    int cx, cy;
-    wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
-
-    wChoice += 5*cx;
-
-    // Choice drop-down list depends on number of items (limited to 10)
-    size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1;
-    int hChoice = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)*nStrings;
+    // the combobox should be slightly larger than the widest string
+    wChoice += 5*GetCharWidth();
 
-    return wxSize(wChoice, hChoice);
+    return wxSize(wChoice, GetVisibleHeight());
 }
 
 long wxChoice::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)