]> git.saurik.com Git - wxWidgets.git/blame - src/msw/taskbar.cpp
Rotated text patch from Hans-Joachim Baader (with some corrections)
[wxWidgets.git] / src / msw / taskbar.cpp
CommitLineData
2bda0e17
KB
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"
ad5c34f3
JS
26#include "wx/window.h"
27#include "wx/frame.h"
28#include "wx/utils.h"
0ae2df30 29#include "wx/menu.h"
2bda0e17
KB
30#endif
31
57c208c5 32#if defined(__WIN95__) && !defined(__TWIN32__)
2bda0e17 33
3d05544e 34#include <windows.h>
2bda0e17 35#include <string.h>
3096bd2f
VZ
36#include "wx/msw/taskbar.h"
37#include "wx/msw/private.h"
2bda0e17 38
57c208c5 39#ifndef __TWIN32__
2bda0e17 40#ifdef __GNUWIN32__
65fd5cb0 41#ifndef wxUSE_NORLANDER_HEADERS
3096bd2f 42#include "wx/msw/gnuwin32/extra.h"
2bda0e17 43#endif
57c208c5 44#endif
65fd5cb0 45#endif
2bda0e17 46
ce3ed50d
JS
47#ifdef __SALFORDC__
48#include <shellapi.h>
49#endif
50
2bda0e17
KB
51LRESULT APIENTRY _EXPORT wxTaskBarIconWindowProc( HWND hWnd, unsigned msg,
52 UINT wParam, LONG lParam );
53
223d09f6 54wxChar *wxTaskBarWindowClass = wxT("wxTaskBarWindowClass");
2bda0e17
KB
55
56wxList wxTaskBarIcon::sm_taskBarIcons;
57bool wxTaskBarIcon::sm_registeredClass = FALSE;
58UINT wxTaskBarIcon::sm_taskbarMsg = 0;
59
56194595
RD
60
61#if !USE_SHARED_LIBRARY
62BEGIN_EVENT_TABLE(wxTaskBarIcon, wxEvtHandler)
69ecd30f
RD
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)
56194595
RD
70END_EVENT_TABLE()
71
72
73IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
74#endif
75
76
2bda0e17
KB
77wxTaskBarIcon::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
88wxTaskBarIcon::~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
105bool 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
223d09f6 123 if (((const wxChar*) tooltip != NULL) && (tooltip != wxT("")))
2bda0e17
KB
124 {
125 notifyData.uFlags |= NIF_TIP ;
837e5743 126 lstrcpyn(notifyData.szTip, WXSTRINGCAST tooltip, sizeof(notifyData.szTip));
2bda0e17
KB
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
140bool 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
69ecd30f
RD
159bool wxTaskBarIcon::PopupMenu(wxMenu *menu) //, int x, int y);
160{
c7527e3f
JS
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
69ecd30f
RD
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
d66d9d5b
JS
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
50bcd1ae
JS
184 menu->UpdateUI();
185
69ecd30f
RD
186 rval = win->PopupMenu(menu, 0, 0);
187
188 win->PopEventHandler(FALSE);
50c319be 189 win->Destroy();
c7527e3f
JS
190 delete win;
191
192 s_inPopup = FALSE;
d66d9d5b 193
69ecd30f
RD
194 return rval;
195}
196
197
2bda0e17 198// Overridables
56194595 199void wxTaskBarIcon::OnMouseMove(wxEvent&)
2bda0e17
KB
200{
201}
202
56194595 203void wxTaskBarIcon::OnLButtonDown(wxEvent&)
2bda0e17
KB
204{
205}
206
56194595 207void wxTaskBarIcon::OnLButtonUp(wxEvent&)
2bda0e17
KB
208{
209}
210
56194595 211void wxTaskBarIcon::OnRButtonDown(wxEvent&)
2bda0e17
KB
212{
213}
214
56194595 215void wxTaskBarIcon::OnRButtonUp(wxEvent&)
2bda0e17
KB
216{
217}
218
56194595 219void wxTaskBarIcon::OnLButtonDClick(wxEvent&)
2bda0e17
KB
220{
221}
222
56194595 223void wxTaskBarIcon::OnRButtonDClick(wxEvent&)
2bda0e17
KB
224{
225}
226
69ecd30f
RD
227void wxTaskBarIcon::_OnMouseMove(wxEvent& e) { OnMouseMove(e); }
228void wxTaskBarIcon::_OnLButtonDown(wxEvent& e) { OnLButtonDown(e); }
229void wxTaskBarIcon::_OnLButtonUp(wxEvent& e) { OnLButtonUp(e); }
230void wxTaskBarIcon::_OnRButtonDown(wxEvent& e) { OnRButtonDown(e); }
231void wxTaskBarIcon::_OnRButtonUp(wxEvent& e) { OnRButtonUp(e); }
232void wxTaskBarIcon::_OnLButtonDClick(wxEvent& e) { OnLButtonDClick(e); }
233void wxTaskBarIcon::_OnRButtonDClick(wxEvent& e) { OnRButtonDClick(e); }
234
235
2bda0e17
KB
236wxTaskBarIcon* 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
249void wxTaskBarIcon::AddObject(wxTaskBarIcon* obj)
250{
251 sm_taskBarIcons.Append(obj);
252}
253
254void wxTaskBarIcon::RemoveObject(wxTaskBarIcon* obj)
255{
256 sm_taskBarIcons.DeleteObject(obj);
257}
258
259bool wxTaskBarIcon::RegisterWindowClass()
260{
261 if (sm_registeredClass)
262 return TRUE;
263
264 // Also register the taskbar message here
223d09f6 265 sm_taskbarMsg = ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
2bda0e17
KB
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
292WXHWND wxTaskBarIcon::CreateTaskBarWindow()
293{
294 HINSTANCE hInstance = GetModuleHandle(NULL);
295
296 HWND hWnd = CreateWindowEx (0, wxTaskBarWindowClass,
223d09f6 297 wxT("wxTaskBarWindow"),
2bda0e17
KB
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
311long wxTaskBarIcon::WindowProc( WXHWND hWnd, unsigned int msg, unsigned int wParam, long lParam )
312{
56194595
RD
313 wxEventType eventType = 0;
314
2bda0e17
KB
315 if (msg != sm_taskbarMsg)
316 return DefWindowProc((HWND) hWnd, msg, wParam, lParam);
317
318 switch (lParam)
319 {
320 case WM_LBUTTONDOWN:
56194595
RD
321 eventType = wxEVT_TASKBAR_LEFT_DOWN;
322 break;
2bda0e17
KB
323
324 case WM_LBUTTONUP:
56194595
RD
325 eventType = wxEVT_TASKBAR_LEFT_UP;
326 break;
2bda0e17
KB
327
328 case WM_RBUTTONDOWN:
56194595
RD
329 eventType = wxEVT_TASKBAR_RIGHT_DOWN;
330 break;
2bda0e17
KB
331
332 case WM_RBUTTONUP:
56194595
RD
333 eventType = wxEVT_TASKBAR_RIGHT_UP;
334 break;
2bda0e17
KB
335
336 case WM_LBUTTONDBLCLK:
56194595
RD
337 eventType = wxEVT_TASKBAR_LEFT_DCLICK;
338 break;
2bda0e17
KB
339
340 case WM_RBUTTONDBLCLK:
56194595
RD
341 eventType = wxEVT_TASKBAR_RIGHT_DCLICK;
342 break;
2bda0e17
KB
343
344 case WM_MOUSEMOVE:
56194595
RD
345 eventType = wxEVT_TASKBAR_MOVE;
346 break;
2bda0e17
KB
347
348 default:
56194595 349 break;
2bda0e17 350 }
56194595
RD
351
352 if (eventType) {
353 wxEvent event;
354 event.SetEventType(eventType);
355 event.SetEventObject(this);
356
357 ProcessEvent(event);
358 }
2bda0e17
KB
359 return 0;
360}
361
362LRESULT 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__