1 /////////////////////////////////////////////////////////////////////////
3 // Purpose: Implements wxTaskBarIcon class for manipulating icons on
4 // the Windows task bar.
5 // Author: Julian Smart
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 #include "wx/listimpl.cpp"
50 WX_DEFINE_LIST(wxTaskBarIconList
);
52 LRESULT APIENTRY _EXPORT
53 wxTaskBarIconWindowProc( HWND hWnd
, unsigned msg
, UINT wParam
, LONG lParam
);
55 wxChar
*wxTaskBarWindowClass
= (wxChar
*) wxT("wxTaskBarWindowClass");
57 wxTaskBarIconList
wxTaskBarIcon::sm_taskBarIcons
;
59 // initialized on demand
60 UINT gs_msgTaskbar
= 0;
61 UINT gs_msgRestartTaskbar
= 0;
63 #if WXWIN_COMPATIBILITY_2_4
64 BEGIN_EVENT_TABLE(wxTaskBarIcon
, wxEvtHandler
)
65 EVT_TASKBAR_MOVE (wxTaskBarIcon::_OnMouseMove
)
66 EVT_TASKBAR_LEFT_DOWN (wxTaskBarIcon::_OnLButtonDown
)
67 EVT_TASKBAR_LEFT_UP (wxTaskBarIcon::_OnLButtonUp
)
68 EVT_TASKBAR_RIGHT_DOWN (wxTaskBarIcon::_OnRButtonDown
)
69 EVT_TASKBAR_RIGHT_UP (wxTaskBarIcon::_OnRButtonUp
)
70 EVT_TASKBAR_LEFT_DCLICK (wxTaskBarIcon::_OnLButtonDClick
)
71 EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick
)
76 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
)
78 // ============================================================================
80 // ============================================================================
82 // ----------------------------------------------------------------------------
83 // NotifyIconData: wrapper around NOTIFYICONDATA
84 // ----------------------------------------------------------------------------
86 struct NotifyIconData
: public NOTIFYICONDATA
88 NotifyIconData(WXHWND hwnd
)
90 memset(this, 0, sizeof(NOTIFYICONDATA
));
91 cbSize
= sizeof(NOTIFYICONDATA
);
93 uCallbackMessage
= gs_msgTaskbar
;
96 // we use the same id for all taskbar icons as we don't need it to
97 // distinguish between them
102 // ----------------------------------------------------------------------------
104 // ----------------------------------------------------------------------------
106 wxTaskBarIcon::wxTaskBarIcon()
113 if (RegisterWindowClass())
114 m_hWnd
= CreateTaskBarWindow();
117 wxTaskBarIcon::~wxTaskBarIcon()
128 ::DestroyWindow((HWND
) m_hWnd
);
134 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
)
140 m_strTooltip
= tooltip
;
142 NotifyIconData
notifyData(m_hWnd
);
146 notifyData
.uFlags
|= NIF_ICON
;
147 notifyData
.hIcon
= GetHiconOf(icon
);
150 if ( !tooltip
.empty() )
152 notifyData
.uFlags
|= NIF_TIP
;
153 // lstrcpyn(notifyData.szTip, tooltip.c_str(), WXSIZEOF(notifyData.szTip));
154 wxStrncpy(notifyData
.szTip
, tooltip
.c_str(), WXSIZEOF(notifyData
.szTip
));
157 bool ok
= Shell_NotifyIcon(m_iconAdded
? NIM_MODIFY
158 : NIM_ADD
, ¬ifyData
) != 0;
160 if ( !m_iconAdded
&& ok
)
166 bool wxTaskBarIcon::RemoveIcon()
173 NotifyIconData
notifyData(m_hWnd
);
175 return Shell_NotifyIcon(NIM_DELETE
, ¬ifyData
) != 0;
178 bool wxTaskBarIcon::PopupMenu(wxMenu
*menu
)
180 static bool s_inPopup
= false;
189 wxGetMousePosition(&x
, &y
);
191 // is wxFrame the best window type to use???
192 win
= new wxFrame(NULL
, -1, wxEmptyString
, wxPoint(x
,y
), wxSize(-1,-1), 0);
193 win
->PushEventHandler(this);
195 // Remove from record of top-level windows, or will confuse wxWindows
196 // if we try to exit right now.
197 wxTopLevelWindows
.DeleteObject(win
);
201 // Work around a WIN32 bug
202 ::SetForegroundWindow ((HWND
) win
->GetHWND ());
204 bool rval
= win
->PopupMenu(menu
, 0, 0);
206 // Work around a WIN32 bug
207 ::PostMessage ((HWND
) win
->GetHWND(),WM_NULL
,0,0L);
209 win
->PopEventHandler(false);
218 #if WXWIN_COMPATIBILITY_2_4
220 void wxTaskBarIcon::OnMouseMove(wxEvent
&) {}
221 void wxTaskBarIcon::OnLButtonDown(wxEvent
&) {}
222 void wxTaskBarIcon::OnLButtonUp(wxEvent
&) {}
223 void wxTaskBarIcon::OnRButtonDown(wxEvent
&) {}
224 void wxTaskBarIcon::OnRButtonUp(wxEvent
&) {}
225 void wxTaskBarIcon::OnLButtonDClick(wxEvent
&) {}
226 void wxTaskBarIcon::OnRButtonDClick(wxEvent
&) {}
228 void wxTaskBarIcon::_OnMouseMove(wxEvent
& e
) { OnMouseMove(e
); }
229 void wxTaskBarIcon::_OnLButtonDown(wxEvent
& e
) { OnLButtonDown(e
); }
230 void wxTaskBarIcon::_OnLButtonUp(wxEvent
& e
) { OnLButtonUp(e
); }
231 void wxTaskBarIcon::_OnRButtonDown(wxEvent
& e
) { OnRButtonDown(e
); }
232 void wxTaskBarIcon::_OnRButtonUp(wxEvent
& e
) { OnRButtonUp(e
); }
233 void wxTaskBarIcon::_OnLButtonDClick(wxEvent
& e
) { OnLButtonDClick(e
); }
234 void wxTaskBarIcon::_OnRButtonDClick(wxEvent
& e
) { OnRButtonDClick(e
); }
237 wxTaskBarIcon
* wxTaskBarIcon::FindObjectForHWND(WXHWND hWnd
)
239 wxTaskBarIconList::compatibility_iterator node
= sm_taskBarIcons
.GetFirst();
242 wxTaskBarIcon
*obj
= node
->GetData();
243 if (obj
->GetHWND() == hWnd
)
245 node
= node
->GetNext();
250 void wxTaskBarIcon::AddObject(wxTaskBarIcon
* obj
)
252 sm_taskBarIcons
.Append(obj
);
255 void wxTaskBarIcon::RemoveObject(wxTaskBarIcon
* obj
)
257 sm_taskBarIcons
.DeleteObject(obj
);
260 bool wxTaskBarIcon::RegisterWindowClass()
262 static bool s_registered
= false;
267 // Taskbar restart msg will be sent to us if the icon needs to be redrawn
268 gs_msgRestartTaskbar
= RegisterWindowMessage(wxT("TaskbarCreated"));
270 // Also register the taskbar message here
271 gs_msgTaskbar
= ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
273 // set up and register window class
275 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
276 wc
.lpfnWndProc
= (WNDPROC
) wxTaskBarIconWindowProc
;
279 wc
.hInstance
= wxGetInstance();
282 wc
.hbrBackground
= 0;
283 wc
.lpszMenuName
= NULL
;
284 wc
.lpszClassName
= wxTaskBarWindowClass
;
286 if ( !::RegisterClass(&wc
) )
288 wxLogLastError(_T("RegisterClass(taskbar icon)"));
298 WXHWND
wxTaskBarIcon::CreateTaskBarWindow()
300 HINSTANCE hInstance
= GetModuleHandle(NULL
);
302 HWND hWnd
= CreateWindowEx (0, wxTaskBarWindowClass
,
303 wxT("wxTaskBarWindow"),
314 return (WXHWND
) hWnd
;
317 // ----------------------------------------------------------------------------
318 // wxTaskBarIcon window proc
319 // ----------------------------------------------------------------------------
321 long wxTaskBarIcon::WindowProc(WXHWND hWnd
,
326 wxEventType eventType
= 0;
328 if (msg
== gs_msgRestartTaskbar
) // does the icon need to be redrawn?
331 SetIcon(m_icon
, m_strTooltip
);
334 if (msg
!= gs_msgTaskbar
)
335 return DefWindowProc((HWND
) hWnd
, msg
, wParam
, lParam
);
340 eventType
= wxEVT_TASKBAR_LEFT_DOWN
;
344 eventType
= wxEVT_TASKBAR_LEFT_UP
;
348 eventType
= wxEVT_TASKBAR_RIGHT_DOWN
;
352 eventType
= wxEVT_TASKBAR_RIGHT_UP
;
355 case WM_LBUTTONDBLCLK
:
356 eventType
= wxEVT_TASKBAR_LEFT_DCLICK
;
359 case WM_RBUTTONDBLCLK
:
360 eventType
= wxEVT_TASKBAR_RIGHT_DCLICK
;
364 eventType
= wxEVT_TASKBAR_MOVE
;
373 wxTaskBarIconEvent
event(eventType
, this);
381 LRESULT APIENTRY _EXPORT
382 wxTaskBarIconWindowProc(HWND hWnd
, unsigned msg
, UINT wParam
, LONG lParam
)
384 wxTaskBarIcon
*obj
= wxTaskBarIcon::FindObjectForHWND((WXHWND
) hWnd
);
386 return obj
->WindowProc((WXHWND
) hWnd
, msg
, wParam
, lParam
);
388 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);