]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/button.cpp
make the string properly 0 terminated and allow for one char more on the output buffer
[wxWidgets.git] / src / msw / button.cpp
index 0c07934f056f5acf6c67f4b1da73e0442da3fafe..6b6f67aa651b4d7350a33a91949ee7df7ba7cafa 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "button.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -38,6 +34,7 @@
     #include "wx/bmpbuttn.h"
     #include "wx/settings.h"
     #include "wx/dcscreen.h"
+    #include "wx/dcclient.h"
 #endif
 
 #include "wx/stockitem.h"
@@ -216,38 +213,16 @@ WXDWORD wxButton::MSWGetStyle(long style, WXDWORD *exstyle) const
 
 wxSize wxButton::DoGetBestSize() const
 {
-    int wBtn = 0;
-    int wChar, hChar, hBtn;
-    wxGetCharSize(GetHWND(), &wChar, &hChar, GetFont());
-
-    wxString label = wxGetWindowText(GetHWND());
-    if ( label.find(_T('\n')) != wxString::npos )
-    {
-        wxStringTokenizer tokens( label, wxT("\n") );
+    wxClientDC dc(wx_const_cast(wxButton *, this));
+    dc.SetFont(GetFont());
 
-        // the button height is proportional to the height of the font used
-        hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hChar);
-        hBtn += hChar*(tokens.CountTokens()-1);
-        
-        while (tokens.HasMoreTokens())
-        {
-            wxString sub = tokens.GetNextToken();
-            int w;
-            GetTextExtent( sub, &w, NULL);
-            if (w > wBtn)
-                wBtn = w;
-        }
-    }
-    else
-    {
-        GetTextExtent( label, &wBtn, NULL);
+    wxCoord wBtn,
+            hBtn;
+    dc.GetMultiLineTextExtent(wxStripMenuCodes(GetLabel()), &wBtn, &hBtn);
 
-        // the button height is proportional to the height of the font used
-        hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hChar);
-    }
-    
     // add a margin -- the button is wider than just its label
-    wBtn += 3*wChar;
+    wBtn += 3*GetCharWidth();
+    hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hBtn);
 
     // all buttons have at least the standard size unless the user explicitly
     // wants them to be of smaller size and used wxBU_EXACTFIT style when
@@ -263,7 +238,9 @@ wxSize wxButton::DoGetBestSize() const
         return sz;
     }
 
-    return wxSize(wBtn, hBtn);
+    wxSize best(wBtn, hBtn);
+    CacheBestSize(best);
+    return best;
 }
 
 /* static */
@@ -517,8 +494,31 @@ static void DrawButtonText(HDC hdc,
     COLORREF colOld = SetTextColor(hdc, col);
     int modeOld = SetBkMode(hdc, TRANSPARENT);
 
-    // Note: we must have DT_SINGLELINE for DT_VCENTER to work.
-    ::DrawText(hdc, text, text.length(), pRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+    if ( text.find(_T('\n')) != wxString::npos )
+    {
+        // draw multiline label
+
+        // first we need to compute its bounding rect
+        RECT rc;
+        ::CopyRect(&rc, pRect);
+        ::DrawText(hdc, text, text.length(), &rc, DT_CENTER | DT_CALCRECT);
+
+        // now center this rect inside the entire button area
+        const LONG w = rc.right - rc.left;
+        const LONG h = rc.bottom - rc.top;
+        rc.left = (pRect->right - pRect->left)/2 - w/2;
+        rc.right = rc.left+w;
+        rc.top = (pRect->bottom - pRect->top)/2 - h/2;
+        rc.bottom = rc.top+h;
+
+        ::DrawText(hdc, text, text.length(), &rc, DT_CENTER);
+    }
+    else // single line label
+    {
+        // Note: we must have DT_SINGLELINE for DT_VCENTER to work.
+        ::DrawText(hdc, text, text.length(), pRect,
+                   DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+    }
 
     SetBkMode(hdc, modeOld);
     SetTextColor(hdc, colOld);