wxToolTip for MSW implementation (it has several problems right now, but it
[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 #include "wx/tooltip.h"
31 #include "wx/msw/private.h"
32
33 #include <commctrl.h>
34
35 // ----------------------------------------------------------------------------
36 // private classes
37 // ----------------------------------------------------------------------------
38
39 // a simple wrapper around TOOLINFO Win32 structure
40 class wxToolInfo : public TOOLINFO
41 {
42 public:
43 wxToolInfo(wxWindow *win)
44 {
45 // initialize all members
46 ::ZeroMemory(this, sizeof(TOOLINFO));
47
48 cbSize = sizeof(TOOLINFO);
49 uFlags = TTF_IDISHWND;
50 uId = (UINT)win->GetHWND();
51 }
52 };
53
54 // ----------------------------------------------------------------------------
55 // private functions
56 // ----------------------------------------------------------------------------
57
58 // send a message to the tooltip control
59 inline LRESULT SendTooltipMessage(WXHWND hwnd,
60 UINT msg,
61 WPARAM wParam,
62 void *lParam)
63 {
64 return hwnd ? ::SendMessage((HWND)hwnd, msg, wParam, (LPARAM)lParam)
65 : 0;
66 }
67
68 // ============================================================================
69 // implementation
70 // ============================================================================
71
72 // ----------------------------------------------------------------------------
73 // "semiglobal" functions - these methods work with the tooltip control which
74 // is shared among all the wxToolTips of the same frame
75 // ----------------------------------------------------------------------------
76
77 // create the tooltip ctrl for our parent frame if it doesn't exist yet
78 WXHWND wxToolTip::GetToolTipCtrl()
79 {
80 wxWindow *parent = m_window;
81 while ( parent && !parent->IsKindOf(CLASSINFO(wxFrame)) )
82 {
83 parent = parent->GetParent();
84 }
85
86 wxCHECK_MSG( parent, 0, "can't create tooltip control outside a frame" );
87
88 wxFrame *frame = (wxFrame *)parent;
89 HWND hwndTT = (HWND)frame->GetToolTipCtrl();
90 if ( !hwndTT )
91 {
92 hwndTT = ::CreateWindow(TOOLTIPS_CLASS,
93 (LPSTR)NULL,
94 TTS_ALWAYSTIP,
95 CW_USEDEFAULT, CW_USEDEFAULT,
96 CW_USEDEFAULT, CW_USEDEFAULT,
97 (HWND)frame->GetHWND(), (HMENU)NULL,
98 wxGetInstance(), NULL);
99
100 if ( hwndTT )
101 {
102 frame->SetToolTipCtrl((WXHWND)hwndTT);
103 }
104 else
105 {
106 wxLogSysError(_("Can not create tooltip control"));
107 }
108 }
109
110 return (WXHWND)hwndTT;
111 }
112
113 void wxToolTip::Enable(bool flag)
114 {
115 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_ACTIVATE, flag, 0);
116 }
117
118 void wxToolTip::RelayEvent(WXMSG *msg)
119 {
120 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_RELAYEVENT, 0, msg);
121 }
122
123 void wxToolTip::SetDelay(long milliseconds)
124 {
125 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_SETDELAYTIME,
126 TTDT_INITIAL, (void *)milliseconds);
127 }
128
129 // ----------------------------------------------------------------------------
130 // ctor & dtor
131 // ----------------------------------------------------------------------------
132
133 wxToolTip::wxToolTip(const wxString &tip)
134 : m_text(tip)
135 {
136 m_window = NULL;
137 }
138
139 wxToolTip::~wxToolTip()
140 {
141 // there is no need to Remove() this tool - it will be done automatically
142 // anyhow
143 }
144
145 // ----------------------------------------------------------------------------
146 // others
147 // ----------------------------------------------------------------------------
148
149 void wxToolTip::Remove()
150 {
151 // remove this tool from the tooltip control
152 if ( m_window )
153 {
154 wxToolInfo ti(m_window);
155 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_DELTOOL, 0, &ti);
156 }
157 }
158
159 void wxToolTip::SetWindow(wxWindow *win)
160 {
161 Remove();
162
163 m_window = win;
164
165 if ( m_window )
166 {
167 wxToolInfo ti(m_window);
168
169 // as we store our text anyhow, it seems useless to waste system memory
170 // by asking the tooltip ctrl to remember it too - instead it will send
171 // us TTN_NEEDTEXT (via WM_NOTIFY) when it is about to be shown
172 ti.hwnd = (HWND)m_window->GetHWND();
173 ti.lpszText = LPSTR_TEXTCALLBACK;
174 // instead of: ti.lpszText = (char *)m_text.c_str();
175
176 if ( !SendTooltipMessage(GetToolTipCtrl(), TTM_ADDTOOL, 0, &ti) )
177 {
178 wxLogSysError(_("Failed to create the tooltip '%s'"),
179 m_text.c_str());
180 }
181 }
182 }
183
184 void wxToolTip::SetTip(const wxString& tip)
185 {
186 m_text = tip;
187
188 if ( m_window )
189 {
190 // update it immediately
191 wxToolInfo ti(m_window);
192 ti.lpszText = (char *)m_text.c_str();
193
194 (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
195 }
196 }