////////////////////////////////////////////////////////////////////////// // Class Name: SShellNotifyIcon // Description:show ShellNotifyIcon // Creator: 359501300 // Version: 2017.9.11 - 2.0 - Create ////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "SShellNotifyIcon.h" #include "helper\smenuex.h" #include "helper\SMenu.h" namespace SOUI { SShellNotifyIcon::SShellNotifyIcon() :m_menuType(unknow), m_MsgOnlyWnd(NULL), m_iDefIcon(0), m_iStartFrame(1), m_bRunAni(false), m_iDuration(200) { memset(&nid, 0, sizeof(nid)); } SShellNotifyIcon::~SShellNotifyIcon() {} void SShellNotifyIcon::Create(HWND hOwner, HICON hIcon, UINT uFlags, UINT uCallbackMessage, UINT uId) { IniNotifyIconData(hOwner, hIcon, uFlags, uCallbackMessage, uId, m_strTip); } void SShellNotifyIcon::IniNotifyIconData(HWND hOwner, HICON hIcon, UINT flags, UINT callbackmsg, UINT ID, LPCWSTR szTip) { nid.cbSize = sizeof(NOTIFYICONDATA); nid.hWnd = hOwner; nid.uID = ID; nid.uFlags = flags;//NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage = callbackmsg; nid.hIcon = hIcon; _tcscpy_s(nid.szTip, szTip); } void SShellNotifyIcon::ShowMenu() { switch (m_menuType) { case MenuType::menu: { SMenu tmenu; if (tmenu.LoadMenu(m_strMenu)) { POINT pt; GetCursorPos(&pt); SetForegroundWindow(m_MsgOnlyWnd->m_hWnd); tmenu.TrackPopupMenu(0, pt.x, pt.y, m_MsgOnlyWnd->m_hWnd); } } break; case MenuType::menuex: { SMenuEx tmenuex; if (tmenuex.LoadMenu(m_strMenu)) { POINT pt; GetCursorPos(&pt); SetForegroundWindow(m_MsgOnlyWnd->m_hWnd); tmenuex.TrackPopupMenu(0, pt.x, pt.y, m_MsgOnlyWnd->m_hWnd); } } break; } } void SShellNotifyIcon::StartAni() { SASSERT(m_MsgOnlyWnd); if (m_MsgOnlyWnd) { if (m_ArrIcon.GetCount() - (m_iStartFrame + 1) > 2)//至少要两帧吧。。。 { nid.uFlags |= NIF_ICON; nid.uFlags &= ~NIF_INFO; m_iCurFrame = m_iStartFrame; m_MsgOnlyWnd->SetTimer(ANI_TIMER_ID, m_iDuration); m_bRunAni = true; } } } void SShellNotifyIcon::StopAni() { SASSERT(m_MsgOnlyWnd); m_iCurFrame = 0; if (m_MsgOnlyWnd&&m_bRunAni) { m_bRunAni = false; m_MsgOnlyWnd->KillTimer(ANI_TIMER_ID); } nid.hIcon = m_ArrIcon[m_iDefIcon]; Shell_NotifyIcon(NIM_MODIFY, &nid); } void SShellNotifyIcon::SetDefIconIdx(int iIdx) { if (iIdx >= m_ArrIcon.GetCount()) return; m_iDefIcon = iIdx; if (!m_bRunAni) { nid.uFlags |= NIF_ICON; nid.uFlags &= ~NIF_INFO; nid.hIcon = m_ArrIcon[m_iDefIcon]; Shell_NotifyIcon(NIM_MODIFY, &nid); } } void SShellNotifyIcon::NextFrame() { if (m_iCurFrame >= m_ArrIcon.GetCount()) m_iCurFrame = m_iStartFrame; nid.hIcon = m_ArrIcon[m_iCurFrame++]; Shell_NotifyIcon(NIM_MODIFY, &nid); } HRESULT SShellNotifyIcon::SetMenu(SStringT strValue, BOOL bLoading) { pugi::xml_document xmlDoc; if (SApplication::getSingleton().LoadXmlDocment(xmlDoc, strValue)) { if (_tcscmp(xmlDoc.first_child().name(), _T("menu")) == 0) m_menuType = MenuType::menu; else if ((_tcscmp(xmlDoc.first_child().name(), _T("menuRoot")) == 0) || (_tcscmp(xmlDoc.first_child().name(), _T("menuItem")) == 0)) m_menuType = MenuType::menuex; else m_menuType = MenuType::unknow; if (MenuType::unknow != m_menuType) m_strMenu = strValue; return S_OK; } else return S_FALSE; } HRESULT SShellNotifyIcon::SetIcon(SStringT strValue, BOOL bLoading) { for (size_t i = 0; i < m_ArrIcon.GetCount(); i++) { DestroyIcon(m_ArrIcon[i]); } m_ArrIcon.RemoveAll(); SStringTList icoList; size_t icoCount = SplitString(strValue, _T(';'), icoList); SASSERT(icoCount > 0); for (size_t i = 0; i < icoCount; i++) { HICON ico = LOADICON2(icoList[i]); if (ico) m_ArrIcon.Add(ico); } return m_ArrIcon.GetCount() == 0 ? S_FALSE : S_OK; } BOOL SShellNotifyIcon::Show() { //未初使化NotifyIconData if (nid.cbSize != sizeof(NOTIFYICONDATA)) return FALSE; return Shell_NotifyIcon(NIM_ADD, &nid); } BOOL SShellNotifyIcon::Hide() { return Shell_NotifyIcon(NIM_DELETE, &nid); } HRESULT SShellNotifyIcon::SetTip(SStringT szTip, BOOL bLoading) { if (!szTip.IsEmpty()) { m_strTip = szTip; if (!bLoading) { m_strTip = szTip; nid.uFlags |= NIF_TIP; nid.uFlags &= ~NIF_INFO; _tcscpy_s(nid.szTip, szTip); Shell_NotifyIcon(NIM_MODIFY, &nid); } return S_OK; } return S_FALSE; } BOOL SShellNotifyIcon::CreateChildren(pugi::xml_node xmlNode) { SHostWnd *pHostWnd = (SHostWnd*)(GetTopLevelParent()->GetContainer()); SASSERT(pHostWnd); m_MsgOnlyWnd = new CShellNotifyHwnd2(pHostWnd, this); SASSERT(IsWindow(m_MsgOnlyWnd->m_hWnd)); SASSERT(m_iDefIcon < m_ArrIcon.GetCount()); //SASSERT(m_ArrIcon.GetCount()>0); if (m_iDefIcon >= m_ArrIcon.GetCount()) m_iDefIcon = 0; Create(m_MsgOnlyWnd->m_hWnd, m_ArrIcon.GetCount() == 0 ? GETRESPROVIDER->LoadIcon(_T("ICON_LOGO"), 16) : m_ArrIcon[m_iDefIcon]); return Show(); } void SShellNotifyIcon::OnFinalRelease() { if (m_MsgOnlyWnd) { Hide(); for (size_t i = 0; i < m_ArrIcon.GetCount(); i++) { DestroyIcon(m_ArrIcon[i]); } m_ArrIcon.RemoveAll(); m_MsgOnlyWnd->PostMessage(WM_CLOSE); } } }