From f4bdf2b32412bb7688b35e4c70c17525c9a5d335 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 8 Mar 2014 14:33:29 +0000 Subject: [PATCH] Fix handling of controls in vertical toolbars in wxMSW. Not adding the controls to vertical toolbar is not enough, we also need to hide them to prevent them from being shown as independent floating windows. And we also need to add separators instead of the controls themselves to keep the indices the same as in the horizontal case. Closes #11821. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@76098 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + src/msw/toolbar.cpp | 56 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 37b6e35682..7cdd7926a1 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -638,6 +638,7 @@ wxMSW: - Fix crash when adding/removing the same path to/from wxFileSystemWatcher. - Draw "classic" disabled owner drawn buttons better (Artur Wieczorek). - Fix width of the vertical toolbars (Artur Wieczorek). +- Fix handling of controls in the vertical toolbars (Artur Wieczorek). - Fix loading of top to bottom BMP files in wxBitmap (Artur Wieczorek). wxOSX: diff --git a/src/msw/toolbar.cpp b/src/msw/toolbar.cpp index f7f347ea25..00cd5d7d50 100644 --- a/src/msw/toolbar.cpp +++ b/src/msw/toolbar.cpp @@ -244,11 +244,12 @@ private: // helper functions // ---------------------------------------------------------------------------- -// return the rectangle of the item at the given index +// Return the rectangle of the item at the given index and, if specified, with +// the given id. // -// returns an empty (0, 0, 0, 0) rectangle if fails so the caller may compare -// r.right or r.bottom with 0 to check for this -static RECT wxGetTBItemRect(HWND hwnd, int index) +// Returns an empty (0, 0, 0, 0) rectangle if fails so the caller may compare +// r.right or r.bottom with 0 to check for this. +static RECT wxGetTBItemRect(HWND hwnd, int index, int id = wxID_NONE) { RECT r; @@ -256,12 +257,34 @@ static RECT wxGetTBItemRect(HWND hwnd, int index) // only appeared in v4.70 of comctl32.dll if ( !::SendMessage(hwnd, TB_GETITEMRECT, index, (LPARAM)&r) ) { - wxLogLastError(wxT("TB_GETITEMRECT")); + // This call can return false status even when there is no real error, + // e.g. for a hidden button, so check for this to avoid spurious logs. + const DWORD err = ::GetLastError(); + if ( err != ERROR_SUCCESS ) + { + bool reportError = true; - r.top = - r.left = - r.right = - r.bottom = 0; + if ( id != wxID_NONE ) + { + const LRESULT state = ::SendMessage(hwnd, TB_GETSTATE, id, 0); + if ( state != -1 && (state & TBSTATE_HIDDEN) ) + { + // There is no real error to report after all. + reportError = false; + } + else // It is not hidden. + { + // So it must have been a real error, report it with the + // original error code and not the one from TB_GETSTATE. + ::SetLastError(err); + } + } + + if ( reportError ) + wxLogLastError(wxT("TB_GETITEMRECT")); + } + + ::SetRectEmpty(&r); } return r; @@ -988,7 +1011,14 @@ bool wxToolBar::Realize() } button.idCommand = tool->GetId(); - button.fsState = TBSTATE_ENABLED; + + // We don't embed controls in the vertical toolbar but for + // every control there must exist a corresponding button to + // keep indexes the same as in the horizontal case. + if ( IsVertical() && tool->IsControl() ) + button.fsState = TBSTATE_HIDDEN; + else + button.fsState = TBSTATE_ENABLED; button.fsStyle = TBSTYLE_SEP; break; @@ -1102,7 +1132,7 @@ bool wxToolBar::Realize() { wxToolBarTool * const tool = (wxToolBarTool*)node->GetData(); - const RECT r = wxGetTBItemRect(GetHwnd(), toolIndex); + const RECT r = wxGetTBItemRect(GetHwnd(), toolIndex, tool->GetId()); if ( !tool->IsControl() ) { @@ -1114,15 +1144,17 @@ bool wxToolBar::Realize() continue; } + wxControl * const control = tool->GetControl(); if ( IsVertical() ) { // don't embed controls in the vertical toolbar, this doesn't look // good and wxGTK doesn't do it neither (and the code below can't // deal with this case) + control->Hide(); continue; } - wxControl * const control = tool->GetControl(); + control->Show(); wxStaticText * const staticText = tool->GetStaticText(); wxSize size = control->GetSize();