~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to clientgui/msw/taskbarex.cpp

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/////////////////////////////////////////////////////////////////////////
2
 
// File:        taskbar.cpp
3
 
// Purpose:     Implements wxTaskBarIconEx 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: taskbarex.cpp 15453 2008-06-23 18:48:59Z romw $
9
 
// Copyright:   (c)
10
 
// Licence:     wxWindows licence
11
 
/////////////////////////////////////////////////////////////////////////
12
 
 
13
 
#ifdef __GNUG__
14
 
#pragma implementation "taskbarex.h"
15
 
#endif
16
 
 
17
 
#include "stdwx.h"
18
 
#include "BOINCGUIApp.h"
19
 
#include "msw/taskbarex.h"
20
 
#include "BOINCTaskBar.h"
21
 
 
22
 
 
23
 
LRESULT APIENTRY wxTaskBarIconExWindowProc( HWND hWnd, unsigned msg, UINT wParam, LONG lParam );
24
 
 
25
 
wxChar* wxTaskBarExWindowClass = (wxChar*) wxT("wxTaskBarExWindowClass");
26
 
wxChar* wxTaskBarExWindow = (wxChar*) wxT("wxTaskBarExWindow");
27
 
 
28
 
const UINT WM_TASKBARCREATED   = ::RegisterWindowMessage(wxT("TaskbarCreated"));
29
 
const UINT WM_TASKBARSHUTDOWN  = ::RegisterWindowMessage(wxT("TaskbarShutdown"));
30
 
 
31
 
bool   wxTaskBarIconEx::sm_registeredClass = FALSE;
32
 
UINT   wxTaskBarIconEx::sm_taskbarMsg = 0;
33
 
 
34
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_CREATED )
35
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_CONTEXT_MENU )
36
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_SELECT )
37
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_KEY_SELECT )
38
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_SHOW )
39
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_HIDE )
40
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_TIMEOUT )
41
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_USERCLICK )
42
 
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_SHUTDOWN )
43
 
 
44
 
IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIconEx, wxEvtHandler)
45
 
 
46
 
BEGIN_EVENT_TABLE (wxTaskBarIconEx, wxEvtHandler)
47
 
    EVT_CLOSE(wxTaskBarIconEx::OnClose)
48
 
    EVT_TASKBAR_CREATED(wxTaskBarIconEx::OnTaskBarCreated)
49
 
END_EVENT_TABLE ()
50
 
 
51
 
 
52
 
wxTaskBarIconEx::wxTaskBarIconEx(void)
53
 
{
54
 
    m_hWnd = 0;
55
 
    m_iconAdded = FALSE;
56
 
 
57
 
    if (RegisterWindowClass())
58
 
        m_hWnd = CreateTaskBarWindow( wxTaskBarExWindow );
59
 
}
60
 
 
61
 
wxTaskBarIconEx::wxTaskBarIconEx( wxChar* szWindowTitle )
62
 
{
63
 
    m_hWnd = 0;
64
 
    m_iconAdded = FALSE;
65
 
 
66
 
    if (RegisterWindowClass())
67
 
        m_hWnd = CreateTaskBarWindow( szWindowTitle );
68
 
}
69
 
 
70
 
wxTaskBarIconEx::~wxTaskBarIconEx(void)
71
 
{
72
 
    if (m_iconAdded)
73
 
    {
74
 
        RemoveIcon();
75
 
    }
76
 
 
77
 
    if (m_hWnd)
78
 
    {
79
 
        ::DestroyWindow((HWND) m_hWnd);
80
 
        m_hWnd = 0;
81
 
    }
82
 
}
83
 
 
84
 
// Events
85
 
void wxTaskBarIconEx::OnClose(wxCloseEvent& WXUNUSED(event))
86
 
{
87
 
    wxLogTrace(wxT("Function Start/End"), wxT("wxTaskBarIconEx::OnClose - Function Begin"));
88
 
 
89
 
    ::DestroyWindow((HWND) m_hWnd);
90
 
    m_hWnd = 0;
91
 
 
92
 
    wxLogTrace(wxT("Function Start/End"), wxT("wxTaskBarIconEx::OnClose - Function End"));
93
 
}
94
 
 
95
 
void wxTaskBarIconEx::OnTaskBarCreated(wxTaskBarIconExEvent& WXUNUSED(event))
96
 
{
97
 
    m_iconAdded = false;
98
 
    UpdateIcon();
99
 
}
100
 
 
101
 
// Operations
102
 
bool wxTaskBarIconEx::SetIcon(const wxIcon& icon)
103
 
