From f2d7fdf7b0a57a7e0bf033530148343751b5346b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 8 Feb 2010 19:52:00 +0000 Subject: [PATCH] Add support for showing "elevation" icon in wxMSW buttons. Add, document and test in the widgets sample wxButton::SetAuthNeeded(). Closes #11705. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63421 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/button.h | 9 +++++++ include/wx/msw/button.h | 5 ++++ include/wx/msw/private/button.h | 10 +++++-- interface/wx/button.h | 26 +++++++++++++++++++ samples/widgets/button.cpp | 11 +++++--- src/msw/button.cpp | 46 ++++++++++++++++++++++++++++++--- 7 files changed, 99 insertions(+), 9 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 573305c573..9909d54328 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -522,6 +522,7 @@ MSW: - Suppressed spurious character event for decimal key in numeric keypad. - Allow to not create wxPaintDC in EVT_PAINT handler. - Fix sending of wxEVT_COMMAND_LIST_COL_DRAGGING events in wxListCtrl. +- Allow putting the UAC symbol on buttons (Chris Spencer). i18n: diff --git a/include/wx/button.h b/include/wx/button.h index dfcf6610da..b6827dc002 100644 --- a/include/wx/button.h +++ b/include/wx/button.h @@ -64,6 +64,12 @@ class WXDLLIMPEXP_CORE wxButtonBase : public wxControl public: wxButtonBase() { } + // show the authentication needed symbol on the button: this is currently + // only implemented on Windows Vista and newer (on which it shows the UAC + // shield symbol) + void SetAuthNeeded(bool show = true) { DoSetAuthNeeded(show); } + bool GetAuthNeeded() const { return DoGetAuthNeeded(); } + // show the image in the button in addition to the label: this method is // supported on all (major) platforms void SetBitmap(const wxBitmap& bitmap, wxDirection dir = wxLEFT) @@ -170,6 +176,9 @@ protected: // choose the default border for this window virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; } + virtual bool DoGetAuthNeeded() const { return false; } + virtual void DoSetAuthNeeded(bool WXUNUSED(show)) { } + virtual wxBitmap DoGetBitmap(State WXUNUSED(which)) const { return wxBitmap(); } virtual void DoSetBitmap(const wxBitmap& WXUNUSED(bitmap), diff --git a/include/wx/msw/button.h b/include/wx/msw/button.h index 52ca818cbe..e1de60c2d6 100644 --- a/include/wx/msw/button.h +++ b/include/wx/msw/button.h @@ -80,6 +80,8 @@ protected: // usually overridden base class virtuals virtual wxSize DoGetBestSize() const; + virtual bool DoGetAuthNeeded() const; + virtual void DoSetAuthNeeded(bool show); virtual wxBitmap DoGetBitmap(State which) const; virtual void DoSetBitmap(const wxBitmap& bitmap, State which); virtual wxSize DoGetBitmapMargins() const; @@ -88,6 +90,9 @@ protected: class wxButtonImageData *m_imageData; + // true if the UAC symbol is shown + bool m_authNeeded; + private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxButton) }; diff --git a/include/wx/msw/private/button.h b/include/wx/msw/private/button.h index 7d006f747a..03be993bc0 100644 --- a/include/wx/msw/private/button.h +++ b/include/wx/msw/private/button.h @@ -45,13 +45,19 @@ inline int GetMultilineStyle(const wxString& label) // depending on whether the label contains the new lines void UpdateMultilineStyle(HWND hwnd, const wxString& label); +// flags for ComputeBestSize() and GetFittingSize() +enum +{ + Size_AuthNeeded = 1 +}; + // common implementation of wxButton and wxToggleButton::DoGetBestSize() // (implemented in src/msw/button.cpp) -wxSize ComputeBestSize(wxControl *btn); +wxSize ComputeBestSize(wxControl *btn, int flags = 0); // compute the button size (as if wxBU_EXACTFIT were specified, i.e. without // adjusting it to be of default size if it's smaller) for the given label size -wxSize GetFittingSize(wxWindow *win, const wxSize& sizeLabel); +wxSize GetFittingSize(wxWindow *win, const wxSize& sizeLabel, int flags = 0); } // namespace wxMSWButton diff --git a/interface/wx/button.h b/interface/wx/button.h index 5669cfc7bc..4027c9aef1 100644 --- a/interface/wx/button.h +++ b/interface/wx/button.h @@ -146,6 +146,19 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxButtonNameStr); + /** + Returns @true if an authentication needed symbol is displayed on the + button. + + @remarks This method always returns @false if the platform is not + Windows Vista or newer. + + @see SetAuthNeeded() + + @since 2.9.1 + */ + bool GetAuthNeeded() const; + /** Return the bitmap shown by the button. @@ -223,6 +236,19 @@ public: */ wxString GetLabel() const; + /** + Sets whether an authentication needed symbol should be displayed on the + button. + + @remarks This method doesn't do anything if the platform is not Windows + Vista or newer. + + @see GetAuthNeeded() + + @since 2.9.1 + */ + void SetAuthNeeded(bool needed = true); + /** Sets the bitmap to display in the button. diff --git a/samples/widgets/button.cpp b/samples/widgets/button.cpp index 61b118ae0e..af70f76ea0 100644 --- a/samples/widgets/button.cpp +++ b/samples/widgets/button.cpp @@ -124,6 +124,7 @@ protected: wxCheckBox *m_chkBitmapOnly, *m_chkTextAndBitmap, *m_chkFit, + *m_chkAuthNeeded, *m_chkDefault; // more checkboxes for wxBitmapButton only @@ -184,6 +185,7 @@ ButtonWidgetsPage::ButtonWidgetsPage(WidgetsBookCtrl *book, m_chkBitmapOnly = m_chkTextAndBitmap = m_chkFit = + m_chkAuthNeeded = m_chkDefault = m_chkUsePressed = m_chkUseFocused = @@ -210,8 +212,9 @@ void ButtonWidgetsPage::CreateContent() wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL); m_chkBitmapOnly = CreateCheckBoxAndAddToSizer(sizerLeft, "&Bitmap only"); - m_chkTextAndBitmap = CreateCheckBoxAndAddToSizer(sizerLeft, "Text &and &bitmap"); + m_chkTextAndBitmap = CreateCheckBoxAndAddToSizer(sizerLeft, "Text &and bitmap"); m_chkFit = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Fit exactly")); + m_chkAuthNeeded = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("Require a&uth")); m_chkDefault = CreateCheckBoxAndAddToSizer(sizerLeft, wxT("&Default")); sizerLeft->AddSpacer(5); @@ -307,6 +310,7 @@ void ButtonWidgetsPage::Reset() { m_chkBitmapOnly->SetValue(false); m_chkFit->SetValue(true); + m_chkAuthNeeded->SetValue(false); m_chkTextAndBitmap->SetValue(false); m_chkDefault->SetValue(false); @@ -432,10 +436,11 @@ void ButtonWidgetsPage::CreateButton() m_chkUseCurrent->Enable(showsBitmap); m_chkUseDisabled->Enable(showsBitmap); + if ( m_chkAuthNeeded->GetValue() ) + m_button->SetAuthNeeded(); + if ( m_chkDefault->GetValue() ) - { m_button->SetDefault(); - } AddButtonToSizer(); diff --git a/src/msw/button.cpp b/src/msw/button.cpp index 2f68d8b362..2d71a51c29 100644 --- a/src/msw/button.cpp +++ b/src/msw/button.cpp @@ -103,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 // ---------------------------------------------------------------------------- @@ -433,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; @@ -441,17 +449,21 @@ 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 @@ -486,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)) { @@ -583,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 ) @@ -948,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 // ---------------------------------------------------------------------------- -- 2.45.2