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 LRESULT APIENTRY _EXPORT 
wxTaskBarIconWindowProc( HWND hWnd
, unsigned msg
, 
  53                                      UINT wParam
, LONG lParam 
); 
  55 wxChar 
*wxTaskBarWindowClass 
= wxT("wxTaskBarWindowClass"); 
  57 wxList 
wxTaskBarIcon::sm_taskBarIcons
; 
  58 bool   wxTaskBarIcon::sm_registeredClass 
= FALSE
; 
  59 UINT   
wxTaskBarIcon::sm_taskbarMsg 
= 0; 
  62 BEGIN_EVENT_TABLE(wxTaskBarIcon
, wxEvtHandler
) 
  63     EVT_TASKBAR_MOVE         (wxTaskBarIcon::_OnMouseMove
) 
  64     EVT_TASKBAR_LEFT_DOWN    (wxTaskBarIcon::_OnLButtonDown
) 
  65     EVT_TASKBAR_LEFT_UP      (wxTaskBarIcon::_OnLButtonUp
) 
  66     EVT_TASKBAR_RIGHT_DOWN   (wxTaskBarIcon::_OnRButtonDown
) 
  67     EVT_TASKBAR_RIGHT_UP     (wxTaskBarIcon::_OnRButtonUp
) 
  68     EVT_TASKBAR_LEFT_DCLICK  (wxTaskBarIcon::_OnLButtonDClick
) 
  69     EVT_TASKBAR_RIGHT_DCLICK (wxTaskBarIcon::_OnRButtonDClick
) 
  73 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
) 
  76 wxTaskBarIcon::wxTaskBarIcon(void) 
  83     if (RegisterWindowClass()) 
  84         m_hWnd 
= CreateTaskBarWindow(); 
  87 wxTaskBarIcon::~wxTaskBarIcon(void) 
  98         ::DestroyWindow((HWND
) m_hWnd
); 
 104 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
) 
 109     NOTIFYICONDATA notifyData
; 
 111     memset(¬ifyData
, 0, sizeof(notifyData
)); 
 112         notifyData
.cbSize 
= sizeof(notifyData
); 
 113         notifyData
.hWnd 
= (HWND
) m_hWnd
; 
 114         notifyData
.uCallbackMessage 
= sm_taskbarMsg
; 
 115         notifyData
.uFlags 
= NIF_MESSAGE 
; 
 118         notifyData
.uFlags 
|= NIF_ICON
; 
 119         notifyData
.hIcon 
= (HICON
) icon
.GetHICON(); 
 122     if (((const wxChar
*) tooltip 
!= NULL
) && (tooltip 
!= wxT(""))) 
 124         notifyData
.uFlags 
|= NIF_TIP 
; 
 125                 lstrcpyn(notifyData
.szTip
, WXSTRINGCAST tooltip
, sizeof(notifyData
.szTip
)); 
 131         return (Shell_NotifyIcon(NIM_MODIFY
, & notifyData
) != 0); 
 134         m_iconAdded 
= (Shell_NotifyIcon(NIM_ADD
, & notifyData
) != 0); 
 139 bool wxTaskBarIcon::RemoveIcon(void) 
 144     NOTIFYICONDATA notifyData
; 
 146     memset(¬ifyData
, 0, sizeof(notifyData
)); 
 147         notifyData
.cbSize 
= sizeof(notifyData
); 
 148         notifyData
.hWnd 
= (HWND
) m_hWnd
; 
 149         notifyData
.uCallbackMessage 
= sm_taskbarMsg
; 
 150         notifyData
.uFlags 
= NIF_MESSAGE
; 
 151         notifyData
.hIcon 
= 0 ; // hIcon; 
 155     return (Shell_NotifyIcon(NIM_DELETE
, & notifyData
) != 0); 
 158 bool wxTaskBarIcon::PopupMenu(wxMenu 
*menu
) //, int x, int y); 
 160     // OK, so I know this isn't thread-friendly, but 
 161     // what to do? We need this check. 
 163     static bool s_inPopup 
= FALSE
; 
 173     wxGetMousePosition(&x
, &y
); 
 175     // is wxFrame the best window type to use??? 
 176     win 
= new wxFrame(NULL
, -1, "", wxPoint(x
,y
), wxSize(-1,-1), 0); 
 177     win
->PushEventHandler(this); 
 179     // Remove from record of top-level windows, or will confuse wxWindows 
 180     // if we try to exit right now. 
 181     wxTopLevelWindows
.DeleteObject(win
); 
 185     // Work around a WIN32 bug 
 186     ::SetForegroundWindow ((HWND
) win
->GetHWND ()); 
 188     rval 
= win
->PopupMenu(menu
, 0, 0); 
 190     // Work around a WIN32 bug 
 191     ::PostMessage ((HWND
) win
->GetHWND(),WM_NULL
,0,0L); 
 193     win
