X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4b601a59b5f303a8866a18c90fff90aff393c6b7..b2edb8f3c524f302b727386bb0a694c44fb57e7d:/src/msw/button.cpp diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 67494356d6..407981a03a 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -44,6 +44,7 @@ #include "wx/msw/private.h" #include "wx/msw/private/button.h" #include "wx/msw/private/dc.h" +#include "wx/private/window.h" using namespace wxMSWImpl; @@ -102,6 +103,12 @@ using namespace wxMSWImpl; #define DT_HIDEPREFIX 0x00100000 #endif +// set the value for BCM_SETSHIELD (for the UAC shield) if it's not defined in +// the header +#ifndef BCM_SETSHIELD + #define BCM_SETSHIELD 0x160c +#endif + // ---------------------------------------------------------------------------- // button image data // ---------------------------------------------------------------------------- @@ -432,7 +439,9 @@ void wxMSWButton::UpdateMultilineStyle(HWND hwnd, const wxString& label) ::SetWindowLong(hwnd, GWL_STYLE, styleNew); } -wxSize wxMSWButton::GetFittingSize(wxWindow *win, const wxSize& sizeLabel) +wxSize wxMSWButton::GetFittingSize(wxWindow *win, + const wxSize& sizeLabel, + int flags) { // FIXME: this is pure guesswork, need to retrieve the real button margins wxSize sizeBtn = sizeLabel; @@ -440,24 +449,31 @@ wxSize wxMSWButton::GetFittingSize(wxWindow *win, const wxSize& sizeLabel) sizeBtn.x += 3*win->GetCharWidth(); sizeBtn.y = 11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(sizeLabel.y)/10; + // account for the shield UAC icon if we have it + if ( flags & Size_AuthNeeded ) + sizeBtn.x += wxSystemSettings::GetMetric(wxSYS_SMALLICON_X); + return sizeBtn; } -wxSize wxMSWButton::ComputeBestSize(wxControl *btn) +wxSize wxMSWButton::ComputeBestSize(wxControl *btn, int flags) { wxClientDC dc(btn); wxSize sizeBtn; dc.GetMultiLineTextExtent(btn->GetLabelText(), &sizeBtn.x, &sizeBtn.y); - sizeBtn = GetFittingSize(btn, sizeBtn); + sizeBtn = GetFittingSize(btn, sizeBtn, flags); // 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(); + // The size of a standard button in the dialog units is 50x14, use it. + // Note that we intentionally don't use GetDefaultSize() here, because + // it's inexact -- dialog units depend on this dialog's font. + wxSize sizeDef = btn->ConvertDialogToPixels(wxSize(50, 14)); if ( sizeBtn.x < sizeDef.x ) sizeBtn.x = sizeDef.x; if ( sizeBtn.y < sizeDef.y ) @@ -482,6 +498,8 @@ bool wxButton::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { + m_authNeeded = false; + wxString label(lbl); if (label.empty() && wxIsStockID(id)) { @@ -579,7 +597,11 @@ wxSize wxButton::DoGetBestSize() const // zero size) if ( ShowsLabel() || !m_imageData ) { - size = wxMSWButton::ComputeBestSize(const_cast(this)); + int flags = 0; + if ( GetAuthNeeded() ) + flags |= wxMSWButton::Size_AuthNeeded; + + size = wxMSWButton::ComputeBestSize(const_cast(this), flags); } if ( m_imageData ) @@ -659,16 +681,20 @@ wxSize wxButtonBase::GetDefaultSize() wxScreenDC dc; dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - // the size of a standard button in the dialog units is 50x14, - // translate this to pixels - // NB1: the multipliers come from the Windows convention - // NB2: the extra +1/+2 were needed to get the size be the same as the - // size of the buttons in the standard dialog - I don't know how - // this happens, but on my system this size is 75x23 in pixels and - // 23*8 isn't even divisible by 14... Would be nice to understand - // why these constants are needed though! - s_sizeBtn.x = (50 * (dc.GetCharWidth() + 1))/4; - s_sizeBtn.y = ((14 * dc.GetCharHeight()) + 2)/8; + // The size of a standard button in the dialog units is 50x14, + // translate this to pixels. + // + // Windows' computes dialog units using average character width over + // upper- and lower-case ASCII alphabet and not using the average + // character width metadata stored in the font; see + // http://support.microsoft.com/default.aspx/kb/145994 for detailed + // discussion. + // + // NB: wxMulDivInt32() is used, because it correctly rounds the result + + const wxSize base = wxPrivate::GetAverageASCIILetterSize(dc); + s_sizeBtn.x = wxMulDivInt32(50, base.x, 4); + s_sizeBtn.y = wxMulDivInt32(14, base.y, 8); } return s_sizeBtn; @@ -928,7 +954,7 @@ WXLRESULT wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) #if wxUSE_UXTHEME wxUxThemeEngine::GetIfActive() || #endif // wxUSE_UXTHEME - m_imageData && m_imageData->GetBitmap(State_Current).IsOk() + (m_imageData && m_imageData->GetBitmap(State_Current).IsOk()) ) ) { @@ -940,6 +966,26 @@ WXLRESULT wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) return wxControl::MSWWindowProc(nMsg, wParam, lParam); } +// ---------------------------------------------------------------------------- +// authentication needed handling +// ---------------------------------------------------------------------------- + +bool wxButton::DoGetAuthNeeded() const +{ + return m_authNeeded; +} + +void wxButton::DoSetAuthNeeded(bool show) +{ + // show/hide UAC symbol on Windows Vista and later + if ( wxGetWinVersion() >= wxWinVersion_6 ) + { + m_authNeeded = show; + ::SendMessage(GetHwnd(), BCM_SETSHIELD, 0, show); + InvalidateBestSize(); + } +} + // ---------------------------------------------------------------------------- // button images // ---------------------------------------------------------------------------- @@ -994,6 +1040,7 @@ void wxButton::DoSetBitmapMargins(wxCoord x, wxCoord y) wxCHECK_RET( m_imageData, "SetBitmap() must be called first" ); m_imageData->SetBitmapMargins(x, y); + InvalidateBestSize(); } void wxButton::DoSetBitmapPosition(wxDirection dir) @@ -1001,6 +1048,7 @@ void wxButton::DoSetBitmapPosition(wxDirection dir) wxCHECK_RET( m_imageData, "SetBitmap() must be called first" ); m_imageData->SetBitmapPosition(dir); + InvalidateBestSize(); } // ----------------------------------------------------------------------------