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 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
22 #include "wx/window.h"
28 #if defined(__WIN95__)
30 #include "wx/msw/private.h"
31 #include "wx/msw/winundef.h"
34 #include "wx/taskbar.h"
41 // initialized on demand
42 UINT gs_msgTaskbar
= 0;
43 UINT gs_msgRestartTaskbar
= 0;
45 #if WXWIN_COMPATIBILITY_2_4
46 BEGIN_EVENT_TABLE(wxTaskBarIcon
, wxTaskBarIconBase
)
47 EVT_TASKBAR_MOVE (wxTaskBarIcon::_OnMouseMove
)
48 EVT_TASKBAR_LEFT_DOWN (wxTaskBarIcon::_OnLButtonDown
)
49 EVT_TASKBAR_LEFT_UP (wxTaskBarIcon::_OnLButtonUp
)
50 EVT_TASKBAR_RIGHT_DOWN (wxTaskBarIcon::_OnRButtonDown
)
51 EVT_TASKBAR_RIGHT_UP (wxTaskBarIcon::_OnRButtonUp
)
52 EVT_TASKBAR_LEFT_DCLICK (wxTaskBarIcon::_OnLButtonDClick
)
53 EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick
)
58 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
)
60 // ============================================================================
62 // ============================================================================
64 // ----------------------------------------------------------------------------
65 // wxTaskBarIconWindow: helper window
66 // ----------------------------------------------------------------------------
68 // NB: this class serves two purposes:
69 // 1. win32 needs a HWND associated with taskbar icon, this provides it
70 // 2. we need wxTopLevelWindow so that the app doesn't exit when
71 // last frame is closed but there still is a taskbar icon
72 class wxTaskBarIconWindow
: public wxFrame
75 wxTaskBarIconWindow(wxTaskBarIcon
*icon
)
76 : wxFrame(NULL
, wxID_ANY
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, 0),
81 WXLRESULT
MSWWindowProc(WXUINT msg
,
82 WXWPARAM wParam
, WXLPARAM lParam
)
84 if (msg
== gs_msgRestartTaskbar
|| msg
== gs_msgTaskbar
)
86 return m_icon
->WindowProc(msg
, wParam
, lParam
);
90 return wxFrame::MSWWindowProc(msg
, wParam
, lParam
);
95 wxTaskBarIcon
*m_icon
;
99 // ----------------------------------------------------------------------------
100 // NotifyIconData: wrapper around NOTIFYICONDATA
101 // ----------------------------------------------------------------------------
103 struct NotifyIconData
: public NOTIFYICONDATA
105 NotifyIconData(WXHWND hwnd
)
107 memset(this, 0, sizeof(NOTIFYICONDATA
));
108 cbSize
= sizeof(NOTIFYICONDATA
);
110 uCallbackMessage
= gs_msgTaskbar
;
111 uFlags
= NIF_MESSAGE
;
113 // we use the same id for all taskbar icons as we don't need it to
114 // distinguish between them
119 // ----------------------------------------------------------------------------
121 // ----------------------------------------------------------------------------
123 wxTaskBarIcon::wxTaskBarIcon()
127 RegisterWindowMessages();
130 wxTaskBarIcon::~wxTaskBarIcon()
140 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
)
142 // NB: we have to create the window lazily because of backward compatibility,
143 // old applications may create a wxTaskBarIcon instance before wxApp
144 // is initialized (as samples/taskbar used to do)
147 m_win
= new wxTaskBarIconWindow(this);
151 m_strTooltip
= tooltip
;
153 NotifyIconData
notifyData((HWND
)m_win
->GetHWND());
157 notifyData
.uFlags
|= NIF_ICON
;
158 notifyData
.hIcon
= GetHiconOf(icon
);
161 if ( !tooltip
.empty() )
163 notifyData
.uFlags
|= NIF_TIP
;
164 // lstrcpyn(notifyData.szTip, tooltip.c_str(), WXSIZEOF(notifyData.szTip));
165 wxStrncpy(notifyData
.szTip
, tooltip
.c_str(), WXSIZEOF(notifyData
.szTip
));
168 bool ok
= Shell_NotifyIcon(m_iconAdded
? NIM_MODIFY
169 : NIM_ADD
, ¬ifyData
) != 0;
171 if ( !m_iconAdded
&& ok
)
177 bool wxTaskBarIcon::RemoveIcon()
184 NotifyIconData
notifyData((HWND
)m_win
->GetHWND());
186 return Shell_NotifyIcon(NIM_DELETE
, ¬ifyData
) != 0;
189 bool wxTaskBarIcon::PopupMenu(wxMenu
*menu
)
191 wxASSERT_MSG( m_win
!= NULL
, _T("taskbar icon not initialized") );
193 static bool s_inPopup
= false;
201 wxGetMousePosition(&x
, &y
);
205 m_win
->PushEventHandler(this);
209 // Work around a WIN32 bug
210 ::SetForegroundWindow((HWND
)m_win
->GetHWND());
212 bool rval
= m_win
->PopupMenu(menu
, 0, 0);
214 // Work around a WIN32 bug
215 ::PostMessage((HWND
)m_win
->GetHWND(), WM_NULL
, 0, 0L);
217 m_win
->PopEventHandler(false);
224 #if WXWIN_COMPATIBILITY_2_4
226 void wxTaskBarIcon::OnMouseMove(wxEvent
& e
) { e
.Skip(); }
227 void wxTaskBarIcon::OnLButtonDown(wxEvent
& e
) { e
.Skip(); }
228 void wxTaskBarIcon::OnLButtonUp(wxEvent
& e
) { e
.Skip(); }
229 void wxTaskBarIcon::OnRButtonDown(wxEvent
& e
) { e
.Skip(); }
230 void wxTaskBarIcon::OnRButtonUp(wxEvent
& e
) { e
.Skip(); }
231 void wxTaskBarIcon::OnLButtonDClick(wxEvent
& e
) { e
.Skip(); }
232 void wxTaskBarIcon::OnRButtonDClick(wxEvent
& e
) { e
.Skip(); }
234 void wxTaskBarIcon::_OnMouseMove(wxTaskBarIconEvent
& e
)
236 void wxTaskBarIcon::_OnLButtonDown(wxTaskBarIconEvent
& e
)
237 { OnLButtonDown(e
); }
238 void wxTaskBarIcon::_OnLButtonUp(wxTaskBarIconEvent
& e
)
240 void wxTaskBarIcon::_OnRButtonDown(wxTaskBarIconEvent
& e
)
241 { OnRButtonDown(e
); }
242 void wxTaskBarIcon::_OnRButtonUp(wxTaskBarIconEvent
& e
)
244 void wxTaskBarIcon::_OnLButtonDClick(wxTaskBarIconEvent
& e
)
245 { OnLButtonDClick(e
); }
246 void wxTaskBarIcon::_OnRButtonDClick(wxTaskBarIconEvent
& e
)
247 { OnRButtonDClick(e
); }
250 void wxTaskBarIcon::RegisterWindowMessages()
252 static bool s_registered
= false;
256 // Taskbar restart msg will be sent to us if the icon needs to be redrawn
257 gs_msgRestartTaskbar
= RegisterWindowMessage(wxT("TaskbarCreated"));
259 // Also register the taskbar message here
260 gs_msgTaskbar
= ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
266 // ----------------------------------------------------------------------------
267 // wxTaskBarIcon window proc
268 // ----------------------------------------------------------------------------
270 long wxTaskBarIcon::WindowProc(unsigned int msg
,
271 unsigned int WXUNUSED(wParam
),
274 wxEventType eventType
= 0;
276 if (msg
== gs_msgRestartTaskbar
) // does the icon need to be redrawn?
279 SetIcon(m_icon
, m_strTooltip
);
282 // this function should only be called for gs_msg(Restart)Taskbar messages
283 wxASSERT(msg
== gs_msgTaskbar
);
288 eventType
= wxEVT_TASKBAR_LEFT_DOWN
;
292 eventType
= wxEVT_TASKBAR_LEFT_UP
;
296 eventType
= wxEVT_TASKBAR_RIGHT_DOWN
;
300 eventType
= wxEVT_TASKBAR_RIGHT_UP
;
303 case WM_LBUTTONDBLCLK
:
304 eventType
= wxEVT_TASKBAR_LEFT_DCLICK
;
307 case WM_RBUTTONDBLCLK
:
308 eventType
= wxEVT_TASKBAR_RIGHT_DCLICK
;
312 eventType
= wxEVT_TASKBAR_MOVE
;
321 wxTaskBarIconEvent
event(eventType
, this);