show the taskbar icon even after Explorer restart (patch 723532) + some code cleanup
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20424 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -66,9 +66,10 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
WXHWND m_hWnd;
|
WXHWND m_hWnd;
|
||||||
bool m_iconAdded;
|
bool m_iconAdded;
|
||||||
|
wxIcon m_icon;
|
||||||
|
wxString m_strTooltip;
|
||||||
|
|
||||||
static wxTaskBarIconList sm_taskBarIcons;
|
static wxTaskBarIconList sm_taskBarIcons;
|
||||||
static bool sm_registeredClass;
|
|
||||||
static unsigned int sm_taskbarMsg;
|
|
||||||
|
|
||||||
#if WXWIN_COMPATIBILITY_2_4
|
#if WXWIN_COMPATIBILITY_2_4
|
||||||
// non-virtual default event handlers to forward events to the virtuals
|
// non-virtual default event handlers to forward events to the virtuals
|
||||||
|
@@ -52,14 +52,16 @@
|
|||||||
#include "wx/listimpl.cpp"
|
#include "wx/listimpl.cpp"
|
||||||
WX_DEFINE_LIST(wxTaskBarIconList);
|
WX_DEFINE_LIST(wxTaskBarIconList);
|
||||||
|
|
||||||
LRESULT APIENTRY _EXPORT wxTaskBarIconWindowProc( HWND hWnd, unsigned msg,
|
LRESULT APIENTRY _EXPORT
|
||||||
UINT wParam, LONG lParam );
|
wxTaskBarIconWindowProc( HWND hWnd, unsigned msg, UINT wParam, LONG lParam );
|
||||||
|
|
||||||
wxChar *wxTaskBarWindowClass = (wxChar*) wxT("wxTaskBarWindowClass");
|
wxChar *wxTaskBarWindowClass = (wxChar*) wxT("wxTaskBarWindowClass");
|
||||||
|
|
||||||
wxTaskBarIconList wxTaskBarIcon::sm_taskBarIcons;
|
wxTaskBarIconList wxTaskBarIcon::sm_taskBarIcons;
|
||||||
bool wxTaskBarIcon::sm_registeredClass = FALSE;
|
|
||||||
UINT wxTaskBarIcon::sm_taskbarMsg = 0;
|
// initialized on demand
|
||||||
|
UINT gs_msgTaskbar = 0;
|
||||||
|
UINT gs_msgRestartTaskbar = 0;
|
||||||
|
|
||||||
#if WXWIN_COMPATIBILITY_2_4
|
#if WXWIN_COMPATIBILITY_2_4
|
||||||
BEGIN_EVENT_TABLE(wxTaskBarIcon, wxEvtHandler)
|
BEGIN_EVENT_TABLE(wxTaskBarIcon, wxEvtHandler)
|
||||||
@@ -76,8 +78,35 @@ END_EVENT_TABLE()
|
|||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon, wxEvtHandler)
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
wxTaskBarIcon::wxTaskBarIcon(void)
|
// ----------------------------------------------------------------------------
|
||||||
|
// NotifyIconData: wrapper around NOTIFYICONDATA
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct NotifyIconData : public NOTIFYICONDATA
|
||||||
|
{
|
||||||
|
NotifyIconData(WXHWND hwnd)
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(NOTIFYICONDATA));
|
||||||
|
cbSize = sizeof(NOTIFYICONDATA);
|
||||||
|
hWnd = (HWND) hwnd;
|
||||||
|
uCallbackMessage = gs_msgTaskbar;
|
||||||
|
uFlags = NIF_MESSAGE;
|
||||||
|
|
||||||
|
// we use the same id for all taskbar icons as we don't need it to
|
||||||
|
// distinguish between them
|
||||||
|
uID = 99;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxTaskBarIcon
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxTaskBarIcon::wxTaskBarIcon()
|
||||||
{
|
{
|
||||||
m_hWnd = 0;
|
m_hWnd = 0;
|
||||||
m_iconAdded = false;
|
m_iconAdded = false;
|
||||||
@@ -88,7 +117,7 @@ wxTaskBarIcon::wxTaskBarIcon(void)
|
|||||||
m_hWnd = CreateTaskBarWindow();
|
m_hWnd = CreateTaskBarWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTaskBarIcon::~wxTaskBarIcon(void)
|
wxTaskBarIcon::~wxTaskBarIcon()
|
||||||
{
|
{
|
||||||
RemoveObject(this);
|
RemoveObject(this);
|
||||||
|
|
||||||
@@ -110,60 +139,46 @@ bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
|
|||||||
if (!IsOk())
|
if (!IsOk())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NOTIFYICONDATA notifyData;
|
m_icon = icon;
|
||||||
|
m_strTooltip = tooltip;
|
||||||
|
|
||||||
|
NotifyIconData notifyData(m_hWnd);
|
||||||
|
|
||||||
memset(¬ifyData, 0, sizeof(notifyData));
|
|
||||||
notifyData.cbSize = sizeof(notifyData);
|
|
||||||
notifyData.hWnd = (HWND) m_hWnd;
|
|
||||||
notifyData.uCallbackMessage = sm_taskbarMsg;
|
|
||||||
notifyData.uFlags = NIF_MESSAGE ;
|
|
||||||
if (icon.Ok())
|
if (icon.Ok())
|
||||||
{
|
{
|
||||||
notifyData.uFlags |= NIF_ICON;
|
notifyData.uFlags |= NIF_ICON;
|
||||||
notifyData.hIcon = (HICON) icon.GetHICON();
|
notifyData.hIcon = GetHiconOf(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((const wxChar*) tooltip != NULL) && (tooltip != wxT("")))
|
if ( !tooltip.empty() )
|
||||||
{
|
{
|
||||||
notifyData.uFlags |= NIF_TIP ;
|
notifyData.uFlags |= NIF_TIP;
|
||||||
lstrcpyn(notifyData.szTip, WXSTRINGCAST tooltip, sizeof(notifyData.szTip));
|
lstrcpyn(notifyData.szTip, tooltip.c_str(), WXSIZEOF(notifyData.szTip));
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyData.uID = 99;
|
bool ok = Shell_NotifyIcon(m_iconAdded ? NIM_MODIFY
|
||||||
|
: NIM_ADD, ¬ifyData) != 0;
|
||||||
|
|
||||||
if (m_iconAdded)
|
if ( !m_iconAdded && ok )
|
||||||
return (Shell_NotifyIcon(NIM_MODIFY, & notifyData) != 0);
|
m_iconAdded = true;
|
||||||
else
|
|
||||||
{
|
return ok;
|
||||||
m_iconAdded = (Shell_NotifyIcon(NIM_ADD, & notifyData) != 0);
|
|
||||||
return m_iconAdded;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTaskBarIcon::RemoveIcon(void)
|
bool wxTaskBarIcon::RemoveIcon()
|
||||||
{
|
{
|
||||||
if (!m_iconAdded)
|
if (!m_iconAdded)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NOTIFYICONDATA notifyData;
|
|
||||||
|
|
||||||
memset(¬ifyData, 0, sizeof(notifyData));
|
|
||||||
notifyData.cbSize = sizeof(notifyData);
|
|
||||||
notifyData.hWnd = (HWND) m_hWnd;
|
|
||||||
notifyData.uCallbackMessage = sm_taskbarMsg;
|
|
||||||
notifyData.uFlags = NIF_MESSAGE;
|
|
||||||
notifyData.hIcon = 0 ; // hIcon;
|
|
||||||
notifyData.uID = 99;
|
|
||||||
m_iconAdded = false;
|
m_iconAdded = false;
|
||||||
|
|
||||||
return (Shell_NotifyIcon(NIM_DELETE, & notifyData) != 0);
|
NotifyIconData notifyData(m_hWnd);
|
||||||
|
|
||||||
|
return Shell_NotifyIcon(NIM_DELETE, ¬ifyData) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxTaskBarIcon::PopupMenu(wxMenu *menu) //, int x, int y);
|
bool wxTaskBarIcon::PopupMenu(wxMenu *menu)
|
||||||
{
|
{
|
||||||
// OK, so I know this isn't thread-friendly, but
|
|
||||||
// what to do? We need this check.
|
|
||||||
|
|
||||||
static bool s_inPopup = false;
|
static bool s_inPopup = false;
|
||||||
|
|
||||||
if (s_inPopup)
|
if (s_inPopup)
|
||||||
@@ -247,35 +262,40 @@ void wxTaskBarIcon::RemoveObject(wxTaskBarIcon* obj)
|
|||||||
|
|
||||||
bool wxTaskBarIcon::RegisterWindowClass()
|
bool wxTaskBarIcon::RegisterWindowClass()
|
||||||
{
|
{
|
||||||
if (sm_registeredClass)
|
static bool s_registered = false;
|
||||||
|
|
||||||
|
if ( s_registered )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Taskbar restart msg will be sent to us if the icon needs to be redrawn
|
||||||
|
gs_msgRestartTaskbar = RegisterWindowMessage(wxT("TaskbarCreated"));
|
||||||
|
|
||||||
// Also register the taskbar message here
|
// Also register the taskbar message here
|
||||||
sm_taskbarMsg = ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
|
gs_msgTaskbar = ::RegisterWindowMessage(wxT("wxTaskBarIconMessage"));
|
||||||
|
|
||||||
|
// set up and register window class
|
||||||
WNDCLASS wc;
|
WNDCLASS wc;
|
||||||
bool rc;
|
|
||||||
|
|
||||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* set up and register window class
|
|
||||||
*/
|
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
wc.lpfnWndProc = (WNDPROC) wxTaskBarIconWindowProc;
|
wc.lpfnWndProc = (WNDPROC) wxTaskBarIconWindowProc;
|
||||||
wc.cbClsExtra = 0;
|
wc.cbClsExtra = 0;
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hInstance = hInstance;
|
wc.hInstance = wxGetInstance();
|
||||||
wc.hIcon = 0;
|
wc.hIcon = 0;
|
||||||
wc.hCursor = 0;
|
wc.hCursor = 0;
|
||||||
wc.hbrBackground = 0;
|
wc.hbrBackground = 0;
|
||||||
wc.lpszMenuName = NULL;
|
wc.lpszMenuName = NULL;
|
||||||
wc.lpszClassName = wxTaskBarWindowClass ;
|
wc.lpszClassName = wxTaskBarWindowClass;
|
||||||
rc = (::RegisterClass( &wc ) != 0);
|
|
||||||
|
|
||||||
sm_registeredClass = (rc != 0);
|
if ( !::RegisterClass(&wc) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("RegisterClass(taskbar icon)"));
|
||||||
|
|
||||||
return( (rc != 0) );
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_registered = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WXHWND wxTaskBarIcon::CreateTaskBarWindow()
|
WXHWND wxTaskBarIcon::CreateTaskBarWindow()
|
||||||
@@ -297,11 +317,24 @@ WXHWND wxTaskBarIcon::CreateTaskBarWindow()
|
|||||||
return (WXHWND) hWnd;
|
return (WXHWND) hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
long wxTaskBarIcon::WindowProc( WXHWND hWnd, unsigned int msg, unsigned int wParam, long lParam )
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxTaskBarIcon window proc
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
long wxTaskBarIcon::WindowProc(WXHWND hWnd,
|
||||||
|
unsigned int msg,
|
||||||
|
unsigned int wParam,
|
||||||
|
long lParam)
|
||||||
{
|
{
|
||||||
wxEventType eventType = 0;
|
wxEventType eventType = 0;
|
||||||
|
|
||||||
if (msg != sm_taskbarMsg)
|
if (msg == gs_msgRestartTaskbar) // does the icon need to be redrawn?
|
||||||
|
{
|
||||||
|
m_iconAdded = false;
|
||||||
|
SetIcon(m_icon, m_strTooltip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg != gs_msgTaskbar)
|
||||||
return DefWindowProc((HWND) hWnd, msg, wParam, lParam);
|
return DefWindowProc((HWND) hWnd, msg, wParam, lParam);
|
||||||
|
|
||||||
switch (lParam)
|
switch (lParam)
|
||||||
@@ -338,16 +371,18 @@ long wxTaskBarIcon::WindowProc( WXHWND hWnd, unsigned int msg, unsigned int wPar
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventType) {
|
if (eventType)
|
||||||
|
{
|
||||||
wxTaskBarIconEvent event(eventType, this);
|
wxTaskBarIconEvent event(eventType, this);
|
||||||
|
|
||||||
ProcessEvent(event);
|
ProcessEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT APIENTRY _EXPORT wxTaskBarIconWindowProc( HWND hWnd, unsigned msg,
|
LRESULT APIENTRY _EXPORT
|
||||||
UINT wParam, LONG lParam )
|
wxTaskBarIconWindowProc(HWND hWnd, unsigned msg, UINT wParam, LONG lParam)
|
||||||
{
|
{
|
||||||
wxTaskBarIcon *obj = wxTaskBarIcon::FindObjectForHWND((WXHWND) hWnd);
|
wxTaskBarIcon *obj = wxTaskBarIcon::FindObjectForHWND((WXHWND) hWnd);
|
||||||
if (obj)
|
if (obj)
|
||||||
|
Reference in New Issue
Block a user