]> git.saurik.com Git - wxWidgets.git/blob - src/msw/taskbar.cpp
wxWindow::GetBestSize() added
[wxWidgets.git] / src / msw / taskbar.cpp
1 /////////////////////////////////////////////////////////////////////////
2 // File: taskbar.cpp
3 // Purpose: Implements wxTaskBarIcon class for manipulating icons on
4 // the Windows task bar.
5 // Author: Julian Smart
6 // Modified by:
7 // Created: 24/3/98
8 // RCS-ID: $Id$
9 // Copyright: (c)
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////
12
13 #ifdef __GNUG__
14 #pragma implementation "taskbar.h"
15 #endif
16
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/defs.h"
26 #include "wx/window.h"
27 #include "wx/frame.h"
28 #include "wx/utils.h"
29 #include "wx/menu.h"
30 #endif
31
32 #if defined(__WIN95__) && !defined(__TWIN32__)
33
34 #include <windows.h>
35 #include <string.h>
36 #include "wx/msw/taskbar.h"
37 #include "wx/msw/private.h"
38
39 #ifndef __TWIN32__
40 #ifdef __GNUWIN32__
41 #ifndef wxUSE_NORLANDER_HEADERS
42 #include "wx/msw/gnuwin32/extra.h"
43 #endif
44 #endif
45 #endif
46
47 #ifdef __SALFORDC__
48 #include <shellapi.h>
49 #endif
50
51 LRESULT APIENTRY _EXPORT wxTaskBarIconWindowProc( HWND hWnd, unsigned msg,
52 UINT wParam, LONG lParam );
53
54 wxChar *wxTaskBarWindowClass = wxT("wxTaskBarWindowClass");
55
56 wxList wxTaskBarIcon::sm_taskBarIcons;
57 bool wxTaskBarIcon::sm_registeredClass = FALSE;
58 UINT wxTaskBarIcon::sm_taskbarMsg = 0;
59
60
61 #if !USE_SHARED_LIBRARY
62 BEGIN_EVENT_TABLE(wxTaskBarIcon, wxEvtHandler)
63 EVT_TASKBAR_MOVE (wxTaskBarIcon::_OnMouseMove)
64 EVT_TASKBAR_LEFT_DOWN (wxTaskBarIcon::_OnLButtonDown)
65 EVT_TASKBAR_LEFT_UP (wxTaskBarIcon::_OnLButtonUp)
66 EVT_TASKBAR_RIGHT_DOWN (wxTaskBarIcon::_OnRButtonDown)
67 EVT_TASKBAR_RIGHT_UP (wxTaskBarIcon::_OnRButtonUp)
68 EVT_TASKBAR_LEFT_DCLICK (wxTaskBarIcon::_OnLButtonDClick)
69 EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick)
70 END_EVENT_TABLE()
71
72
73 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
74 #endif
75
76
77 wxTaskBarIcon::wxTaskBarIcon(void)
78 {
79 m_hWnd = 0;
80 m_iconAdded = FALSE;
81
82 AddObject(this);
83
84 if (RegisterWindowClass())
85 m_hWnd = CreateTaskBarWindow();
86 }
87
88 wxTaskBarIcon::~wxTaskBarIcon(void)
89 {
90 RemoveObject(this);
91
92 if (m_iconAdded)
93 {
94 RemoveIcon();
95 }
96
97 if (m_hWnd)
98 {
99 ::DestroyWindow((HWND) m_hWnd);
100 m_hWnd = 0;
101 }
102 }
103
104 // Operations
105 bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
106 {
107 if (!IsOK())
108 return FALSE;
109
110 NOTIFYICONDATA notifyData;
111
112 memset(&notifyData, 0, sizeof(notifyData));
113 notifyData.cbSize = sizeof(notifyData);
114 notifyData.hWnd = (HWND) m_hWnd;
115 notifyData.uCallbackMessage = sm_taskbarMsg;
116 notifyData.uFlags = NIF_MESSAGE ;
117 if (icon.Ok())
118 {
119 notifyData.uFlags |= NIF_ICON;
120 notifyData.hIcon = (HICON) icon.GetHICON();
121 }
122
123 if (((const wxChar*) tooltip != NULL) && (tooltip != wxT("")))
124 {
125 notifyData.uFlags |= NIF_TIP ;
126 lstrcpyn(notifyData.szTip, WXSTRINGCAST tooltip, sizeof(notifyData.szTip));
127 }
128
129 notifyData.uID = 99;
130
131 if (m_iconAdded)
132 return (Shell_NotifyIcon(NIM_MODIFY, & notifyData) != 0);
133 else
134 {
135 m_iconAdded = (Shell_NotifyIcon(NIM_ADD, & notifyData) != 0);
136 return m_iconAdded;
137 }
138 }
139
140 bool wxTaskBarIcon::RemoveIcon(void)
141 {
142 if (!m_iconAdded)
143 return FALSE;
144
145 NOTIFYICONDATA notifyData;
146
147 memset(&notifyData, 0, sizeof(notifyData));
148 notifyData.cbSize = sizeof(notifyData);
149 notifyData.hWnd = (HWND) m_hWnd;
150 notifyData.uCallbackMessage = sm_taskbarMsg;
151 notifyData.uFlags = NIF_MESSAGE;
152 notifyData.hIcon = 0 ; // hIcon;
153 notifyData.uID = 99;
154 m_iconAdded = FALSE;
155
156 return (Shell_NotifyIcon(NIM_DELETE, & notifyData) != 0);
157 }
158
159 bool wxTaskBarIcon::PopupMenu(wxMenu *menu) //, int x, int y);
160 {
161 // OK, so I know this isn't thread-friendly, but
162 // what to do? We need this check.
163
164 static bool s_inPopup = FALSE;
165
166 if (s_inPopup)
167 return FALSE;
168
169 s_inPopup = TRUE;
170
171 bool rval = FALSE;
172 wxWindow* win;
173 int x, y;
174 wxGetMousePosition(&x, &y);
175
176 // is wxFrame the best window type to use???
177 win = new wxFrame(NULL, -1, "", wxPoint(x,y), wxSize(-1,-1), 0);
178 win->PushEventHandler(this);
179
180 // Remove from record of top-level windows, or will confuse wxWindows
181 // if we try to exit right now.
182 wxTopLevelWindows.DeleteObject(win);
183
184 menu->UpdateUI();
185
186 rval = win->PopupMenu(menu, 0, 0);
187
188 win->PopEventHandler(FALSE);
189 win->Destroy();
190 delete win;
191
192 s_inPopup = FALSE;
193
194 return rval;
195 }
196
197
198 // Overridables
199 void wxTaskBarIcon::OnMouseMove(wxEvent&)
200 {
201 }
202
203 void wxTaskBarIcon::OnLButtonDown(wxEvent&)
204 {
205 }
206
207 void wxTaskBarIcon::OnLButtonUp(wxEvent&)
208 {
209 }
210
211 void wxTaskBarIcon::OnRButtonDown(wxEvent&)
212 {
213 }
214
215 void wxTaskBarIcon::OnRButtonUp(wxEvent&)
216 {
217 }
218
219 void wxTaskBarIcon::OnLButtonDClick(wxEvent&)
220 {
221 }
222
223 void wxTaskBarIcon::OnRButtonDClick(wxEvent&)
224 {
225 }
226
227 void wxTaskBarIcon::_OnMouseMove(wxEvent& e) { OnMouseMove(e); }
228 void wxTaskBarIcon::_OnLButtonDown(wxEvent& e) { OnLButtonDown(e); }
229 void wxTaskBarIcon::_OnLButtonUp(wxEvent& e) { OnLButtonUp(e); }
230 void wxTaskBarIcon::_OnRButtonDown(wxEvent& e) { OnRButtonDown(e); }
231 void wxTaskBarIcon::_OnRButtonUp(wxEvent& e) { OnRButtonUp(e); }
232 void wxTaskBarIcon::_OnLButtonDClick(wxEvent& e) { OnLButtonDClick(e); }
233 void wxTaskBarIcon::_OnRButtonDClick(wxEvent& e) { OnRButtonDClick(e); }
234
235
236 wxTaskBarIcon* wxTaskBarIcon::FindObjectForHWND(WXHWND hWnd)
237 {
238 wxNode*node = sm_taskBarIcons.First();
239 while (node)
240 {
241 wxTaskBarIcon* obj = (wxTaskBarIcon*) node->Data();
242 if (obj->GetHWND() == hWnd)
243 return obj;
244 node = node->Next();
245 }
246 return NULL;
247 }
248
249 void wxTaskBarIcon::AddObject(wxTaskBarIcon* obj)
250 {
251 sm_taskBarIcons.Append(obj);
252 }
253
254 void wxTaskBarIcon::RemoveObject(wxTaskBarIcon* obj)
255 {
256 sm_taskBarIcons.DeleteObject(obj);
257 }
258
259 bool wxTaskBarIcon::RegisterWindowClass()
260 {
261 if (sm_registeredClass)
262 return TRUE;
263
264 // Also register the taskbar message here
265 sm_taskbarMsg = ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
266
267 WNDCLASS wc;
268 bool rc;
269
270 HINSTANCE hInstance = GetModuleHandle(NULL);
271
272 /*
273 * set up and register window class
274 */
275 wc.style = CS_HREDRAW | CS_VREDRAW;
276 wc.lpfnWndProc = (WNDPROC) wxTaskBarIconWindowProc;
277 wc.cbClsExtra = 0;
278 wc.cbWndExtra = 0;
279 wc.hInstance = hInstance;
280 wc.hIcon = 0;
281 wc.hCursor = 0;
282 wc.hbrBackground = 0;
283 wc.lpszMenuName = NULL;
284 wc.lpszClassName = wxTaskBarWindowClass ;
285 rc = (::RegisterClass( &wc ) != 0);
286
287 sm_registeredClass = (rc != 0);
288
289 return( (rc != 0) );
290 }
291
292 WXHWND wxTaskBarIcon::CreateTaskBarWindow()
293 {
294 HINSTANCE hInstance = GetModuleHandle(NULL);
295
296 HWND hWnd = CreateWindowEx (0, wxTaskBarWindowClass,
297 wxT("wxTaskBarWindow"),
298 WS_OVERLAPPED,
299 0,
300 0,
301 10,
302 10,
303 NULL,
304 (HMENU) 0,
305 hInstance,
306 NULL);
307
308 return (WXHWND) hWnd;
309 }
310
311 long wxTaskBarIcon::WindowProc( WXHWND hWnd, unsigned int msg, unsigned int wParam, long lParam )
312 {
313 wxEventType eventType = 0;
314
315 if (msg != sm_taskbarMsg)
316 return DefWindowProc((HWND) hWnd, msg, wParam, lParam);
317
318 switch (lParam)
319 {
320 case WM_LBUTTONDOWN:
321 eventType = wxEVT_TASKBAR_LEFT_DOWN;
322 break;
323
324 case WM_LBUTTONUP:
325 eventType = wxEVT_TASKBAR_LEFT_UP;
326 break;
327
328 case WM_RBUTTONDOWN:
329 eventType = wxEVT_TASKBAR_RIGHT_DOWN;
330 break;
331
332 case WM_RBUTTONUP:
333 eventType = wxEVT_TASKBAR_RIGHT_UP;
334 break;
335
336 case WM_LBUTTONDBLCLK:
337 eventType = wxEVT_TASKBAR_LEFT_DCLICK;
338 break;
339
340 case WM_RBUTTONDBLCLK:
341 eventType = wxEVT_TASKBAR_RIGHT_DCLICK;
342 break;
343
344 case WM_MOUSEMOVE:
345 eventType = wxEVT_TASKBAR_MOVE;
346 break;
347
348 default:
349 break;
350 }
351
352 if (eventType) {
353 wxEvent event;
354 event.SetEventType(eventType);
355 event.SetEventObject(this);
356
357 ProcessEvent(event);
358 }
359 return 0;
360 }
361
362 LRESULT APIENTRY _EXPORT wxTaskBarIconWindowProc( HWND hWnd, unsigned msg,
363 UINT wParam, LONG lParam )
364 {
365 wxTaskBarIcon* obj = wxTaskBarIcon::FindObjectForHWND((WXHWND) hWnd);
366 if (obj)
367 return obj->WindowProc((WXHWND) hWnd, msg, wParam, lParam);
368 else
369 return DefWindowProc(hWnd, msg, wParam, lParam);
370 }
371
372 #endif
373 // __WIN95__