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