{
104
 
    if (!IsOK())
105
 
        return FALSE;
106
 
 
107
 
    memset(&notifyData, 0, sizeof(notifyData));
108
 
    notifyData.cbSize           = sizeof(notifyData);
109
 
    notifyData.hWnd             = (HWND) m_hWnd;
110
 
    notifyData.uID              = 99;
111
 
    notifyData.uCallbackMessage = sm_taskbarMsg;
112
 
    notifyData.uFlags           = NIF_MESSAGE;
113
 
    notifyData.uVersion         = NOTIFYICON_VERSION;
114
 
 
115
 
    if (icon.Ok())
116
 
    {
117
 
        notifyData.uFlags |= NIF_ICON;
118
 
        notifyData.hIcon = (HICON) icon.GetHICON();
119
 
    }
120
 
 
121
 
 
122
 
    UpdateIcon();
123
 
    return m_iconAdded;
124
 
}
125
 
 
126
 
bool wxTaskBarIconEx::SetTooltip(const wxString& message)
127
 
{
128
 
    if (!IsOK())
129
 
        return FALSE;
130
 
 
131
 
    memset(&notifyData, 0, sizeof(notifyData));
132
 
    notifyData.cbSize           = sizeof(notifyData);
133
 
    notifyData.hWnd             = (HWND) m_hWnd;
134
 
    notifyData.uID              = 99;
135
 
    notifyData.uCallbackMessage = sm_taskbarMsg;
136
 
    notifyData.uFlags           = NIF_MESSAGE;
137
 
    notifyData.uVersion         = NOTIFYICON_VERSION;
138
 
 
139
 
    if (((const wxChar*) message != NULL) && (message != wxT("")))
140
 
    {
141
 
        notifyData.uFlags |= NIF_TIP ;
142
 
        lstrcpyn(notifyData.szTip, WXSTRINGCAST message, sizeof(notifyData.szTip));
143
 
    }
144
 
 
145
 
 
146
 
    UpdateIcon();
147
 
    return m_iconAdded;
148
 
}
149
 
 
150
 
bool wxTaskBarIconEx::SetBalloon(const wxIcon& icon, const wxString title, const wxString message, unsigned int timeout, unsigned int iconballoon)
151
 
{
152
 
    if (!IsOK())
153
 
        return false;
154
 
 
155
 
    wxString strTip = wxEmptyString;
156
 
 
157
 
    if (!IsBalloonsSupported())
158
 
        strTip = title + wxT(" - ") + message;
159
 
 
160
 
    memset(&notifyData, 0, sizeof(notifyData));
161
 
    notifyData.cbSize           = sizeof(notifyData);
162
 
    notifyData.hWnd             = (HWND) m_hWnd;
163
 
    notifyData.uID              = 99;
164
 
    notifyData.uCallbackMessage = sm_taskbarMsg;
165
 
    notifyData.uFlags           = NIF_MESSAGE;
166
 
    notifyData.dwInfoFlags      = iconballoon | NIIF_NOSOUND;
167
 
    notifyData.uTimeout         = timeout;
168
 
    notifyData.uVersion         = NOTIFYICON_VERSION;
169
 
 
170
 
    if (icon.Ok())
171
 
    {
172
 
        notifyData.uFlags |= NIF_ICON;
173
 
        notifyData.hIcon = (HICON) icon.GetHICON();
174
 
    }
175
 
 
176
 
    if (IsBalloonsSupported())
177
 
    {
178
 
        notifyData.uFlags |= NIF_INFO | NIF_TIP;
179
 
        lstrcpyn(notifyData.szInfo, WXSTRINGCAST message, sizeof(notifyData.szInfo));
180
 
        lstrcpyn(notifyData.szInfoTitle, WXSTRINGCAST title, sizeof(notifyData.szInfoTitle));
181
 
        lstrcpyn(notifyData.szTip, WXSTRINGCAST wxEmptyString, sizeof(notifyData.szTip));
182
 
    }
183
 
    else
184
 
    {
185
 
        notifyData.uFlags |= NIF_TIP;
186
 
        lstrcpyn(notifyData.szTip, WXSTRINGCAST strTip, sizeof(notifyData.szTip));
187
 
    }
188
 
 
189
 
    UpdateIcon();
190
 
    return m_iconAdded;
191
 
}
192
 
 
193
 
bool wxTaskBarIconEx::RemoveIcon()
194
 
{
195
 
    if (!m_iconAdded)
196
 
        return FALSE;
197
 
 
198
 
    memset(&notifyData, 0, sizeof(notifyData));
199
 
    notifyData.cbSize = sizeof(notifyData);
200
 
    notifyData.hWnd = (HWND) m_hWnd;
201
 
    notifyData.uCallbackMessage = sm_taskbarMsg;
202
 
    notifyData.uFlags = NIF_MESSAGE;
203
 
    notifyData.hIcon = 0 ; // hIcon;
204
 
    notifyData.uID = 99;
205
 
    m_iconAdded = FALSE;
206
 
 
207
 
    return (Shell_NotifyIcon(NIM_DELETE, & notifyData) != 0);
208
 
}
209
 
 
210
 
void wxTaskBarIconEx::UpdateIcon()
211
 
