X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/77ffb5937e89927b621128789401db8921fe580f..ccdc11bbaf0310a474ad7b9d41413b31c3544356:/src/msw/button.cpp diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 7ec5cbb742..ad0fbede21 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: msw/button.cpp +// Name: src/msw/button.cpp // Purpose: wxButton // Author: Julian Smart // Modified by: // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWidgets licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -17,10 +17,6 @@ // 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" @@ -30,16 +26,20 @@ #if wxUSE_BUTTON +#include "wx/button.h" + #ifndef WX_PRECOMP #include "wx/app.h" - #include "wx/button.h" #include "wx/brush.h" #include "wx/panel.h" #include "wx/bmpbuttn.h" #include "wx/settings.h" #include "wx/dcscreen.h" + #include "wx/dcclient.h" #endif +#include "wx/stockitem.h" +#include "wx/tokenzr.h" #include "wx/msw/private.h" // ---------------------------------------------------------------------------- @@ -59,7 +59,7 @@ wxBEGIN_FLAGS( wxButtonStyle ) wxFLAGS_MEMBER(wxBORDER_RAISED) wxFLAGS_MEMBER(wxBORDER_STATIC) wxFLAGS_MEMBER(wxBORDER_NONE) - + // old style border flags wxFLAGS_MEMBER(wxSIMPLE_BORDER) wxFLAGS_MEMBER(wxSUNKEN_BORDER) @@ -88,10 +88,10 @@ wxEND_FLAGS( wxButtonStyle ) IMPLEMENT_DYNAMIC_CLASS_XTI(wxButton, wxControl,"wx/button.h") wxBEGIN_PROPERTIES_TABLE(wxButton) - wxEVENT_PROPERTY( Click , wxEVT_COMMAND_BUTTON_CLICKED , wxCommandEvent) + wxEVENT_PROPERTY( Click , wxEVT_COMMAND_BUTTON_CLICKED , wxCommandEvent) - wxPROPERTY( Font , wxFont , SetFont , GetFont , EMPTY_MACROVALUE, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) - wxPROPERTY( Label, wxString , SetLabel, GetLabel, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) + wxPROPERTY( Font , wxFont , SetFont , GetFont , EMPTY_MACROVALUE, 0 /*flags*/ , wxT("Helpstring") , wxT("group")) + wxPROPERTY( Label, wxString , SetLabel, GetLabel, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) wxPROPERTY_FLAGS( WindowStyle , wxButtonStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style @@ -121,15 +121,30 @@ IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl) bool wxButton::Create(wxWindow *parent, wxWindowID id, - const wxString& label, + const wxString& lbl, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name) { + wxString label(lbl); + if (label.empty() && wxIsStockID(id)) + { + // On Windows, some buttons aren't supposed to have + // mnemonics, so strip them out. + + label = wxGetStockLabel(id +#if defined(__WXMSW__) || defined(__WXWINCE__) + , ( id != wxID_OK && + id != wxID_CANCEL && + id != wxID_CLOSE ) +#endif + ); + } + if ( !CreateControl(parent, id, pos, size, style, validator, name) ) - return FALSE; + return false; WXDWORD exstyle; WXDWORD msStyle = MSWGetStyle(style, &exstyle); @@ -199,17 +214,16 @@ WXDWORD wxButton::MSWGetStyle(long style, WXDWORD *exstyle) const wxSize wxButton::DoGetBestSize() const { - int wBtn; - GetTextExtent(wxGetWindowText(GetHWND()), &wBtn, NULL); + wxClientDC dc(wx_const_cast(wxButton *, this)); + dc.SetFont(GetFont()); - int wChar, hChar; - wxGetCharSize(GetHWND(), &wChar, &hChar, &GetFont()); + wxCoord wBtn, + hBtn; + dc.GetMultiLineTextExtent(wxStripMenuCodes(GetLabel()), &wBtn, &hBtn); // add a margin -- the button is wider than just its label - wBtn += 3*wChar; - - // the button height is proportional to the height of the font used - int hBtn = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(hChar); + 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 @@ -225,7 +239,9 @@ wxSize wxButton::DoGetBestSize() const return sz; } - return wxSize(wBtn, hBtn); + wxSize best(wBtn, hBtn); + CacheBestSize(best); + return best; } /* static */ @@ -302,8 +318,8 @@ void wxButton::SetDefault() wxWindow *winOldDefault = parent->SetDefaultItem(this); // ... and Windows - SetDefaultStyle(wxDynamicCast(winOldDefault, wxButton), FALSE); - SetDefaultStyle(this, TRUE); + SetDefaultStyle(wxDynamicCast(winOldDefault, wxButton), false); + SetDefaultStyle(this, true); } // set this button as being currently default @@ -316,8 +332,8 @@ void wxButton::SetTmpDefault() wxWindow *winOldDefault = parent->GetDefaultItem(); parent->SetTmpDefaultItem(this); - SetDefaultStyle(wxDynamicCast(winOldDefault, wxButton), FALSE); - SetDefaultStyle(this, TRUE); + SetDefaultStyle(wxDynamicCast(winOldDefault, wxButton), false); + SetDefaultStyle(this, true); } // unset this button as currently default, it may still stay permanent default @@ -331,8 +347,8 @@ void wxButton::UnsetTmpDefault() wxWindow *winOldDefault = parent->GetDefaultItem(); - SetDefaultStyle(this, FALSE); - SetDefaultStyle(wxDynamicCast(winOldDefault, wxButton), TRUE); + SetDefaultStyle(this, false); + SetDefaultStyle(wxDynamicCast(winOldDefault, wxButton), true); } /* static */ @@ -413,12 +429,12 @@ void wxButton::Command(wxCommandEvent & event) bool wxButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) { - bool processed = FALSE; + bool processed = false; switch ( param ) { // NOTE: Apparently older versions (NT 4?) of the common controls send // BN_DOUBLECLICKED but not a second BN_CLICKED for owner-drawn - // buttons, so in order to send two EVET_BUTTON events we should + // buttons, so in order to send two EVT_BUTTON events we should // catch both types. Currently (Feb 2003) up-to-date versions of // win98, win2k and winXP all send two BN_CLICKED messages for // all button types, so we don't catch BN_DOUBLECLICKED anymore @@ -437,7 +453,7 @@ bool wxButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) WXLRESULT wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { - // when we receive focus, we want to temporary become the default button in + // when we receive focus, we want to temporarily become the default button in // our parent panel so that pressing "Enter" would activate us -- and when // losing it we should restore the previous default button as well if ( nMsg == WM_SETFOCUS ) @@ -479,8 +495,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); @@ -510,14 +549,14 @@ bool wxButton::SetBackgroundColour(const wxColour &colour) if ( !wxControl::SetBackgroundColour(colour) ) { // nothing to do - return FALSE; + return false; } MakeOwnerDrawn(); Refresh(); - return TRUE; + return true; } bool wxButton::SetForegroundColour(const wxColour &colour) @@ -525,14 +564,14 @@ bool wxButton::SetForegroundColour(const wxColour &colour) if ( !wxControl::SetForegroundColour(colour) ) { // nothing to do - return FALSE; + return false; } MakeOwnerDrawn(); Refresh(); - return TRUE; + return true; } /* @@ -592,7 +631,7 @@ static void DrawButtonFrame(HDC hdc, const RECT& rectBtn, DrawRect(hdc, r); (void)SelectObject(hdc, hpenGrey); - InflateRect(&r, -1, -1); + ::InflateRect(&r, -1, -1); DrawRect(hdc, r); } @@ -602,7 +641,7 @@ static void DrawButtonFrame(HDC hdc, const RECT& rectBtn, { DrawRect(hdc, r); - InflateRect(&r, -1, -1); + ::InflateRect(&r, -1, -1); } wxDrawLine(hdc, r.left, r.bottom, r.right, r.bottom); @@ -685,10 +724,9 @@ bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis) ::DeleteObject(hbrushBackground); - return TRUE; + return true; } #endif // __WIN32__ #endif // wxUSE_BUTTON -