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"
45 // initialized on demand
46 UINT gs_msgTaskbar
= 0;
47 UINT gs_msgRestartTaskbar
= 0;
49 #if WXWIN_COMPATIBILITY_2_4
50 BEGIN_EVENT_TABLE(wxTaskBarIcon
, wxTaskBarIconBase
)
51 EVT_TASKBAR_MOVE (wxTaskBarIcon::_OnMouseMove
)
52 EVT_TASKBAR_LEFT_DOWN (wxTaskBarIcon::_OnLButtonDown
)
53 EVT_TASKBAR_LEFT_UP (wxTaskBarIcon::_OnLButtonUp
)
54 EVT_TASKBAR_RIGHT_DOWN (wxTaskBarIcon::_OnRButtonDown
)
55 EVT_TASKBAR_RIGHT_UP (wxTaskBarIcon::_OnRButtonUp
)
56 EVT_TASKBAR_LEFT_DCLICK (wxTaskBarIcon::_OnLButtonDClick
)
57 EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick
)
62 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
)
64 // ============================================================================
66 // ============================================================================
68 // ----------------------------------------------------------------------------
69 // wxTaskBarIconWindow: helper window
70 // ----------------------------------------------------------------------------
72 // NB: this class serves two purposes:
73 // 1. win32 needs a HWND associated with taskbar icon, this provides it
74 // 2. we need wxTopLevelWindow so that the app doesn't exit when
75 // last frame is closed but there still is a taskbar icon
76 class wxTaskBarIconWindow
: public wxFrame
79 wxTaskBarIconWindow(wxTaskBarIcon
*icon
)
80 : wxFrame(NULL
, wxID_ANY
, wxEmptyString
, wxDefaultPosition
, wxDefaultSize
, 0),
85 WXLRESULT
MSWWindowProc(WXUINT msg
,
86 WXWPARAM wParam
, WXLPARAM lParam
)
88 if (msg
== gs_msgRestartTaskbar
|| msg
== gs_msgTaskbar
)
90 return m_icon
->WindowProc(msg
, wParam
, lParam
);
94 return wxFrame::MSWWindowProc(msg
, wParam
, lParam
);
99 wxTaskBarIcon
*m_icon
;
103 // ----------------------------------------------------------------------------
104 // NotifyIconData: wrapper around NOTIFYICONDATA
105 // ----------------------------------------------------------------------------
107 struct NotifyIconData
: public NOTIFYICONDATA
109 NotifyIconData(WXHWND hwnd
)
111 memset(this, 0, sizeof(NOTIFYICONDATA
));
112 cbSize
= sizeof(NOTIFYICONDATA
);
114 uCallbackMessage
= gs_msgTaskbar
;
115 uFlags
= NIF_MESSAGE
;
117 // we use the same id for all taskbar icons as we don't need it to
118 // distinguish between them
123 // ----------------------------------------------------------------------------
125 // ----------------------------------------------------------------------------
127 wxTaskBarIcon::wxTaskBarIcon()
131 RegisterWindowMessages();
134 wxTaskBarIcon::~wxTaskBarIcon()
144 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
)
146 // NB: we have to create the window lazily because of backward compatiblity,
147 // old aplications may create wxTaskBarIcon instance before wxApp
148 // is initialized (as samples/taskbar used to do)
151 m_win
= new wxTaskBarIconWindow(this);
155 m_strTooltip
= tooltip
;
157 NotifyIconData
notifyData((HWND
)m_win
->GetHWND());
161 notifyData
.uFlags
|= NIF_ICON
;
162 notifyData
.hIcon
= GetHiconOf(icon
);
165 if ( !tooltip
.empty() )
167 notifyData
.uFlags
|= NIF_TIP
;
168 // lstrcpyn(notifyData.szTip, tooltip.c_str(), WXSIZEOF(notifyData.szTip));
169 wxStrncpy(notifyData
.szTip
, tooltip
.c_str(), WXSIZEOF(notifyData
.szTip
));
172 bool ok
= Shell_NotifyIcon(m_iconAdded
? NIM_MODIFY
173 : NIM_ADD
, ¬ifyData
) != 0;
175 if ( !m_iconAdded
&& ok
)
181 bool wxTaskBarIcon::RemoveIcon()
188 NotifyIconData
notifyData((HWND
)m_win
->GetHWND());
190 return Shell_NotifyIcon(NIM_DELETE
, ¬ifyData
) != 0;
193 bool wxTaskBarIcon::PopupMenu(wxMenu
*menu
)
195 wxASSERT_MSG( m_win
!= NULL
, _T("taskbar icon not initialized") );
197 static bool s_inPopup
= false;
205 wxGetMousePosition(&x
, &y
);
209 m_win
->PushEventHandler(this);
213 // Work around a WIN32 bug
214 ::SetForegroundWindow((HWND
)m_win
->GetHWND());
216 bool rval
= m_win
->PopupMenu(menu
, 0, 0);
218 // Work around a WIN32 bug
219 ::PostMessage((HWND
)m_win
->GetHWND(), WM_NULL
, 0, 0L);
221 m_win
->PopEventHandler(false);
228 #if WXWIN_COMPATIBILITY_2_4
230 void wxTaskBarIcon::OnMouseMove(wxEvent
& e
) { e
.Skip(); }
231 void wxTaskBarIcon::OnLButtonDown(wxEvent
& e
) { e
.Skip(); }
232 void wxTaskBarIcon::OnLButtonUp(wxEvent
& e
) { e
.Skip(); }
233 void wxTaskBarIcon::OnRButtonDown(wxEvent
& e
) { e
.Skip(); }
234 void wxTaskBarIcon::OnRButtonUp(wxEvent
& e
) { e
.Skip(); }
235 void wxTaskBarIcon::OnLButtonDClick(wxEvent
& e
) { e
.Skip(); }
236 void wxTaskBarIcon::OnRButtonDClick(wxEvent
& e
) { e
.Skip(); }
238 void wxTaskBarIcon::_OnMouseMove(wxTaskBarIconEvent
& e
)
240 void wxTaskBarIcon::_OnLButtonDown(wxTaskBarIconEvent
& e
)
241 { OnLButtonDown(e
); }
242 void wxTaskBarIcon::_OnLButtonUp(wxTaskBarIconEvent
& e
)
244 void wxTaskBarIcon::_OnRButtonDown(wxTaskBarIconEvent
& e
)
245 { OnRButtonDown(e
); }
246 void wxTaskBarIcon::_OnRButtonUp(wxTaskBarIconEvent
& e
)
248 void wxTaskBarIcon::_OnLButtonDClick(wxTaskBarIconEvent
& e
)
249 { OnLButtonDClick(e
); }
250 void wxTaskBarIcon::_OnRButtonDClick(wxTaskBarIconEvent
& e
)
251 { OnRButtonDClick(e
); }
254 void wxTaskBarIcon::RegisterWindowMessages()
256 static bool s_registered
= false;
260 // Taskbar restart msg will be sent to us if the icon needs to be redrawn
261 gs_msgRestartTaskbar
= RegisterWindowMessage(wxT("TaskbarCreated"));
263 // Also register the taskbar message here
264 gs_msgTaskbar
= ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
270 // ----------------------------------------------------------------------------
271 // wxTaskBarIcon window proc
272 // ----------------------------------------------------------------------------
274 long wxTaskBarIcon::WindowProc(unsigned int msg
,
275 unsigned int WXUNUSED(wParam
),
278 wxEventType eventType
= 0;
280 if (msg
== gs_msgRestartTaskbar
) // does the icon need to be redrawn?
283 SetIcon(m_icon
, m_strTooltip
);
286 // this function should only be called for gs_msg(Restart)Taskbar messages
287 wxASSERT(msg
== gs_msgTaskbar
);
292 eventType
= wxEVT_TASKBAR_LEFT_DOWN
;
296 eventType
= wxEVT_TASKBAR_LEFT_UP
;
300 eventType
= wxEVT_TASKBAR_RIGHT_DOWN
;
304 eventType
= wxEVT_TASKBAR_RIGHT_UP
;
307 case WM_LBUTTONDBLCLK
:
308 eventType
= wxEVT_TASKBAR_LEFT_DCLICK
;
311 case WM_RBUTTONDBLCLK
:
312 eventType
= wxEVT_TASKBAR_RIGHT_DCLICK
;
316 eventType
= wxEVT_TASKBAR_MOVE
;
325 wxTaskBarIconEvent
event(eventType
, this);