#include "wx/gdicmn.h"
class WXDLLIMPEXP_FWD_CORE wxWindow;
+class wxToolTipOtherWindows;
class WXDLLIMPEXP_CORE wxToolTip : public wxObject
{
// remove any tooltip from the window
static void Remove(WXHWND hwnd, unsigned int id, const wxRect& rc);
- // the rect we're associated with
+ // Set the rectangle we're associated with. This rectangle is only used for
+ // the main window, not any sub-windows added with Add() so in general it
+ // makes sense to use it for tooltips associated with a single window only.
void SetRect(const wxRect& rc);
- const wxRect& GetRect() const { return m_rect; }
private:
+ // Adds a window other than our main m_window to this tooltip.
+ void DoAddOtherWindow(WXHWND hWnd);
+
+ // Perform the specified operation for the given window only.
+ void DoSetTip(WXHWND hWnd);
+ void DoRemove(WXHWND hWnd);
+
+ // Call the given function for all windows we're associated with.
+ void DoForAllWindows(void (wxToolTip::*func)(WXHWND));
+
+
// the one and only one tooltip control we use - never access it directly
// but use GetToolTipCtrl() which will create it when needed
static WXHWND ms_hwndTT;
void Remove();
wxString m_text; // tooltip text
- wxWindow* m_window; // window we're associated with
+ wxWindow* m_window; // main window we're associated with
+ wxToolTipOtherWindows *m_others; // other windows associated with it or NULL
wxRect m_rect; // the rect of the window for which this tooltip is shown
// (or a rect with width/height == 0 to show it for the entire window)
unsigned int m_id; // the id of this tooltip (ignored when m_rect width/height is 0)
#endif
#include "wx/tokenzr.h"
+#include "wx/vector.h"
#include "wx/msw/private.h"
#ifndef TTTOOLINFO_V1_SIZE
// private classes
// ----------------------------------------------------------------------------
+// This is simply a wrapper for vector<HWND> but defined as a class to hide the
+// details from the public header.
+class wxToolTipOtherWindows : public wxVector<WXHWND>
+{
+};
+
// a wrapper around TOOLINFO Win32 structure
#ifdef __VISUALC__
#pragma warning( disable : 4097 ) // we inherit from a typedef - so what?
: m_text(tip)
{
m_window = NULL;
+ m_others = NULL;
// make sure m_rect.IsEmpty() == true
m_rect.SetWidth(0);
: m_text(tip), m_rect(rc), m_id(id)
{
m_window = NULL;
+ m_others = NULL;
SetWindow(win);
}
// the tooltip has to be removed before deleting. Otherwise, if it is visible
// while being deleted, there will be a delay before it goes away.
Remove();
+
+ delete m_others;
}
// ----------------------------------------------------------------------------
(void)SendTooltipMessage(GetToolTipCtrl(), TTM_DELTOOL, &ti);
}
-void wxToolTip::Remove()
+void wxToolTip::DoRemove(WXHWND hWnd)
{
- // remove this tool from the tooltip control
- if ( m_window )
+ if ( hWnd == m_window->GetHWND() )
+ {
+ // Remove the tooltip from the main window.
+ Remove(hWnd, m_id, m_rect);
+ }
+ else
{
- Remove(m_window->GetHWND(), m_id, m_rect);
+ // Not really sure what to pass to remove in this case...
+ Remove(hWnd, 0, wxRect());
}
}
+void wxToolTip::Remove()
+{
+ DoForAllWindows(&wxToolTip::DoRemove);
+}
+
void wxToolTip::Add(WXHWND hWnd)
+{
+ if ( !m_others )
+ m_others = new wxToolTipOtherWindows;
+
+ m_others->push_back(hWnd);
+
+ DoAddOtherWindow(hWnd);
+}
+
+void wxToolTip::DoAddOtherWindow(WXHWND hWnd)
{
HWND hwnd = (HWND)hWnd;
HWND hwnd = GetDlgItem(GetHwndOf(m_window), id);
if ( !hwnd )
{
- // may be it's a child of parent of the control, in fact?
+ // 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);
{
m_text = tip;
- if ( m_window )
+ 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 = const_cast<wxChar *>(m_text.wx_str());
+ (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, &ti);
+}
+
+void wxToolTip::DoForAllWindows(void (wxToolTip::*func)(WXHWND))
+{
+ if ( !m_window )
{
- // update the tip text shown by the control
- wxToolInfo ti(GetHwndOf(m_window), m_id, m_rect);
+ wxASSERT_MSG( !m_others,
+ wxS("Can't have other windows without the main one.") );
+ return;
+ }
- // 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);
+ (this->*func)(m_window->GetHWND());
- ti.lpszText = const_cast<wxChar *>(m_text.wx_str());
- (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, &ti);
+ if ( m_others )
+ {
+ for ( wxToolTipOtherWindows::const_iterator it = m_others->begin();
+ it != m_others->end();
+ ++it )
+ {
+ (this->*func)(*it);
+ }
}
}