->PopEventHandler(FALSE
); 
 204 void wxTaskBarIcon::OnMouseMove(wxEvent
&) 
 208 void wxTaskBarIcon::OnLButtonDown(wxEvent
&) 
 212 void wxTaskBarIcon::OnLButtonUp(wxEvent
&) 
 216 void wxTaskBarIcon::OnRButtonDown(wxEvent
&) 
 220 void wxTaskBarIcon::OnRButtonUp(wxEvent
&) 
 224 void wxTaskBarIcon::OnLButtonDClick(wxEvent
&) 
 228 void wxTaskBarIcon::OnRButtonDClick(wxEvent
&) 
 232 void wxTaskBarIcon::_OnMouseMove(wxEvent
& e
)      { OnMouseMove(e
);     } 
 233 void wxTaskBarIcon::_OnLButtonDown(wxEvent
& e
)    { OnLButtonDown(e
);   } 
 234 void wxTaskBarIcon::_OnLButtonUp(wxEvent
& e
)      { OnLButtonUp(e
);     } 
 235 void wxTaskBarIcon::_OnRButtonDown(wxEvent
& e
)    { OnRButtonDown(e
);   } 
 236 void wxTaskBarIcon::_OnRButtonUp(wxEvent
& e
)      { OnRButtonUp(e
);     } 
 237 void wxTaskBarIcon::_OnLButtonDClick(wxEvent
& e
)  { OnLButtonDClick(e
); } 
 238 void wxTaskBarIcon::_OnRButtonDClick(wxEvent
& e
)  { OnRButtonDClick(e
); } 
 241 wxTaskBarIcon
* wxTaskBarIcon::FindObjectForHWND(WXHWND hWnd
) 
 243     wxNode
*node 
= sm_taskBarIcons
.First(); 
 246         wxTaskBarIcon
* obj 
= (wxTaskBarIcon
*) node
->Data(); 
 247         if (obj
->GetHWND() == hWnd
) 
 254 void wxTaskBarIcon::AddObject(wxTaskBarIcon
* obj
) 
 256     sm_taskBarIcons
.Append(obj
); 
 259 void wxTaskBarIcon::RemoveObject(wxTaskBarIcon
* obj
) 
 261     sm_taskBarIcons
.DeleteObject(obj
); 
 264 bool wxTaskBarIcon::RegisterWindowClass() 
 266     if (sm_registeredClass
) 
 269     // Also register the taskbar message here 
 270     sm_taskbarMsg 
= ::RegisterWindowMessage(wxT("wxTaskBarIconMessage")); 
 275     HINSTANCE hInstance 
= GetModuleHandle(NULL
); 
 278      * set up and register window class 
 280     wc
.style 
= CS_HREDRAW 
| CS_VREDRAW
; 
 281     wc
.lpfnWndProc 
= (WNDPROC
) wxTaskBarIconWindowProc
; 
 284     wc
.hInstance 
= hInstance
; 
 287     wc
.hbrBackground 
= 0; 
 288     wc
.lpszMenuName 
= NULL
; 
 289     wc
.lpszClassName 
= wxTaskBarWindowClass 
; 
 290     rc 
= (::RegisterClass( &wc 
) != 0); 
 292     sm_registeredClass 
= (rc 
!= 0); 
 297 WXHWND 
wxTaskBarIcon::CreateTaskBarWindow() 
 299     HINSTANCE hInstance 
= GetModuleHandle(NULL
); 
 301     HWND hWnd 
= CreateWindowEx (0, wxTaskBarWindowClass
, 
 302             wxT("wxTaskBarWindow"), 
 313     return (WXHWND
) hWnd
; 
 316 long wxTaskBarIcon::WindowProc( WXHWND hWnd
, unsigned int msg
, unsigned int wParam
, long lParam 
) 
 318     wxEventType eventType 
= 0; 
 320     if (msg 
!= sm_taskbarMsg
) 
 321         return DefWindowProc((HWND
) hWnd
, msg
, wParam
, lParam
); 
 326             eventType 
= wxEVT_TASKBAR_LEFT_DOWN
; 
 330             eventType 
= wxEVT_TASKBAR_LEFT_UP
; 
 334             eventType 
= wxEVT_TASKBAR_RIGHT_DOWN
; 
 338             eventType 
= wxEVT_TASKBAR_RIGHT_UP
; 
 341         case WM_LBUTTONDBLCLK
: 
 342             eventType 
= wxEVT_TASKBAR_LEFT_DCLICK
; 
 345         case WM_RBUTTONDBLCLK
: 
 346             eventType 
= wxEVT_TASKBAR_RIGHT_DCLICK
; 
 350             eventType 
= wxEVT_TASKBAR_MOVE
; 
 359         event
.SetEventType(eventType
); 
 360         event
.SetEventObject(this); 
 367 LRESULT APIENTRY _EXPORT 
wxTaskBarIconWindowProc( HWND hWnd
, unsigned msg
, 
 368                                      UINT wParam
, LONG lParam 
) 
 370     wxTaskBarIcon
* obj 
= wxTaskBarIcon::FindObjectForHWND((WXHWND
) hWnd
); 
 372         return obj
->WindowProc((WXHWND
) hWnd
, msg
, wParam
, lParam
); 
 374         return DefWindowProc(hWnd
, msg
, wParam
, lParam
);