X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/533171c2873027b260f7107451ab22992d9e3926..591cc82deb5bc6dd0af6047ecfa7ce7cf4f8d859:/src/msw/button.cpp diff --git a/src/msw/button.cpp b/src/msw/button.cpp index b342fbc0b2..ef43802277 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -72,6 +72,10 @@ #define ODS_NOFOCUSRECT 0x0200 #endif +#ifndef DT_HIDEPREFIX + #define DT_HIDEPREFIX 0x00100000 +#endif + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -137,14 +141,69 @@ wxCONSTRUCTOR_6( wxButton , wxWindow* , Parent , wxWindowID , Id , wxString , La IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl) #endif -// this macro tries to adjust the default button height to a reasonable value -// using the char height as the base -#define BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cy) (11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)/10) - // ============================================================================ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// helper functions from wx/msw/private/button.h +// ---------------------------------------------------------------------------- + +void wxMSWButton::UpdateMultilineStyle(HWND hwnd, const wxString& label) +{ + // update BS_MULTILINE style depending on the new label (resetting it + // doesn't seem to do anything very useful but it shouldn't hurt and we do + // have to set it whenever the label becomes multi line as otherwise it + // wouldn't be shown correctly as we don't use BS_MULTILINE when creating + // the control unless it already has new lines in its label) + long styleOld = ::GetWindowLong(hwnd, GWL_STYLE), + styleNew; + if ( label.find(_T('\n')) != wxString::npos ) + styleNew = styleOld | BS_MULTILINE; + else + styleNew = styleOld & ~BS_MULTILINE; + + if ( styleNew != styleOld ) + ::SetWindowLong(hwnd, GWL_STYLE, styleNew); +} + +wxSize wxMSWButton::GetFittingSize(wxWindow *win, const wxSize& sizeLabel) +{ + // FIXME: this is pure guesswork, need to retrieve the real button margins + wxSize sizeBtn = sizeLabel; + + sizeBtn.x += 3*win->GetCharWidth(); + sizeBtn.y = 11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(sizeLabel.y)/10; + + return sizeBtn; +} + +wxSize wxMSWButton::ComputeBestSize(wxControl *btn) +{ + wxClientDC dc(btn); + + wxSize sizeBtn; + dc.GetMultiLineTextExtent(btn->GetLabelText(), &sizeBtn.x, &sizeBtn.y); + + sizeBtn = GetFittingSize(btn, sizeBtn); + + // 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 + // creating the button + if ( !btn->HasFlag(wxBU_EXACTFIT) ) + { + wxSize sizeDef = wxButton::GetDefaultSize(); + if ( sizeBtn.x < sizeDef.x ) + sizeBtn.x = sizeDef.x; + if ( sizeBtn.y < sizeDef.y ) + sizeBtn.y = sizeDef.y; + } + + btn->CacheBestSize(sizeBtn); + + return sizeBtn; +} + // ---------------------------------------------------------------------------- // creation/destruction // ---------------------------------------------------------------------------- @@ -246,34 +305,7 @@ void wxButton::SetLabel(const wxString& label) wxSize wxButton::DoGetBestSize() const { - wxClientDC dc(wx_const_cast(wxButton *, this)); - dc.SetFont(GetFont()); - - wxCoord wBtn, - hBtn; - dc.GetMultiLineTextExtent(GetLabelText(), &wBtn, &hBtn); - - // add a margin -- the button is wider than just its label - 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 - // creating the button - if ( !HasFlag(wxBU_EXACTFIT) ) - { - wxSize sz = GetDefaultSize(); - if (wBtn > sz.x) - sz.x = wBtn; - if (hBtn > sz.y) - sz.y = hBtn; - - return sz; - } - - wxSize best(wBtn, hBtn); - CacheBestSize(best); - return best; + return wxMSWButton::ComputeBestSize(const_cast(this)); } /* static */ @@ -562,11 +594,15 @@ WXLRESULT wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) static void DrawButtonText(HDC hdc, RECT *pRect, const wxString& text, - COLORREF col) + COLORREF col, + int flags) { COLORREF colOld = SetTextColor(hdc, col); int modeOld = SetBkMode(hdc, TRANSPARENT); + // center text horizontally in any case + flags |= DT_CENTER; + if ( text.find(_T('\n')) != wxString::npos ) { // draw multiline label @@ -585,13 +621,14 @@ static void DrawButtonText(HDC hdc, rc.top = (pRect->bottom - pRect->top)/2 - h/2; rc.bottom = rc.top+h; - ::DrawText(hdc, text.wx_str(), text.length(), &rc, DT_CENTER); + ::DrawText(hdc, text.wx_str(), text.length(), &rc, flags); } else // single line label { - // Note: we must have DT_SINGLELINE for DT_VCENTER to work. + // centre text vertically too (notice that we must have DT_SINGLELINE + // for DT_VCENTER to work) ::DrawText(hdc, text.wx_str(), text.length(), pRect, - DT_SINGLELINE | DT_CENTER | DT_VCENTER); + flags | DT_SINGLELINE | DT_VCENTER); } SetBkMode(hdc, modeOld); @@ -870,13 +907,18 @@ bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis) } } - COLORREF colFg = wxColourToRGB(GetForegroundColour()); - if ( state & ODS_DISABLED ) colFg = GetSysColor(COLOR_GRAYTEXT) ; - wxString label = GetLabel(); - if ( state & ODS_NOACCEL ) label = GetLabelText() ; - DrawButtonText(hdc, &rectBtn, label, colFg); + COLORREF colFg = state & ODS_DISABLED + ? ::GetSysColor(COLOR_GRAYTEXT) + : wxColourToRGB(GetForegroundColour()); + + // notice that DT_HIDEPREFIX doesn't work on old (pre-Windows 2000) systems + // but by happy coincidence ODS_NOACCEL is not used under them neither so + // DT_HIDEPREFIX should never be used there + DrawButtonText(hdc, &rectBtn, GetLabel(), colFg, + state & ODS_NOACCEL ? DT_HIDEPREFIX : 0); return true; } #endif // wxUSE_BUTTON +