{
212
 
    if (m_iconAdded)
213
 
    {
214
 
        Shell_NotifyIcon(NIM_MODIFY, &notifyData);
215
 
    }
216
 
    else
217
 
    {
218
 
        m_iconAdded = (Shell_NotifyIcon(NIM_ADD, &notifyData) != 0);
219
 
        if (IsBalloonsSupported())
220
 
        {
221
 
            Shell_NotifyIcon(NIM_SETVERSION, &notifyData);
222
 
        }
223
 
    }
224
 
}
225
 
 
226
 
bool wxTaskBarIconEx::PopupMenu(wxMenu *menu) //, int x, int y);
227
 
{
228
 
    // OK, so I know this isn't thread-friendly, but
229
 
    // what to do? We need this check.
230
 
 
231
 
    static bool s_inPopup = FALSE;
232
 
 
233
 
    if (s_inPopup)
234
 
        return FALSE;
235
 
 
236
 
    s_inPopup = TRUE;
237
 
 
238
 
    bool        rval = FALSE;
239
 
    wxWindow*   win;
240
 
    int         x, y;
241
 
    wxGetMousePosition(&x, &y);
242
 
 
243
 
    // is wxFrame the best window type to use???
244
 
    win = new wxFrame(NULL, -1, wxEmptyString, wxPoint(x,y), wxSize(-1,-1), 0);
245
 
    win->PushEventHandler(this);
246
 
 
247
 
    // Remove from record of top-level windows, or will confuse wxWindows
248
 
    // if we try to exit right now.
249
 
    wxTopLevelWindows.DeleteObject(win);
250
 
 
251
 
    menu->UpdateUI();
252
 
 
253
 
    // Work around a WIN32 bug
254
 
    ::SetForegroundWindow ((HWND) win->GetHWND ());
255
 
 
256
 
    rval = win->PopupMenu(menu, 0, 0);
257
 
 
258
 
    // Work around a WIN32 bug
259
 
    ::PostMessage ((HWND) win->GetHWND(),WM_NULL,0,0L);
260
 
 
261
 
    win->PopEventHandler(FALSE);
262
 
    win->Destroy();
263
 
    delete win;
264
 
 
265
 
    s_inPopup = FALSE;
266
 
 
267
 
    return rval;
268
 
}
269
 
 
270
 
 
271
 
bool wxTaskBarIconEx::RegisterWindowClass()
272
 
{
273
 
    if (sm_registeredClass)
274
 
        return TRUE;
275
 
 
276
 
    // Also register the taskbar message here
277
 
    sm_taskbarMsg = ::RegisterWindowMessage(wxT("wxTaskBarIconExMessage"));
278
 
 
279
 
    WNDCLASS        wc;
280
 
    bool        rc;
281
 
 
282
 
    HINSTANCE hInstance = GetModuleHandle(NULL);
283
 
 
284
 
    /*
285
 
     * set up and register window class
286
 
     */
287
 
    wc.style = CS_HREDRAW | CS_VREDRAW;
288
 
    wc.lpfnWndProc = (WNDPROC) wxTaskBarIconExWindowProc;
289
 
    wc.cbClsExtra = 0;
290
 
    wc.cbWndExtra = 0;
291
 
    wc.hInstance = hInstance;
292
 
    wc.hIcon = 0;
293
 
    wc.hCursor = 0;
294
 
    wc.hbrBackground = 0;
295
 
    wc.lpszMenuName = NULL;
296
 
    wc.lpszClassName = wxTaskBarExWindowClass ;
297
 
    rc = (::RegisterClass( &wc ) != 0);
298
 
 
299
 
    sm_registeredClass = (rc != 0);
300
 
 
301
 
    return( (rc != 0) );
302
 
}
303
 
 
304
 
WXHWND wxTaskBarIconEx::CreateTaskBarWindow( wxChar* szWindowTitle )
305
 
{
306
 
    HINSTANCE hInstance = GetModuleHandle(NULL);
307
 
 
308
 
    HWND hWnd = CreateWindowEx (0, wxTaskBarExWindowClass,
309
 
            szWindowTitle,
310
 
            WS_OVERLAPPED,
311
 
            0,
312
 
            0,
313
 
            10,
314
 
            10,
315
 
            NULL,
316
 
            (HMENU) 0,
317
 
            hInstance,
318
 
            NULL);
319
 
 
320
 
    return (WXHWND) hWnd;
321
 
}
322
 
 
323
 
bool wxTaskBarIconEx::IsBalloonsSupported()
324
 
{
325
 
#ifdef __WXMSW__
326
 
    wxInt32 iMajor = 0, iMinor = 0;
327
 
    if ( wxWINDOWS_NT == wxGetOsVersion( &iMajor, &iMinor ) )
328
 
    {
329
 
        if ( (5 >= iMajor) && (0 <= iMinor) )
330
 
            return true;
331
 
    }
332
 
#endif
333
 
    return false;
334
 
}
335
 
 
336
 
long wxTaskBarIconEx::WindowProc( WXHWND hWnd, unsigned int msg, unsigned int wParam, long lParam )
337
 
