1 /////////////////////////////////////////////////////////////////////////
3 // Purpose: Implements wxTaskBarIcon class for manipulating icons on
4 // the Windows task bar.
5 // Author: Julian Smart
6 // Modified by: Vaclav Slavik
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////
13 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
14 #pragma implementation "taskbar.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
26 #include "wx/window.h"
32 #if defined(__WIN95__)
34 #include "wx/msw/private.h"
35 #include "wx/msw/winundef.h"
38 #include "wx/taskbar.h"
40 #ifdef __GNUWIN32_OLD__
41 #include "wx/msw/gnuwin32/extra.h"
49 // initialized on demand
50 UINT gs_msgTaskbar
= 0;
51 UINT gs_msgRestartTaskbar
= 0;
53 #if WXWIN_COMPATIBILITY_2_4
54 BEGIN_EVENT_TABLE(wxTaskBarIcon
, wxEvtHandler
)
55 EVT_TASKBAR_MOVE (wxTaskBarIcon::_OnMouseMove
)
56 EVT_TASKBAR_LEFT_DOWN (wxTaskBarIcon::_OnLButtonDown
)
57 EVT_TASKBAR_LEFT_UP (wxTaskBarIcon::_OnLButtonUp
)
58 EVT_TASKBAR_RIGHT_DOWN (wxTaskBarIcon::_OnRButtonDown
)
59 EVT_TASKBAR_RIGHT_UP (wxTaskBarIcon::_OnRButtonUp
)
60 EVT_TASKBAR_LEFT_DCLICK (wxTaskBarIcon::_OnLButtonDClick
)
61 EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick
)
66 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
)
68 // ============================================================================
70 // ============================================================================
72 // ----------------------------------------------------------------------------
73 // wxTaskBarIconWindow: helper window
74 // ----------------------------------------------------------------------------
76 // NB: this class serves two purposes:
77 // 1. win32 needs a HWND associated with taskbar icon, this provides it
78 // 2. we need wxTopLevelWindow so that the app doesn't exit when
79 // last frame is closed but there still is a taskbar icon
80 class wxTaskBarIconWindow
: public wxFrame
83 wxTaskBarIconWindow(wxTaskBarIcon
*icon
)
84 : wxFrame(NULL
, -1, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, 0),
89 WXLRESULT
MSWWindowProc(WXUINT msg
,
90 WXWPARAM wParam
, WXLPARAM lParam
)
92 if (msg
== gs_msgRestartTaskbar
|| msg
== gs_msgTaskbar
)
94 return m_icon
->WindowProc(msg
, wParam
, lParam
);
98 return wxFrame::MSWWindowProc(msg
, wParam
, lParam
);
103 wxTaskBarIcon
*m_icon
;
107 // ----------------------------------------------------------------------------
108 // NotifyIconData: wrapper around NOTIFYICONDATA
109 // ----------------------------------------------------------------------------
111 struct NotifyIconData
: public NOTIFYICONDATA
113 NotifyIconData(WXHWND hwnd
)
115 memset(this, 0, sizeof(NOTIFYICONDATA
));
116 cbSize
= sizeof(NOTIFYICONDATA
);
118 uCallbackMessage
= gs_msgTaskbar
;
119 uFlags
= NIF_MESSAGE
;
121 // we use the same id for all taskbar icons as we don't need it to
122 // distinguish between them
127 // ----------------------------------------------------------------------------
129 // ----------------------------------------------------------------------------
131 wxTaskBarIcon::wxTaskBarIcon()
135 RegisterWindowMessages();
138 wxTaskBarIcon::~wxTaskBarIcon()
148 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
)
150 // NB: we have to create the window lazily because of backward compatiblity,
151 // old aplications may create wxTaskBarIcon instance before wxApp
152 // is initialized (as samples/taskbar used to do)
155 m_win
= new wxTaskBarIconWindow(this);
159 m_strTooltip
= tooltip
;
161 NotifyIconData
notifyData((HWND
)m_win
->GetHWND());
165 notifyData
.uFlags
|= NIF_ICON
;
166 notifyData
.hIcon
= GetHiconOf(icon
);
169 if ( !tooltip
.empty() )
171 notifyData
.uFlags
|= NIF_TIP
;
172 // lstrcpyn(notifyData.szTip, tooltip.c_str(), WXSIZEOF(notifyData.szTip));
173 wxStrncpy(notifyData
.szTip
, tooltip
.c_str(), WXSIZEOF(notifyData
.szTip
));
176 bool ok
= Shell_NotifyIcon(m_iconAdded
? NIM_MODIFY
177 : NIM_ADD
, ¬ifyData
) != 0;
179 if ( !m_iconAdded
&& ok
)
185 bool wxTaskBarIcon::RemoveIcon()
192 NotifyIconData
notifyData((HWND
)m_win
->GetHWND());
194 return Shell_NotifyIcon(NIM_DELETE
, ¬ifyData
) != 0;
197 bool wxTaskBarIcon::PopupMenu(wxMenu
*menu
)
199 wxASSERT_MSG( m_win
!= NULL
, _T("taskbar icon not initialized") );
201 static bool s_inPopup
= false;
209 wxGetMousePosition(&x
, &y
);
213 m_win
->PushEventHandler(this);
217 // Work around a WIN32 bug
218 ::SetForegroundWindow((HWND
)m_win
->GetHWND());
220 bool rval
= m_win
->PopupMenu(menu
, 0, 0);
222 // Work around a WIN32 bug
223 ::PostMessage((HWND
)m_win
->GetHWND(), WM_NULL
, 0, 0L);
225 m_win
->PopEventHandler(false);
232 #if WXWIN_COMPATIBILITY_2_4
234 void wxTaskBarIcon::OnMouseMove(wxEvent
&) {}
235 void wxTaskBarIcon::OnLButtonDown(wxEvent
&) {}
236 void wxTaskBarIcon::OnLButtonUp(wxEvent
&) {}
237 void wxTaskBarIcon::OnRButtonDown(wxEvent
&) {}
238 void wxTaskBarIcon::OnRButtonUp(wxEvent
&) {}
239 void wxTaskBarIcon::OnLButtonDClick(wxEvent
&) {}
240 void wxTaskBarIcon::OnRButtonDClick(wxEvent
&) {}
242 void wxTaskBarIcon::_OnMouseMove(wxEvent
& e
) { OnMouseMove(e
); }
243 void wxTaskBarIcon::_OnLButtonDown(wxEvent
& e
) { OnLButtonDown(e
); }
244 void wxTaskBarIcon::_OnLButtonUp(wxEvent
& e
) { OnLButtonUp(e
); }
245 void wxTaskBarIcon::_OnRButtonDown(wxEvent
& e
) { OnRButtonDown(e
); }
246 void wxTaskBarIcon::_OnRButtonUp(wxEvent
& e
) { OnRButtonUp(e
); }
247 void wxTaskBarIcon::_OnLButtonDClick(wxEvent
& e
) { OnLButtonDClick(e
); }
248 void wxTaskBarIcon::_OnRButtonDClick(wxEvent
& e
) { OnRButtonDClick(e
); }
251 void wxTaskBarIcon::RegisterWindowMessages()
253 static bool s_registered
= false;
257 // Taskbar restart msg will be sent to us if the icon needs to be redrawn
258 gs_msgRestartTaskbar
= RegisterWindowMessage(wxT("TaskbarCreated"));
260 // Also register the taskbar message here
261 gs_msgTaskbar
= ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
267 // ----------------------------------------------------------------------------
268 // wxTaskBarIcon window proc
269 // ----------------------------------------------------------------------------
271 long wxTaskBarIcon::WindowProc(unsigned int msg
,
272 unsigned int WXUNUSED(wParam
),
275 wxEventType eventType
= 0;
277 if (msg
== gs_msgRestartTaskbar
) // does the icon need to be redrawn?
280 SetIcon(m_icon
, m_strTooltip
);
283 // this function should only be called for gs_msg(Restart)Taskbar messages
284 wxASSERT(msg
== gs_msgTaskbar
);
289 eventType
= wxEVT_TASKBAR_LEFT_DOWN
;
293 eventType
= wxEVT_TASKBAR_LEFT_UP
;
297 eventType
= wxEVT_TASKBAR_RIGHT_DOWN
;
301 eventType
= wxEVT_TASKBAR_RIGHT_UP
;
304 case WM_LBUTTONDBLCLK
:
305 eventType
= wxEVT_TASKBAR_LEFT_DCLICK
;
308 case WM_RBUTTONDBLCLK
:
309 eventType
= wxEVT_TASKBAR_RIGHT_DCLICK
;
313 eventType
= wxEVT_TASKBAR_MOVE
;
322 wxTaskBarIconEvent
event(eventType
, this);