set tooltip to be TOPMOST
[wxWidgets.git] / src / msw / tooltip.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/tooltip.cpp
3 // Purpose: wxToolTip class implementation for MSW
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 31.01.99
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Vadim Zeitlin
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/wx.h"
28 #endif
29
30 #if wxUSE_TOOLTIPS
31
32 #include "wx/tooltip.h"
33 #include "wx/msw/private.h"
34
35 #if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__) || defined(wxUSE_NORLANDER_HEADERS)
36 #include <commctrl.h>
37 #endif
38
39 WXHWND wxToolTip::hwndTT = NULL;
40
41 // ----------------------------------------------------------------------------
42 // private classes
43 // ----------------------------------------------------------------------------
44
45
46 // a simple wrapper around TOOLINFO Win32 structure
47 #pragma warning( disable : 4097 )
48 class wxToolInfo : public TOOLINFO
49 {
50 public:
51 wxToolInfo(wxWindow *win)
52 {
53 // initialize all members
54 #if __GNUWIN32__ && !defined(wxUSE_NORLANDER_HEADERS)
55 memset(this, 0, sizeof(TOOLINFO));
56 #else
57 ::ZeroMemory(this, sizeof(TOOLINFO));
58 #endif
59
60 cbSize = sizeof(TOOLINFO);
61 uFlags = TTF_IDISHWND;
62 uId = (UINT)win->GetHWND();
63 }
64 };
65 #pragma warning( default : 4097 )
66
67 // ----------------------------------------------------------------------------
68 // private functions
69 // ----------------------------------------------------------------------------
70
71 // send a message to the tooltip control
72 inline LRESULT SendTooltipMessage(WXHWND hwnd,
73 UINT msg,
74 WPARAM wParam,
75 void *lParam)
76 {
77 return hwnd ? ::SendMessage((HWND)hwnd, msg, wParam, (LPARAM)lParam)
78 : 0;
79 }
80
81 // send a message to all existing tooltip controls
82 static void SendTooltipMessageToAll(WXHWND hwnd,
83 UINT msg,
84 WPARAM wParam,
85 LPARAM lParam)
86 {
87 if ( hwnd )
88 (void)SendTooltipMessage((WXHWND)hwnd, msg, wParam, (void *)lParam);
89 }
90
91 // ============================================================================
92 // implementation
93 // ============================================================================
94
95 // ----------------------------------------------------------------------------
96 // static functions
97 // ----------------------------------------------------------------------------
98
99
100
101 void wxToolTip::Enable(bool flag)
102 {
103 SendTooltipMessageToAll((WXHWND)hwndTT,TTM_ACTIVATE, flag, 0);
104 }
105
106 void wxToolTip::SetDelay(long milliseconds)
107 {
108 SendTooltipMessageToAll((WXHWND)hwndTT,TTM_SETDELAYTIME, TTDT_INITIAL, milliseconds);
109 }
110
111 // ---------------------------------------------------------------------------
112 // implementation helpers
113 // ---------------------------------------------------------------------------
114
115 // create the tooltip ctrl for our parent frame if it doesn't exist yet
116 WXHWND wxToolTip::GetToolTipCtrl()
117 {
118 if ( !hwndTT )
119 {
120 hwndTT = (WXHWND)::CreateWindow(TOOLTIPS_CLASS,
121 (LPSTR)NULL,
122 TTS_ALWAYSTIP,
123 CW_USEDEFAULT, CW_USEDEFAULT,
124 CW_USEDEFAULT, CW_USEDEFAULT,
125 NULL, (HMENU)NULL,
126 wxGetInstance(),
127 NULL);
128 if ( hwndTT )
129 SetWindowPos(hwndTT, HWND_TOPMOST,0, 0, 0, 0,
130 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
131
132 }
133
134 return (WXHWND)hwndTT;
135 }
136
137 void wxToolTip::RelayEvent(WXMSG *msg)
138 {
139 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_RELAYEVENT, 0, msg);
140 }
141
142 // ----------------------------------------------------------------------------
143 // ctor & dtor
144 // ----------------------------------------------------------------------------
145
146 wxToolTip::wxToolTip(const wxString &tip)
147 : m_text(tip)
148 {
149 m_window = NULL;
150 }
151
152 wxToolTip::~wxToolTip()
153 {
154 // there is no need to Remove() this tool - it will be done automatically
155 // anyhow
156 }
157
158 // ----------------------------------------------------------------------------
159 // others
160 // ----------------------------------------------------------------------------
161
162 void wxToolTip::Remove()
163 {
164 // remove this tool from the tooltip control
165 if ( m_window )
166 {
167 wxToolInfo ti(m_window);
168 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_DELTOOL, 0, &ti);
169 }
170 }
171
172 void wxToolTip::SetWindow(wxWindow *win)
173 {
174 Remove();
175
176 m_window = win;
177
178 if ( m_window )
179 {
180 wxToolInfo ti(m_window);
181
182 // as we store our text anyhow, it seems useless to waste system memory
183 // by asking the tooltip ctrl to remember it too - instead it will send
184 // us TTN_NEEDTEXT (via WM_NOTIFY) when it is about to be shown
185 ti.hwnd = (HWND)m_window->GetHWND();
186 ti.lpszText = LPSTR_TEXTCALLBACK;
187 // instead of: ti.lpszText = (char *)m_text.c_str();
188
189 if ( !SendTooltipMessage(GetToolTipCtrl(), TTM_ADDTOOL, 0, &ti) )
190 {
191 wxLogSysError(_("Failed to create the tooltip '%s'"),
192 m_text.c_str());
193 }
194 }
195 }
196
197 void wxToolTip::SetTip(const wxString& tip)
198 {
199 m_text = tip;
200
201 if ( m_window )
202 {
203 // update it immediately
204 wxToolInfo ti(m_window);
205 ti.lpszText = (wxChar *)m_text.c_str();
206
207 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
208 }
209 }
210
211 #endif // wxUSE_TOOLTIPS