{
338
 
    wxLogTrace(wxT("Function Start/End"), wxT("wxTaskBarIconEx::WindowProc - Function Begin"));
339
 
 
340
 
    wxEventType eventType = 0;
341
 
    long        lReturnValue = 0;     
342
 
 
343
 
    if      ( WM_CLOSE == msg )
344
 
    {
345
 
        wxLogTrace(wxT("Function Status"), wxT("wxTaskBarIconEx::WindowProc - WM_CLOSE Detected"));
346
 
 
347
 
        wxCloseEvent eventClose(wxEVT_CLOSE_WINDOW);
348
 
        ProcessEvent(eventClose);
349
 
 
350
 
        if ( !eventClose.GetSkipped() )
351
 
            lReturnValue = DefWindowProc((HWND) hWnd, msg, wParam, lParam);
352
 
        else
353
 
            lReturnValue = 0;
354
 
    }
355
 
    else if ( WM_TASKBARCREATED == msg )
356
 
    {
357
 
        wxLogTrace(wxT("Function Status"), wxT("wxTaskBarIconEx::WindowProc - WM_TASKBARCREATED Detected"));
358
 
        eventType = wxEVT_TASKBAR_CREATED;
359
 
    }
360
 
    else if ( WM_TASKBARSHUTDOWN == msg )
361
 
    {
362
 
        wxLogTrace(wxT("Function Status"), wxT("wxTaskBarIconEx::WindowProc - WM_TASKBARSHUTDOWN Detected"));
363
 
        eventType = wxEVT_TASKBAR_SHUTDOWN;
364
 
    }
365
 
    if (msg != sm_taskbarMsg)
366
 
        lReturnValue = DefWindowProc((HWND) hWnd, msg, wParam, lParam);
367
 
 
368
 
    if ( 0 == eventType )
369
 
    {
370
 
        switch (lParam)
371
 
        {
372
 
            case WM_LBUTTONDOWN:
373
 
                eventType = wxEVT_TASKBAR_LEFT_DOWN;
374
 
                break;
375
 
 
376
 
            case WM_LBUTTONUP:
377
 
                eventType = wxEVT_TASKBAR_LEFT_UP;
378
 
                break;
379
 
 
380
 
            case WM_RBUTTONDOWN:
381
 
                eventType = wxEVT_TASKBAR_RIGHT_DOWN;
382
 
                break;
383
 
 
384
 
            case WM_RBUTTONUP:
385
 
                eventType = wxEVT_TASKBAR_RIGHT_UP;
386
 
                break;
387
 
 
388
 
            case WM_LBUTTONDBLCLK:
389
 
                eventType = wxEVT_TASKBAR_LEFT_DCLICK;
390
 
                break;
391
 
 
392
 
            case WM_RBUTTONDBLCLK:
393
 
                eventType = wxEVT_TASKBAR_RIGHT_DCLICK;
394
 
                break;
395
 
 
396
 
            case WM_MOUSEMOVE:
397
 
                eventType = wxEVT_TASKBAR_MOVE;
398
 
                break;
399
 
 
400
 
            case WM_CONTEXTMENU:
401
 
                eventType = wxEVT_TASKBAR_CONTEXT_MENU;
402
 
                break;
403
 
 
404
 
            case NIN_SELECT:
405
 
                eventType = wxEVT_TASKBAR_SELECT;
406
 
                break;
407
 
 
408
 
            case NIN_KEYSELECT:
409
 
                eventType = wxEVT_TASKBAR_KEY_SELECT;
410
 
                break;
411
 
 
412
 
            case NIN_BALLOONSHOW:
413
 
                eventType = wxEVT_TASKBAR_BALLOON_SHOW;
414
 
                break;
415
 
 
416
 
            case NIN_BALLOONHIDE:
417
 
                eventType = wxEVT_TASKBAR_BALLOON_HIDE;
418
 
                break;
419
 
 
420
 
            case NIN_BALLOONTIMEOUT:
421
 
                eventType = wxEVT_TASKBAR_BALLOON_TIMEOUT;
422
 
                break;
423
 
 
424
 
            case NIN_BALLOONUSERCLICK:
425
 
                eventType = wxEVT_TASKBAR_BALLOON_USERCLICK;
426
 
                break;
427
 
        }
428
 
    }
429
 
 
430
 
    if (eventType)
431
 
    {
432
 
        wxTaskBarIconExEvent event(eventType, this);
433
 
        ProcessEvent(event);
434
 
 
435
 
        lReturnValue = 0;
436
 
    }
437
 
 
438
 
    wxLogTrace(wxT("Function Start/End"), wxT("wxTaskBarIconEx::WindowProc - Function End"));
439
 
    return lReturnValue;
440
 
}
441
 
 
442
 
LRESULT APIENTRY wxTaskBarIconExWindowProc( HWND hWnd, unsigned msg, UINT wParam, LONG lParam )
443
 
{
444
 
    return wxGetApp().GetTaskBarIcon()->WindowProc((WXHWND) hWnd, msg, wParam, lParam);
445
 
}
446
 
 
447
 
 
448
 
