diff --git a/include/wx/msw/tooltip.h b/include/wx/msw/tooltip.h index 39ffe0d6da..68ea492031 100644 --- a/include/wx/msw/tooltip.h +++ b/include/wx/msw/tooltip.h @@ -94,6 +94,9 @@ private: // remove this tooltip from the tooltip control void Remove(); + // adjust tooltip max width based on current tooltip text + bool AdjustMaxWidth(); + wxString m_text; // tooltip text wxWindow* m_window; // main window we're associated with wxToolTipOtherWindows *m_others; // other windows associated with it or NULL diff --git a/src/msw/tooltip.cpp b/src/msw/tooltip.cpp index 56aa27bad9..053080aaeb 100644 --- a/src/msw/tooltip.cpp +++ b/src/msw/tooltip.cpp @@ -406,6 +406,104 @@ void wxToolTip::DoAddHWND(WXHWND hWnd) } #ifdef TTM_SETMAXTIPWIDTH + if ( !AdjustMaxWidth() ) +#endif // TTM_SETMAXTIPWIDTH + { + // replace the '\n's with spaces because otherwise they appear as + // unprintable characters in the tooltip string + m_text.Replace(wxT("\n"), wxT(" ")); + ti.lpszText = wxMSW_CONV_LPTSTR(m_text); + + if ( !SendTooltipMessage(GetToolTipCtrl(), TTM_ADDTOOL, &ti) ) + { + wxLogDebug(wxT("Failed to create the tooltip '%s'"), m_text.c_str()); + } + } +} + +void wxToolTip::SetWindow(wxWindow *win) +{ + Remove(); + + m_window = win; + + // add the window itself + if ( m_window ) + { + DoAddHWND(m_window->GetHWND()); + } +#if !defined(__WXUNIVERSAL__) + // and all of its subcontrols (e.g. radio buttons in a radiobox) as well + wxControl *control = wxDynamicCast(m_window, wxControl); + if ( control ) + { + const wxArrayLong& subcontrols = control->GetSubcontrols(); + size_t count = subcontrols.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + int id = subcontrols[n]; + HWND hwnd = GetDlgItem(GetHwndOf(m_window), id); + if ( !hwnd ) + { + // maybe it's a child of parent of the control, in fact? + // (radiobuttons are subcontrols, i.e. children of the radiobox + // for wxWidgets but are its siblings at Windows level) + hwnd = GetDlgItem(GetHwndOf(m_window->GetParent()), id); + } + + // must have it by now! + wxASSERT_MSG( hwnd, wxT("no hwnd for subcontrol?") ); + + AddOtherWindow((WXHWND)hwnd); + } + } +#endif // !defined(__WXUNIVERSAL__) +} + +void wxToolTip::SetRect(const wxRect& rc) +{ + m_rect = rc; + + if ( m_window ) + { + wxToolInfo ti(GetHwndOf(m_window), m_id, m_rect); + (void)SendTooltipMessage(GetToolTipCtrl(), TTM_NEWTOOLRECT, &ti); + } +} + +void wxToolTip::SetTip(const wxString& tip) +{ + m_text = tip; + +#ifdef TTM_SETMAXTIPWIDTH + if ( !AdjustMaxWidth() ) +#endif // TTM_SETMAXTIPWIDTH + { + // replace the '\n's with spaces because otherwise they appear as + // unprintable characters in the tooltip string + m_text.Replace(wxT("\n"), wxT(" ")); + } + + DoForAllWindows(&wxToolTip::DoSetTip); +} + +void wxToolTip::DoSetTip(WXHWND hWnd) +{ + // update the tip text shown by the control + wxToolInfo ti((HWND)hWnd, m_id, m_rect); + + // for some reason, changing the tooltip text directly results in + // repaint of the controls under it, see #10520 -- but this doesn't + // happen if we reset it first + ti.lpszText = const_cast(wxT("")); + (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, &ti); + + ti.lpszText = wxMSW_CONV_LPTSTR(m_text); + (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, &ti); +} + +bool wxToolTip::AdjustMaxWidth() +{ if ( wxApp::GetComCtl32Version() >= 470 ) { // use TTM_SETMAXTIPWIDTH to make tooltip multiline using the @@ -476,92 +574,11 @@ void wxToolTip::DoAddHWND(WXHWND hWnd) SendTooltipMessage(GetToolTipCtrl(), TTM_SETMAXTIPWIDTH, wxUIntToPtr(maxWidth)); } + + return true; } - else -#endif // TTM_SETMAXTIPWIDTH - { - // replace the '\n's with spaces because otherwise they appear as - // unprintable characters in the tooltip string - m_text.Replace(wxT("\n"), wxT(" ")); - ti.lpszText = wxMSW_CONV_LPTSTR(m_text); - if ( !SendTooltipMessage(GetToolTipCtrl(), TTM_ADDTOOL, &ti) ) - { - wxLogDebug(wxT("Failed to create the tooltip '%s'"), m_text.c_str()); - } - } -} - -void wxToolTip::SetWindow(wxWindow *win) -{ - Remove(); - - m_window = win; - - // add the window itself - if ( m_window ) - { - DoAddHWND(m_window->GetHWND()); - } -#if !defined(__WXUNIVERSAL__) - // and all of its subcontrols (e.g. radio buttons in a radiobox) as well - wxControl *control = wxDynamicCast(m_window, wxControl); - if ( control ) - { - const wxArrayLong& subcontrols = control->GetSubcontrols(); - size_t count = subcontrols.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - int id = subcontrols[n]; - HWND hwnd = GetDlgItem(GetHwndOf(m_window), id); - if ( !hwnd ) - { - // maybe it's a child of parent of the control, in fact? - // (radiobuttons are subcontrols, i.e. children of the radiobox - // for wxWidgets but are its siblings at Windows level) - hwnd = GetDlgItem(GetHwndOf(m_window->GetParent()), id); - } - - // must have it by now! - wxASSERT_MSG( hwnd, wxT("no hwnd for subcontrol?") ); - - AddOtherWindow((WXHWND)hwnd); - } - } -#endif // !defined(__WXUNIVERSAL__) -} - -void wxToolTip::SetRect(const wxRect& rc) -{ - m_rect = rc; - - if ( m_window ) - { - wxToolInfo ti(GetHwndOf(m_window), m_id, m_rect); - (void)SendTooltipMessage(GetToolTipCtrl(), TTM_NEWTOOLRECT, &ti); - } -} - -void wxToolTip::SetTip(const wxString& tip) -{ - m_text = tip; - - DoForAllWindows(&wxToolTip::DoSetTip); -} - -void wxToolTip::DoSetTip(WXHWND hWnd) -{ - // update the tip text shown by the control - wxToolInfo ti((HWND)hWnd, m_id, m_rect); - - // for some reason, changing the tooltip text directly results in - // repaint of the controls under it, see #10520 -- but this doesn't - // happen if we reset it first - ti.lpszText = const_cast(wxT("")); - (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, &ti); - - ti.lpszText = wxMSW_CONV_LPTSTR(m_text); - (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, &ti); + return false; } void wxToolTip::DoForAllWindows(void (wxToolTip::*func)(WXHWND))