1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/tooltip.cpp
3 // Purpose: wxToolTip class implementation for MSW
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1999 Vadim Zeitlin
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
32 #include "wx/tooltip.h"
33 #include "wx/msw/private.h"
35 #if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__)
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 // a simple wrapper around TOOLINFO Win32 structure
44 class wxToolInfo
: public TOOLINFO
47 wxToolInfo(wxWindow
*win
)
49 // initialize all members
50 ::ZeroMemory(this, sizeof(TOOLINFO
));
52 cbSize
= sizeof(TOOLINFO
);
53 uFlags
= TTF_IDISHWND
;
54 uId
= (UINT
)win
->GetHWND();
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 // send a message to the tooltip control
63 inline LRESULT
SendTooltipMessage(WXHWND hwnd
,
68 return hwnd ?
::SendMessage((HWND
)hwnd
, msg
, wParam
, (LPARAM
)lParam
)
72 // send a message to all existing tooltip controls
73 static void SendTooltipMessageToAll(UINT msg
, WPARAM wParam
, LPARAM lParam
)
75 // NB: it might be somewhat easier to maintain a list of all existing
76 // wxToolTip controls (put them there in ctor, delete from the list
77 // in dtor) - may be it's worth doing it this way? OTOH, typical
78 // application won't have many top level windows, so iterating over all
79 // of them shouldnt' take much time neither...
81 // iterate over all top level windows and send message to the tooltip
82 // control of each and every of them (or more precisely to all dialogs and
84 wxDialog
*dialog
= NULL
;
85 wxFrame
*frame
= NULL
;
87 wxNode
*node
= wxTopLevelWindows
.First();
90 wxWindow
*win
= (wxWindow
*)node
->Data();
94 if ( win
->IsKindOf(CLASSINFO(wxFrame
)) )
96 frame
= (wxFrame
*)win
;
99 else if ( win
->IsKindOf(CLASSINFO(wxDialog
)) )
101 dialog
= (wxDialog
*)win
;
106 // skip this strange top level window
110 wxASSERT_MSG( dialog
|| frame
, "logic error" );
112 WXHWND hwndTT
= frame ? frame
->GetToolTipCtrl()
113 : dialog
->GetToolTipCtrl();
116 (void)SendTooltipMessage(hwndTT
, msg
, wParam
, (void *)lParam
);
121 // ============================================================================
123 // ============================================================================
125 // ----------------------------------------------------------------------------
127 // ----------------------------------------------------------------------------
129 void wxToolTip
::Enable(bool flag
)
131 SendTooltipMessageToAll(TTM_ACTIVATE
, flag
, 0);
134 void wxToolTip
::SetDelay(long milliseconds
)
136 SendTooltipMessageToAll(TTM_SETDELAYTIME
, TTDT_INITIAL
, milliseconds
);
139 // ---------------------------------------------------------------------------
140 // implementation helpers
141 // ---------------------------------------------------------------------------
143 // create the tooltip ctrl for our parent frame if it doesn't exist yet
144 WXHWND wxToolTip
::GetToolTipCtrl()
146 // find either parent dialog or parent frame - tooltip controls are managed
147 // by these 2 classes only (it doesn't make sense to create one tooltip per
148 // each and every wxWindow)
149 wxFrame
*frame
= NULL
;
150 wxDialog
*dialog
= NULL
;
152 wxWindow
*parent
= m_window
;
155 if ( parent
->IsKindOf(CLASSINFO(wxFrame
)) )
157 frame
= (wxFrame
*)parent
;
161 else if ( parent
->IsKindOf(CLASSINFO(wxDialog
)) )
163 dialog
= (wxDialog
*)parent
;
168 parent
= parent
->GetParent();
171 wxCHECK_MSG( frame
|| dialog
, 0,
172 "can't create tooltip control outside a frame or a dialog" );
174 HWND hwndTT
= (HWND
)(frame ? frame
->GetToolTipCtrl()
175 : dialog
->GetToolTipCtrl());
178 hwndTT
= ::CreateWindow(TOOLTIPS_CLASS
,
181 CW_USEDEFAULT
, CW_USEDEFAULT
,
182 CW_USEDEFAULT
, CW_USEDEFAULT
,
183 (HWND
)frame
->GetHWND(), (HMENU
)NULL
,
184 wxGetInstance(), NULL
);
189 frame
->SetToolTipCtrl((WXHWND
)hwndTT
);
191 dialog
->SetToolTipCtrl((WXHWND
)hwndTT
);
195 wxLogSysError(_("Can not create tooltip control"));
199 return (WXHWND
)hwndTT
;
202 void wxToolTip
::RelayEvent(WXMSG
*msg
)
204 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_RELAYEVENT
, 0, msg
);
207 // ----------------------------------------------------------------------------
209 // ----------------------------------------------------------------------------
211 wxToolTip
::wxToolTip(const wxString
&tip
)
217 wxToolTip
::~wxToolTip()
219 // there is no need to Remove() this tool - it will be done automatically
223 // ----------------------------------------------------------------------------
225 // ----------------------------------------------------------------------------
227 void wxToolTip
::Remove()
229 // remove this tool from the tooltip control
232 wxToolInfo
ti(m_window
);
233 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_DELTOOL
, 0, &ti
);
237 void wxToolTip
::SetWindow(wxWindow
*win
)
245 wxToolInfo
ti(m_window
);
247 // as we store our text anyhow, it seems useless to waste system memory
248 // by asking the tooltip ctrl to remember it too - instead it will send
249 // us TTN_NEEDTEXT (via WM_NOTIFY) when it is about to be shown
250 ti
.hwnd
= (HWND
)m_window
->GetHWND();
251 ti
.lpszText
= LPSTR_TEXTCALLBACK
;
252 // instead of: ti.lpszText = (char *)m_text.c_str();
254 if ( !SendTooltipMessage(GetToolTipCtrl(), TTM_ADDTOOL
, 0, &ti
) )
256 wxLogSysError(_("Failed to create the tooltip '%s'"),
262 void wxToolTip
::SetTip(const wxString
& tip
)
268 // update it immediately
269 wxToolInfo
ti(m_window
);
270 ti
.lpszText
= (char *)m_text
.c_str();
272 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT
, 0, &ti
);
276 #endif // wxUSE_TOOLTIPS