const char *BOINC_RCSID_46d006c50e = "$Id: taskbarex.cpp 15453 2008-06-23 18:48:59Z romw $";
 
1
/////////////////////////////////////////////////////////////////////////
 
2
// File:        taskbar.cpp
 
3
// Purpose:     Implements wxTaskBarIconEx class for manipulating icons on
 
4
//              the Windows task bar.
 
5
// Author:      Julian Smart
 
6
// Modified by: Rom Walton
 
7
// Created:     24/3/98
 
8
// RCS-ID:      $Id: taskbarex.cpp 22576 2010-10-21 16:02:49Z romw $
 
9
// Copyright:   (c)
 
10
// Licence:     wxWindows licence
 
11
/////////////////////////////////////////////////////////////////////////
 
12
 
 
13
#ifdef __GNUG__
 
14
#pragma implementation "taskbarex.h"
 
15
#endif
 
16
 
 
17
#include "stdwx.h"
 
18
#include "BOINCGUIApp.h"
 
19
#include "msw/taskbarex.h"
 
20
#include "BOINCTaskBar.h"
 
21
 
 
22
 
 
23
// Add items new to Windows Vista and Windows 7
 
24
//
 
25
#ifndef NIF_GUID
 
26
#define NIF_GUID                    0x00000020
 
27
#endif
 
28
#ifndef NIF_REALTIME
 
29
#define NIF_REALTIME                0x00000040
 
30
#endif
 
31
#ifndef NIF_SHOWTIP
 
32
#define NIF_SHOWTIP                 0x00000080
 
33
#endif
 
34
#ifndef NIIF_LARGE_ICON
 
35
#define NIIF_LARGE_ICON             0x00000010
 
36
#endif
 
37
#ifndef NIIF_RESPECT_QUIET_TIME
 
38
#define NIIF_RESPECT_QUIET_TIME     0x00000010
 
39
#endif
 
40
 
 
41
 
 
42
LRESULT APIENTRY wxTaskBarIconExWindowProc( HWND hWnd, unsigned msg, UINT wParam, LONG lParam );
 
43
 
 
44
wxChar* wxTaskBarExWindowClass = (wxChar*) wxT("wxTaskBarExWindowClass");
 
45
wxChar* wxTaskBarExWindow      = (wxChar*) wxT("wxTaskBarExWindow");
 
46
 
 
47
const UINT WM_TASKBARCREATED    = ::RegisterWindowMessage(wxT("TaskbarCreated"));
 
48
const UINT WM_TASKBARMESSAGE    = ::RegisterWindowMessage(wxT("TaskbarMessage"));
 
49
const UINT WM_TASKBARSHUTDOWN   = ::RegisterWindowMessage(wxT("TaskbarShutdown"));
 
50
const UINT WM_TASKBARAPPRESTORE = ::RegisterWindowMessage(wxT("TaskbarAppRestore"));
 
51
 
 
52
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_CREATED )
 
53
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_CONTEXT_MENU )
 
54
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_SELECT )
 
55
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_KEY_SELECT )
 
56
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_SHOW )
 
57
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_HIDE )
 
58
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_TIMEOUT )
 
59
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_BALLOON_USERCLICK )
 
60
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_SHUTDOWN )
 
61
DEFINE_EVENT_TYPE( wxEVT_TASKBAR_APPRESTORE )
 
62
 
 
63
IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIconEx, wxEvtHandler)
 
64
 
 
65
BEGIN_EVENT_TABLE (wxTaskBarIconEx, wxEvtHandler)
 
66
    EVT_CLOSE(wxTaskBarIconEx::OnClose)
 
67
    EVT_TASKBAR_CREATED(wxTaskBarIconEx::OnTaskBarCreated)
 
68
END_EVENT_TABLE ()
 
69
 
 
70
 
 
71
wxTaskBarIconEx::wxTaskBarIconEx()
 
72
{
 
73
    m_pTaskbarMutex = new wxMutex();
 
74
    m_iTaskbarID = 0;
 
75
    m_iconAdded = FALSE;
 
76
    m_hWnd = CreateTaskBarWindow( wxTaskBarExWindow );
 
77
}
 
78
 
 
79
wxTaskBarIconEx::wxTaskBarIconEx( wxChar* szWindowTitle, wxInt32 iTaskbarID )
 
80
{
 
81
    m_pTaskbarMutex = new wxMutex();
 
82
    m_iTaskbarID = iTaskbarID;
 
83
    m_iconAdded = FALSE;
 
84
    m_hWnd = CreateTaskBarWindow( szWindowTitle );
 
85
}
 
86
 
 
87
wxTaskBarIconEx::~wxTaskBarIconEx()
 
88
{
 
89
    if (m_iconAdded)
 
90
    {
 
91
        RemoveIcon();
 
92
    }
 
93
 
 
94
    if (m_hWnd)
 
95
    {
 
96
        ::DestroyWindow((HWND) m_hWnd);
 
97
        m_hWnd = 0;
 
98
    }
 
99
}
 
