1 /////////////////////////////////////////////////////////////////////////
3 // Purpose: Implements wxTaskBarIcon class for manipulating icons on
4 // the Windows task bar.
5 // Author: Julian Smart
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////
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__) && !defined(__TWIN32__)
36 #include "wx/msw/winundef.h"
39 #include "wx/msw/taskbar.h"
40 #include "wx/msw/private.h"
43 #ifdef __GNUWIN32_OLD__
44 #include "wx/msw/gnuwin32/extra.h"
52 #include "wx/listimpl.cpp"
53 WX_DEFINE_LIST(wxTaskBarIconList
);
55 LRESULT APIENTRY _EXPORT
wxTaskBarIconWindowProc( HWND hWnd
, unsigned msg
,
56 UINT wParam
, LONG lParam
);
58 wxChar
*wxTaskBarWindowClass
= (wxChar
*) wxT("wxTaskBarWindowClass");
60 wxTaskBarIconList
wxTaskBarIcon::sm_taskBarIcons
;
61 bool wxTaskBarIcon::sm_registeredClass
= FALSE
;
62 UINT
wxTaskBarIcon::sm_taskbarMsg
= 0;
64 DEFINE_EVENT_TYPE( wxEVT_TASKBAR_MOVE
)
65 DEFINE_EVENT_TYPE( wxEVT_TASKBAR_LEFT_DOWN
)
66 DEFINE_EVENT_TYPE( wxEVT_TASKBAR_LEFT_UP
)
67 DEFINE_EVENT_TYPE( wxEVT_TASKBAR_RIGHT_DOWN
)
68 DEFINE_EVENT_TYPE( wxEVT_TASKBAR_RIGHT_UP
)
69 DEFINE_EVENT_TYPE( wxEVT_TASKBAR_LEFT_DCLICK
)
70 DEFINE_EVENT_TYPE( wxEVT_TASKBAR_RIGHT_DCLICK
)
72 BEGIN_EVENT_TABLE(wxTaskBarIcon
, wxEvtHandler
)
73 EVT_TASKBAR_MOVE (wxTaskBarIcon::_OnMouseMove
)
74 EVT_TASKBAR_LEFT_DOWN (wxTaskBarIcon::_OnLButtonDown
)
75 EVT_TASKBAR_LEFT_UP (wxTaskBarIcon::_OnLButtonUp
)
76 EVT_TASKBAR_RIGHT_DOWN (wxTaskBarIcon::_OnRButtonDown
)
77 EVT_TASKBAR_RIGHT_UP (wxTaskBarIcon::_OnRButtonUp
)
78 EVT_TASKBAR_LEFT_DCLICK (wxTaskBarIcon::_OnLButtonDClick
)
79 EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick
)
83 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
)
86 wxTaskBarIcon::wxTaskBarIcon(void)
93 if (RegisterWindowClass())
94 m_hWnd
= CreateTaskBarWindow();
97 wxTaskBarIcon::~wxTaskBarIcon(void)
108 ::DestroyWindow((HWND
) m_hWnd
);
114 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
)
119 NOTIFYICONDATA notifyData
;
121 memset(¬ifyData
, 0, sizeof(notifyData
));
122 notifyData
.cbSize
= sizeof(notifyData
);
123 notifyData
.hWnd
= (HWND
) m_hWnd
;
124 notifyData
.uCallbackMessage
= sm_taskbarMsg
;
125 notifyData
.uFlags
= NIF_MESSAGE
;
128 notifyData
.uFlags
|= NIF_ICON
;
129 notifyData
.hIcon
= (HICON
) icon
.GetHICON();
132 if (((const wxChar
*) tooltip
!= NULL
) && (tooltip
!= wxT("")))
134 notifyData
.uFlags
|= NIF_TIP
;
135 lstrcpyn(notifyData
.szTip
, WXSTRINGCAST tooltip
, sizeof(notifyData
.szTip
));
141 return (Shell_NotifyIcon(NIM_MODIFY
, & notifyData
) != 0);
144 m_iconAdded
= (Shell_NotifyIcon(NIM_ADD
, & notifyData
) != 0);
149 bool wxTaskBarIcon::RemoveIcon(void)
154 NOTIFYICONDATA notifyData
;
156 memset(¬ifyData
, 0, sizeof(notifyData
));
157 notifyData
.cbSize
= sizeof(notifyData
);
158 notifyData
.hWnd
= (HWND
) m_hWnd
;
159 notifyData
.uCallbackMessage
= sm_taskbarMsg
;
160 notifyData
.uFlags
= NIF_MESSAGE
;
161 notifyData
.hIcon
= 0 ; // hIcon;
165 return (Shell_NotifyIcon(NIM_DELETE
, & notifyData
) != 0);
168 bool wxTaskBarIcon::PopupMenu(wxMenu
*menu
) //, int x, int y);
170 // OK, so I know this isn't thread-friendly, but
171 // what to do? We need this check.
173 static bool s_inPopup
= false;
183 wxGetMousePosition(&x
, &y
);
185 // is wxFrame the best window type to use???
186 win
= new wxFrame(NULL
, -1, wxEmptyString
, wxPoint(x
,y
), wxSize(-1,-1), 0);
187 win
->PushEventHandler(this);
189 // Remove from record of top-level windows, or will confuse wxWindows
190 // if we try to exit right now.
191 wxTopLevelWindows
.DeleteObject(win
);
195 // Work around a WIN32 bug
196 ::SetForegroundWindow ((HWND
) win
->GetHWND ());
198 rval
= win
->PopupMenu(menu
, 0, 0);
200 // Work around a WIN32 bug
201 ::PostMessage ((HWND
) win
->GetHWND(),WM_NULL
,0,0L);
203 win
->PopEventHandler(false);
214 void wxTaskBarIcon::OnMouseMove(wxEvent
&)
218 void wxTaskBarIcon::OnLButtonDown(wxEvent
&)
222 void wxTaskBarIcon::OnLButtonUp(wxEvent
&)
226 void wxTaskBarIcon::OnRButtonDown(wxEvent
&)
230 void wxTaskBarIcon::OnRButtonUp(wxEvent
&)
234 void wxTaskBarIcon::OnLButtonDClick(wxEvent
&)
238 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 wxTaskBarIcon
* wxTaskBarIcon::FindObjectForHWND(WXHWND hWnd
)
253 wxTaskBarIconList::Node
*node
= sm_taskBarIcons
.GetFirst();
256 wxTaskBarIcon
*obj
= node
->GetData();
257 if (obj
->GetHWND() == hWnd
)
259 node
= node
->GetNext();
264 void wxTaskBarIcon::AddObject(wxTaskBarIcon
* obj
)
266 sm_taskBarIcons
.Append(obj
);
269 void wxTaskBarIcon::RemoveObject(wxTaskBarIcon
* obj
)
271 sm_taskBarIcons
.DeleteObject(obj
);
274 bool wxTaskBarIcon::RegisterWindowClass()
276 if (sm_registeredClass
)
279 // Also register the taskbar message here
280 sm_taskbarMsg
= ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
285 HINSTANCE hInstance
= GetModuleHandle(NULL
);
288 * set up and register window class
290 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
291 wc
.lpfnWndProc
= (WNDPROC
) wxTaskBarIconWindowProc
;
294 wc
.hInstance
= hInstance
;
297 wc
.hbrBackground
= 0;
298 wc
.lpszMenuName
= NULL
;
299 wc
.lpszClassName
= wxTaskBarWindowClass
;
300 rc
= (::RegisterClass( &wc
) != 0);
302 sm_registeredClass
= (rc
!= 0);
307 WXHWND
wxTaskBarIcon::CreateTaskBarWindow()
309 HINSTANCE hInstance
= GetModuleHandle(NULL
);
311 HWND hWnd
= CreateWindowEx (0, wxTaskBarWindowClass
,
312 wxT("wxTaskBarWindow"),
323 return (WXHWND
) hWnd
;
326 long wxTaskBarIcon::WindowProc( WXHWND hWnd
, unsigned int msg
, unsigned int wParam
, long lParam
)
328 wxEventType eventType
= 0;
330 if (msg
!= sm_taskbarMsg
)
331 return DefWindowProc((HWND
) hWnd
, msg
, wParam
, lParam
);
336 eventType
= wxEVT_TASKBAR_LEFT_DOWN
;
340 eventType
= wxEVT_TASKBAR_LEFT_UP
;
344 eventType
= wxEVT_TASKBAR_RIGHT_DOWN
;
348 eventType
= wxEVT_TASKBAR_RIGHT_UP
;
351 case WM_LBUTTONDBLCLK
:
352 eventType
= wxEVT_TASKBAR_LEFT_DCLICK
;
355 case WM_RBUTTONDBLCLK
:
356 eventType
= wxEVT_TASKBAR_RIGHT_DCLICK
;
360 eventType
= wxEVT_TASKBAR_MOVE
;
368 wxTaskBarIconEvent
event(eventType
, this);
375 LRESULT APIENTRY _EXPORT
wxTaskBarIconWindowProc( HWND hWnd
, unsigned msg
,
376 UINT wParam
, LONG lParam
)
378 wxTaskBarIcon
*obj
= wxTaskBarIcon::FindObjectForHWND((WXHWND
) hWnd
);
380 return obj
->WindowProc((WXHWND
) hWnd
, msg
, wParam
, lParam
);
382 return DefWindowProc(hWnd
, msg
, wParam
, lParam
);