SShellNotifyIcon.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //////////////////////////////////////////////////////////////////////////
  2. // Class Name: SShellNotifyIcon
  3. // Description:show ShellNotifyIcon
  4. // Creator: 359501300
  5. // Version: 2017.9.11 - 2.0 - Create
  6. //////////////////////////////////////////////////////////////////////////
  7. #include "stdafx.h"
  8. #include "SShellNotifyIcon.h"
  9. #include "helper\smenuex.h"
  10. #include "helper\SMenu.h"
  11. namespace SOUI
  12. {
  13. SShellNotifyIcon::SShellNotifyIcon() :m_menuType(unknow), m_MsgOnlyWnd(NULL), m_iDefIcon(0), m_iStartFrame(1), m_bRunAni(false), m_iDuration(200)
  14. {
  15. memset(&nid, 0, sizeof(nid));
  16. }
  17. SShellNotifyIcon::~SShellNotifyIcon() {}
  18. void SShellNotifyIcon::Create(HWND hOwner, HICON hIcon, UINT uFlags, UINT uCallbackMessage, UINT uId)
  19. {
  20. IniNotifyIconData(hOwner, hIcon, uFlags, uCallbackMessage, uId, m_strTip);
  21. }
  22. void SShellNotifyIcon::IniNotifyIconData(HWND hOwner, HICON hIcon, UINT flags, UINT callbackmsg, UINT ID, LPCWSTR szTip)
  23. {
  24. nid.cbSize = sizeof(NOTIFYICONDATA);
  25. nid.hWnd = hOwner;
  26. nid.uID = ID;
  27. nid.uFlags = flags;//NIF_ICON | NIF_MESSAGE | NIF_TIP;
  28. nid.uCallbackMessage = callbackmsg;
  29. nid.hIcon = hIcon;
  30. _tcscpy_s(nid.szTip, szTip);
  31. }
  32. void SShellNotifyIcon::ShowMenu()
  33. {
  34. switch (m_menuType)
  35. {
  36. case MenuType::menu:
  37. {
  38. SMenu tmenu;
  39. if (tmenu.LoadMenu(m_strMenu))
  40. {
  41. POINT pt;
  42. GetCursorPos(&pt);
  43. SetForegroundWindow(m_MsgOnlyWnd->m_hWnd);
  44. tmenu.TrackPopupMenu(0, pt.x, pt.y, m_MsgOnlyWnd->m_hWnd);
  45. }
  46. }
  47. break;
  48. case MenuType::menuex:
  49. {
  50. SMenuEx tmenuex;
  51. if (tmenuex.LoadMenu(m_strMenu))
  52. {
  53. POINT pt;
  54. GetCursorPos(&pt);
  55. SetForegroundWindow(m_MsgOnlyWnd->m_hWnd);
  56. tmenuex.TrackPopupMenu(0, pt.x, pt.y, m_MsgOnlyWnd->m_hWnd);
  57. }
  58. }
  59. break;
  60. }
  61. }
  62. void SShellNotifyIcon::StartAni()
  63. {
  64. SASSERT(m_MsgOnlyWnd);
  65. if (m_MsgOnlyWnd)
  66. {
  67. if (m_ArrIcon.GetCount() - (m_iStartFrame + 1) > 2)//至少要两帧吧。。。
  68. {
  69. nid.uFlags |= NIF_ICON;
  70. nid.uFlags &= ~NIF_INFO;
  71. m_iCurFrame = m_iStartFrame;
  72. m_MsgOnlyWnd->SetTimer(ANI_TIMER_ID, m_iDuration);
  73. m_bRunAni = true;
  74. }
  75. }
  76. }
  77. void SShellNotifyIcon::StopAni()
  78. {
  79. SASSERT(m_MsgOnlyWnd);
  80. m_iCurFrame = 0;
  81. if (m_MsgOnlyWnd&&m_bRunAni)
  82. {
  83. m_bRunAni = false;
  84. m_MsgOnlyWnd->KillTimer(ANI_TIMER_ID);
  85. }
  86. nid.hIcon = m_ArrIcon[m_iDefIcon];
  87. Shell_NotifyIcon(NIM_MODIFY, &nid);
  88. }
  89. void SShellNotifyIcon::SetDefIconIdx(int iIdx)
  90. {
  91. if (iIdx >= m_ArrIcon.GetCount())
  92. return;
  93. m_iDefIcon = iIdx;
  94. if (!m_bRunAni)
  95. {
  96. nid.uFlags |= NIF_ICON;
  97. nid.uFlags &= ~NIF_INFO;
  98. nid.hIcon = m_ArrIcon[m_iDefIcon];
  99. Shell_NotifyIcon(NIM_MODIFY, &nid);
  100. }
  101. }
  102. void SShellNotifyIcon::NextFrame()
  103. {
  104. if (m_iCurFrame >= m_ArrIcon.GetCount())
  105. m_iCurFrame = m_iStartFrame;
  106. nid.hIcon = m_ArrIcon[m_iCurFrame++];
  107. Shell_NotifyIcon(NIM_MODIFY, &nid);
  108. }
  109. HRESULT SShellNotifyIcon::SetMenu(SStringT strValue, BOOL bLoading)
  110. {
  111. pugi::xml_document xmlDoc;
  112. if (SApplication::getSingleton().LoadXmlDocment(xmlDoc, strValue))
  113. {
  114. if (_tcscmp(xmlDoc.first_child().name(), _T("menu")) == 0)
  115. m_menuType = MenuType::menu;
  116. else if ((_tcscmp(xmlDoc.first_child().name(), _T("menuRoot")) == 0) || (_tcscmp(xmlDoc.first_child().name(), _T("menuItem")) == 0))
  117. m_menuType = MenuType::menuex;
  118. else m_menuType = MenuType::unknow;
  119. if (MenuType::unknow != m_menuType)
  120. m_strMenu = strValue;
  121. return S_OK;
  122. }
  123. else return S_FALSE;
  124. }
  125. HRESULT SShellNotifyIcon::SetIcon(SStringT strValue, BOOL bLoading)
  126. {
  127. for (size_t i = 0; i < m_ArrIcon.GetCount(); i++)
  128. {
  129. DestroyIcon(m_ArrIcon[i]);
  130. }
  131. m_ArrIcon.RemoveAll();
  132. SStringTList icoList;
  133. size_t icoCount = SplitString(strValue, _T(';'), icoList);
  134. SASSERT(icoCount > 0);
  135. for (size_t i = 0; i < icoCount; i++)
  136. {
  137. HICON ico = LOADICON2(icoList[i]);
  138. if (ico)
  139. m_ArrIcon.Add(ico);
  140. }
  141. return m_ArrIcon.GetCount() == 0 ? S_FALSE : S_OK;
  142. }
  143. BOOL SShellNotifyIcon::Show()
  144. {
  145. //未初使化NotifyIconData
  146. if (nid.cbSize != sizeof(NOTIFYICONDATA))
  147. return FALSE;
  148. return Shell_NotifyIcon(NIM_ADD, &nid);
  149. }
  150. BOOL SShellNotifyIcon::Hide()
  151. {
  152. return Shell_NotifyIcon(NIM_DELETE, &nid);
  153. }
  154. HRESULT SShellNotifyIcon::SetTip(SStringT szTip, BOOL bLoading)
  155. {
  156. if (!szTip.IsEmpty())
  157. {
  158. m_strTip = szTip;
  159. if (!bLoading)
  160. {
  161. m_strTip = szTip;
  162. nid.uFlags |= NIF_TIP;
  163. nid.uFlags &= ~NIF_INFO;
  164. _tcscpy_s(nid.szTip, szTip);
  165. Shell_NotifyIcon(NIM_MODIFY, &nid);
  166. }
  167. return S_OK;
  168. }
  169. return S_FALSE;
  170. }
  171. BOOL SShellNotifyIcon::CreateChildren(pugi::xml_node xmlNode)
  172. {
  173. SHostWnd *pHostWnd = (SHostWnd*)(GetTopLevelParent()->GetContainer());
  174. SASSERT(pHostWnd);
  175. m_MsgOnlyWnd = new CShellNotifyHwnd2(pHostWnd, this);
  176. SASSERT(IsWindow(m_MsgOnlyWnd->m_hWnd));
  177. SASSERT(m_iDefIcon < m_ArrIcon.GetCount());
  178. //SASSERT(m_ArrIcon.GetCount()>0);
  179. if (m_iDefIcon >= m_ArrIcon.GetCount())
  180. m_iDefIcon = 0;
  181. Create(m_MsgOnlyWnd->m_hWnd, m_ArrIcon.GetCount() == 0 ? GETRESPROVIDER->LoadIcon(_T("ICON_LOGO"), 16) : m_ArrIcon[m_iDefIcon]);
  182. return Show();
  183. }
  184. void SShellNotifyIcon::OnFinalRelease()
  185. {
  186. if (m_MsgOnlyWnd)
  187. {
  188. Hide();
  189. for (size_t i = 0; i < m_ArrIcon.GetCount(); i++)
  190. {
  191. DestroyIcon(m_ArrIcon[i]);
  192. }
  193. m_ArrIcon.RemoveAll();
  194. m_MsgOnlyWnd->PostMessage(WM_CLOSE);
  195. }
  196. }
  197. }