100
 
 
101
// Events
 
102
void wxTaskBarIconEx::OnClose(wxCloseEvent& WXUNUSED(event))
 
103
{
 
104
    ::DestroyWindow((HWND) m_hWnd);
 
105
    m_hWnd = 0;
 
106
}
 
107
 
 
108
void wxTaskBarIconEx::OnTaskBarCreated(wxTaskBarIconExEvent& WXUNUSED(event))
 
109
{
 
110
    m_iconAdded = false;
 
111
    UpdateIcon();
 
112
}
 
113
 
 
114
// Operations
 
115
bool wxTaskBarIconEx::SetIcon(const wxIcon& icon, const wxString& message)
 
116
{
 
117
    if (!IsOK())
 
118
        return false;
 
119
 
 
120
    if (!icon.Ok())
 
121
        return false;
 
122
 
 
123
    memset(&notifyData, 0, sizeof(NOTIFYICONDATA));
 
124
    notifyData.cbSize           = sizeof(notifyData);
 
125
    notifyData.hWnd             = (HWND) m_hWnd;
 
126
    notifyData.uID              = m_iTaskbarID;
 
127
    notifyData.uCallbackMessage = WM_TASKBARMESSAGE;
 
128
    notifyData.uFlags           = NIF_MESSAGE | NIF_ICON | NIF_REALTIME;
 
129
    notifyData.uVersion         = NOTIFYICON_VERSION;
 
130
    notifyData.hIcon            = (HICON) icon.GetHICON();
 
131
 
 
132
    if (!message.empty()) {
 
133
        notifyData.uFlags       |= NIF_TIP;
 
134
        lstrcpyn(notifyData.szTip, WXSTRINGCAST message, sizeof(notifyData.szTip));
 
135
    }
 
136
 
 
137
    UpdateIcon();
 
138
    return m_iconAdded;
 
139
}
 
140
 
 
141
bool wxTaskBarIconEx::SetBalloon(const wxIcon& icon, const wxString title, const wxString message, unsigned int iconballoon)
 
142
{
 
143
    if (!IsOK())
 
144
        return false;
 
145
 
 
146
    if (!icon.Ok())
 
147
        return false;
 
148
 
 
149
    memset(&notifyData, 0, sizeof(NOTIFYICONDATA));
 
150
    notifyData.cbSize           = sizeof(notifyData);
 
151
    notifyData.hWnd             = (HWND) m_hWnd;
 
152
    notifyData.uID              = m_iTaskbarID;
 
153
    notifyData.uCallbackMessage = WM_TASKBARMESSAGE;
 
154
    notifyData.uFlags           = NIF_MESSAGE | NIF_INFO | NIF_ICON | NIF_REALTIME;
 
155
    notifyData.dwInfoFlags      = iconballoon | NIIF_NOSOUND | NIIF_RESPECT_QUIET_TIME;
 
156
    notifyData.uVersion         = NOTIFYICON_VERSION;
 
157
    notifyData.hIcon            = (HICON) icon.GetHICON();
 
158
 
 
159
    lstrcpyn(notifyData.szInfoTitle, WXSTRINGCAST title, sizeof(notifyData.szInfoTitle));
 
160
    lstrcpyn(notifyData.szInfo, WXSTRINGCAST message, sizeof(notifyData.szInfo));
 
161
 
 
162
    UpdateIcon();
 
163
    return m_iconAdded;
 
164
}
 
165
 
 
166
bool wxTaskBarIconEx::QueueBalloon(const wxIcon& icon, const wxString title, const wxString message, unsigned int iconballoon)
 
167
{
 
168
    if (!IsOK())
 
169
        return false;
 
170
 
 
171
    if (!icon.Ok())
 
172
        return false;
 
173
 
 
174
    memset(&notifyData, 0, sizeof(NOTIFYICONDATA));
 
175
    notifyData.cbSize           = sizeof(notifyData);
 
176
    notifyData.hWnd             = (HWND) m_hWnd;
 
177
    notifyData.uID              = m_iTaskbarID;
 
178
    notifyData.uCallbackMessage = WM_TASKBARMESSAGE;
 
179
    notifyData.uFlags           = NIF_MESSAGE | NIF_INFO | NIF_ICON;
 
180
    notifyData.dwInfoFlags      = iconballoon | NIIF_RESPECT_QUIET_TIME;
 
181
    notifyData.uVersion         = NOTIFYICON_VERSION;
 
182
    notifyData.hIcon            = (HICON) icon.GetHICON();
 
183
 
 
184
    lstrcpyn(notifyData.szInfoTitle, WXSTRINGCAST title, sizeof(notifyData.szInfoTitle));
 
185
    lstrcpyn(notifyData.szInfo, WXSTRINGCAST message, sizeof(notifyData.szInfo));
 
186
 
 
187
    UpdateIcon();
 
188
    return m_iconAdded;
 
189
}
 
