Recompute the tooltip width when changing its text in wxMSW.

This avoids unnecessarily wrapping the tooltips if they are set to a longer
string than their initial value later.

Closes #4685.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75756 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-02-01 18:18:47 +00:00
parent 7b1f4ba70a
commit 36e3a58992
2 changed files with 104 additions and 84 deletions

View File

@@ -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

View File

@@ -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<wxChar *>(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<wxChar *>(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))