190
 
 
191
bool wxTaskBarIconEx::RemoveIcon()
 
192
{
 
193
    if (!m_iconAdded)
 
194
        return FALSE;
 
195
 
 
196
    memset(&notifyData, 0, sizeof(NOTIFYICONDATA));
 
197
    notifyData.cbSize           = sizeof(notifyData);
 
198
    notifyData.hWnd             = (HWND) m_hWnd;
 
199
    notifyData.uID              = m_iTaskbarID;
 
200
 
 
201
    m_iconAdded = FALSE;
 
202
 
 
203
    return (Shell_NotifyIcon(NIM_DELETE, &notifyData) != 0);
 
204
}
 
205
 
 
206
void wxTaskBarIconEx::UpdateIcon()
 
207
{
 
208
    if (m_iconAdded)
 
209
    {
 
210
        Shell_NotifyIcon(NIM_MODIFY, &notifyData);
 
211
    }
 
212
    else
 
213
    {
 
214
        m_iconAdded = (Shell_NotifyIcon(NIM_ADD, &notifyData) != 0);
 
215
        if (IsBalloonsSupported())
 
216
        {
 
217
            Shell_NotifyIcon(NIM_SETVERSION, &notifyData);
 
218
        }
 
219
    }
 
220
}
 
221
 
 
222
bool wxTaskBarIconEx::PopupMenu(wxMenu *menu)
 
223
{
 
224
    wxMutexLocker lock(*m_pTaskbarMutex);
 
225
    if (!lock.IsOk()) return false;
 
226
 
 
227
    bool        rval = FALSE;
 
228
    wxWindow*   win;
 
229
    int         x, y;
 
230
    wxGetMousePosition(&x, &y);
 
231
 
 
232
    // is wxFrame the best window type to use???
 
233
    win = new wxFrame(NULL, -1, wxEmptyString, wxPoint(x,y), wxSize(-1,-1), 0);
 
234
    win->PushEventHandler(this);
 
235
 
 
236
    // Remove from record of top-level windows, or will confuse wxWindows
 
237
    // if we try to exit right now.
 
238
    wxTopLevelWindows.DeleteObject(win);
 
239
 
 
240
    menu->UpdateUI();
 
241
 
 
242
    // Work around a WIN32 bug
 
243
    ::SetForegroundWindow ((HWND) win->GetHWND());
 
244
 
 
245
    rval = win->PopupMenu(menu, 0, 0);
 
246
 
 
247
    // Work around a WIN32 bug
 
248
    ::PostMessage ((HWND) win->GetHWND(), WM_NULL, 0, 0L);
 
249
 
 
250
    win->PopEventHandler(FALSE);
 
251
    win->Destroy();
 
252
    delete win;
 
253
 
 
254
    return rval;
 
255
}
 
256
 
 
257
bool wxTaskBarIconEx::FireAppRestore()
 
258
{
 
259
    HWND hWnd = ::FindWindow(wxTaskBarExWindowClass, NULL);
 
260
    if (hWnd) {
 
261
        ::SendMessage(hWnd, WM_TASKBARAPPRESTORE, NULL, NULL);
 
262
        return true;
 
263
    }
 
264
    return false;
 
265
}
 
266
 
 
267
WXHWND wxTaskBarIconEx::CreateTaskBarWindow( wxChar* szWindowTitle )
 
268
{
 
269
    HINSTANCE hInstance = GetModuleHandle(NULL);
 
270
    HWND hWnd = NULL;
 
271
    WNDCLASS wc;
 
272
 
 
273
    if (!::GetClassInfo( hInstance, wxTaskBarExWindowClass, &wc )) {
 
274
        wc.style = CS_HREDRAW | CS_VREDRAW;
 
275
        wc.lpfnWndProc = (WNDPROC) wxTaskBarIconExWindowProc;
 
276
        wc.cbClsExtra = 0;
 
277
        wc.cbWndExtra = 0;
 
278
        wc.hInstance = hInstance;
 
279
        wc.hIcon = 0;
 
280
        wc.hCursor = 0;
 
281
        wc.hbrBackground = 0;
 
282
        wc.lpszMenuName = NULL;
 
283
        wc.lpszClassName = wxTaskBarExWindowClass;
 
284
        ::RegisterClass(&wc);
 
285
    }
 
286
 
 
287
    hWnd = ::CreateWindowEx (
 
288
        0,
 
289
        wxTaskBarExWindowClass,
 
290
        szWindowTitle,
 
291
        WS_OVERLAPPED,
 
292
        0,
 
293
        0,
 
294
        10,
 
295
        10,
 
296
        NULL,
 
297
        (HMENU)0,
 
298
        hInstance,
 
299
        NULL
 
300
    );
 
301
 
 
302
    return (WXHWND)hWnd;
 
303
}
 
304
 
 
305
bool wxTaskBarIconEx::IsBalloonsSupported()
 
306
{
 
307
    wxInt32 iMajor = 0, iMinor = 0;
 
308
    if ( wxWINDOWS_NT == wxGetOsVersion( &iMajor, &iMinor ) )
 
309
    {
 
310
        if ( (6 >= iMajor) || ((5 >= iMajor) && (0 <= iMinor)) )
 
311
            return true;
 
312
    }
 
313
    return false;
 
314
}
 
315
 
 
316
long wxTaskBarIconEx::WindowProc( WXHWND hWnd, unsigned int msg, unsigned int wParam, long lParam )
 
317
{
 
318
    wxEventType eventType = 0;
 
319
    long        lReturnValue = 0;     
 
320
 
 
321
    if      ( WM_CLOSE == msg )
 
322
    {
 
323
        wxCloseEvent eventClose(wxEVT_CLOSE_WINDOW);
 
324
        ProcessEvent(eventClose);
 
325
 
 
326
        if ( !eventClose.GetSkipped() ) {
 
327
            lReturnValue = DefWindowProc((HWND) hWnd, msg, wParam, lParam);
 
328
        } else {
 
329
            lReturnValue = 0;
 
330
        }
 
331
    }
 
332
    else if ( WM_TASKBARCREATED == msg )
 
333
    {
 
334
        eventType = wxEVT_TASKBAR_CREATED;
 
335
    }
 
336
    else if ( WM_TASKBARSHUTDOWN == msg )
 
337
    {
 
338
        eventType = wxEVT_TASKBAR_SHUTDOWN;
 
339
    }
 
340
    else if ( WM_TASKBARAPPRESTORE == msg )
 
341
    {
 
342
        eventType = wxEVT_TASKBAR_APPRESTORE;
 
343
    }
 
344
    else if ( WM_TASKBARMESSAGE == msg )
 
345
    {
 
346
        switch (lParam)
 
347
        {
 
348
            case WM_LBUTTONDOWN:
 
349
                eventType = wxEVT_TASKBAR_LEFT_DOWN;
 
350
                break;
 
351
 
 
352
            case WM_LBUTTONUP:
 
353
                eventType = wxEVT_TASKBAR_LEFT_UP;
 
354
                break;
 
355
 
 
356
            case WM_RBUTTONDOWN:
 
357
                eventType = wxEVT_TASKBAR_RIGHT_DOWN;
 
358
                break;
 
359
 
 
360
            case WM_RBUTTONUP:
 
361
                eventType = wxEVT_TASKBAR_RIGHT_UP;
 
362
                break;
 
363
 
 
364
            case WM_LBUTTONDBLCLK:
 
365
                eventType = wxEVT_TASKBAR_LEFT_DCLICK;
 
366
                break;
 
367
 
 
368
            case WM_RBUTTONDBLCLK:
 
369
                eventType = wxEVT_TASKBAR_RIGHT_DCLICK;
 
370
                break;
 
371
 
 
372
            case WM_MOUSEMOVE:
 
373
                eventType = wxEVT_TASKBAR_MOVE;
 
374
                break;
 
375
 
 
376
            case WM_CONTEXTMENU:
 
377
                eventType = wxEVT_TASKBAR_CONTEXT_MENU;
 
378
                break;
 
379
 
 
380
            case NIN_SELECT:
 
381
                eventType = wxEVT_TASKBAR_SELECT;
 
382
                break;
 
383
 
 
384
            case NIN_KEYSELECT:
 
385
                eventType = wxEVT_TASKBAR_KEY_SELECT;
 
386
                break;
 
387
 
 
388
            case NIN_BALLOONSHOW:
 
389
                eventType = wxEVT_TASKBAR_BALLOON_SHOW;
 
390
                break;
 
391
 
 
392
            case NIN_BALLOONHIDE:
 
393
                eventType = wxEVT_TASKBAR_BALLOON_HIDE;
 
394
                break;
 
395
 
 
396
            case NIN_BALLOONTIMEOUT:
 
397
                eventType = wxEVT_TASKBAR_BALLOON_TIMEOUT;
 
398
                break;
 
399
 
 
400
            case NIN_BALLOONUSERCLICK:
 
401
                eventType = wxEVT_TASKBAR_BALLOON_USERCLICK;
 
402
                break;
 
403
        }
 
404
    }
 
405
    else
 
406
    {
 
407
        lReturnValue = DefWindowProc((HWND) hWnd, msg, wParam, lParam);
 
408
    }
 
409
 
 
410
    if (eventType)
 
411
    {
 
412
        wxTaskBarIconExEvent event(eventType, this);
 
413
        lReturnValue = ProcessEvent(event);
 
414
    }
 
415
 
 
416
    return lReturnValue;
 
417
}
 
418
 
 
419
LRESULT APIENTRY wxTaskBarIconExWindowProc( HWND hWnd, unsigned msg, UINT wParam, LONG lParam )
 
420
{
 
421
    return wxGetApp().GetTaskBarIcon()->WindowProc((WXHWND) hWnd, msg, wParam, lParam);
 
422
}
 
423