XTPTopLevelWndMsgNotifier.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:7k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPTopLevelWndMsgNotifier.cpp: implementation of the CXTPTopLevelWndMsgNotifier class.
  2. //
  3. // This file is a part of the XTREME CALENDAR MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "XTPTopLevelWndMsgNotifier.h"
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. #define XTP_TOPLEVELNOTIFIER_CHECKDATE_TIMEOUT 10 * 1000
  28. static LPCTSTR XTP_TOP_LEVEL_WND_NOTIFIER_NAME = _T("XTPTopLevelWndMsgNotifier");
  29. CXTPTopLevelWndMsgNotifier* XTPGetTopLevelWndMsgNotifier()
  30. {
  31. static CXTPTopLevelWndMsgNotifier s_TopLevelWndMsgNotifier;
  32. return &s_TopLevelWndMsgNotifier;
  33. }
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CXTPTopLevelWndMsgNotifier
  36. CXTPTopLevelWndMsgNotifier::CXTPTopLevelWndMsgNotifier()
  37. {
  38. ::ZeroMemory(&m_timeLastDate, sizeof(m_timeLastDate));
  39. ::ZeroMemory(&m_tziLast, sizeof(m_tziLast));
  40. }
  41. CXTPTopLevelWndMsgNotifier::~CXTPTopLevelWndMsgNotifier()
  42. {
  43. DestroyWindow();
  44. }
  45. BOOL CXTPTopLevelWndMsgNotifier::CreateWnd()
  46. {
  47. LPCTSTR pcszSimpleWndClass = AfxRegisterWndClass(0);
  48. CRect rcEmpty(0, 0, 0, 0);
  49. BOOL bCreated = CreateEx(0, pcszSimpleWndClass,
  50.  XTP_TOP_LEVEL_WND_NOTIFIER_NAME,
  51.  WS_POPUP, rcEmpty, NULL, 0);
  52. ::GetLocalTime(&m_timeLastDate);
  53. VERIFY (::GetTimeZoneInformation(&m_tziLast) != TIME_ZONE_ID_INVALID);
  54. SetTimer(1, XTP_TOPLEVELNOTIFIER_CHECKDATE_TIMEOUT, NULL);
  55. return bCreated;
  56. }
  57. void CXTPTopLevelWndMsgNotifier::Advise(CWnd* pWnd, UINT uWndMsg)
  58. {
  59. ASSERT(pWnd);
  60. if (m_hWnd == NULL)
  61. {
  62. VERIFY(CreateWnd());
  63. }
  64. // WARNING! Already Advised.
  65. ASSERT(-1 == m_arClients.FindExact(pWnd, uWndMsg));
  66. m_arClients.Remove(pWnd, uWndMsg);
  67. CLIENT_INFO clInf = {pWnd, msgAll};
  68. m_arClients.Add(clInf);
  69. }
  70. void CXTPTopLevelWndMsgNotifier::Unadvise(CWnd* pWnd, UINT uWndMsg)
  71. {
  72. // WARNING! Already Unadvised.
  73. ASSERT(m_arClients.FindExact(pWnd, uWndMsg) >= 0);
  74. m_arClients.Remove(pWnd, uWndMsg);
  75. if (m_arClients.GetSize() == 0 && m_hWnd)
  76. {
  77. VERIFY(DestroyWindow());
  78. }
  79. }
  80. void CXTPTopLevelWndMsgNotifier::SendToClients(UINT uWndMsg, WPARAM wParam, LPARAM lParam)
  81. {
  82. CClientsArray arClients;
  83. // prepare clients to local cache
  84. int nCount = (int)m_arClients.GetSize(), i;
  85. for (i = 0; i < nCount; i++)
  86. {
  87. CLIENT_INFO& rData = m_arClients.ElementAt(i);
  88. if (rData.m_uWndMsg == uWndMsg || rData.m_uWndMsg == msgAll)
  89. {
  90. arClients.Add(rData);
  91. }
  92. }
  93. // Send to clients from local cache
  94. nCount = (int)arClients.GetSize();
  95. for (i = 0; i < nCount; i++)
  96. {
  97. const CLIENT_INFO& rData = arClients.ElementAt(i);
  98. if (-1 == m_arClients.FindClient(rData.m_pWnd, rData.m_uWndMsg))
  99. {
  100. continue;
  101. }
  102. try
  103. {
  104. if (::IsWindow(rData.m_pWnd->GetSafeHwnd()))
  105. {
  106. ::SendMessage(rData.m_pWnd->GetSafeHwnd(), uWndMsg, wParam, lParam);
  107. }
  108. }
  109. catch(...)
  110. {
  111. ASSERT(FALSE);
  112. m_arClients.Remove(rData.m_pWnd, msgAll);
  113. }
  114. }
  115. if (m_arClients.GetSize() == 0 && m_hWnd)
  116. {
  117. VERIFY(DestroyWindow());
  118. }
  119. }
  120. /////////////////////////////////////////////////////////////////////////////
  121. //class CClientsArray : public CArray<CLIENT_INFO, CLIENT_INFO&>
  122. CXTPTopLevelWndMsgNotifier::CClientsArray::CClientsArray()
  123. {
  124. }
  125. CXTPTopLevelWndMsgNotifier::CClientsArray::~CClientsArray()
  126. {
  127. }
  128. int CXTPTopLevelWndMsgNotifier::CClientsArray::FindExact(CWnd* pWnd, UINT uWndMsg)
  129. {
  130. int nCount = (int)GetSize();
  131. for (int i = 0; i < nCount; i++)
  132. {
  133. const CLIENT_INFO& rData = ElementAt(i);
  134. if (rData.m_pWnd == pWnd && rData.m_uWndMsg == uWndMsg)
  135. {
  136. return i;
  137. }
  138. }
  139. return -1;
  140. }
  141. int CXTPTopLevelWndMsgNotifier::CClientsArray::FindClient(CWnd* pWnd, UINT uWndMsg)
  142. {
  143. int nCount = (int)GetSize();
  144. for (int i = 0; i < nCount; i++)
  145. {
  146. const CLIENT_INFO& rData = ElementAt(i);
  147. if (rData.m_pWnd == pWnd)
  148. {
  149. if (rData.m_uWndMsg == uWndMsg || uWndMsg == CXTPTopLevelWndMsgNotifier::msgAll)
  150. {
  151. return i;
  152. }
  153. }
  154. }
  155. return -1;
  156. }
  157. void CXTPTopLevelWndMsgNotifier::CClientsArray::Remove(CWnd* pWnd, UINT uWndMsg)
  158. {
  159. int nCount = (int)GetSize();
  160. for (int i = nCount-1; i >= 0; i--)
  161. {
  162. const CLIENT_INFO& rData = ElementAt(i);
  163. if (rData.m_pWnd == pWnd)
  164. {
  165. if (rData.m_uWndMsg == uWndMsg || uWndMsg == CXTPTopLevelWndMsgNotifier::msgAll)
  166. {
  167. RemoveAt(i);
  168. }
  169. }
  170. }
  171. }
  172. BEGIN_MESSAGE_MAP(CXTPTopLevelWndMsgNotifier, CWnd)
  173. ON_WM_TIMECHANGE()
  174. ON_WM_SYSCOLORCHANGE()
  175. ON_WM_TIMER()
  176. END_MESSAGE_MAP()
  177. /////////////////////////////////////////////////////////////////////////////
  178. // CXTPTopLevelWndMsgNotifier message handlers
  179. void CXTPTopLevelWndMsgNotifier::OnTimeChange()
  180. {
  181. _ProcessTimeZone();
  182. SendToClients(WM_TIMECHANGE, 0, 0);
  183. }
  184. void CXTPTopLevelWndMsgNotifier::OnSysColorChange()
  185. {
  186. SendToClients(WM_SYSCOLORCHANGE, 0, 0);
  187. }
  188. void CXTPTopLevelWndMsgNotifier::OnTimer(UINT_PTR uTimerID)
  189. {
  190. if (uTimerID == 1)
  191. {
  192. SYSTEMTIME timeCurrent;
  193. ::ZeroMemory(&timeCurrent, sizeof(timeCurrent));
  194. ::GetLocalTime(&timeCurrent);
  195. //Is date changed ?
  196. if (timeCurrent.wDay    != m_timeLastDate.wDay ||
  197. timeCurrent.wMonth  != m_timeLastDate.wMonth ||
  198. timeCurrent.wYear   != m_timeLastDate.wYear)
  199. {
  200. m_timeLastDate = timeCurrent;
  201. //OnTimeChange();
  202. SendToClients(WM_TIMECHANGE, 0, 0);
  203. }
  204. }
  205. }
  206. void CXTPTopLevelWndMsgNotifier::_ProcessTimeZone()
  207. {
  208. TIME_ZONE_INFORMATION tziCurrent;
  209. ::ZeroMemory(&tziCurrent, sizeof(tziCurrent));
  210. if (::GetTimeZoneInformation(&tziCurrent) == TIME_ZONE_ID_INVALID)
  211. {
  212. ASSERT(FALSE);
  213. return;
  214. }
  215. if (!IsTimeZoneEqual(tziCurrent, m_tziLast))
  216. {
  217. m_tziLast = tziCurrent;
  218. SendToClients(XTP_WM_TIME_ZONE_CHANGED, 0, 0);
  219. //TRACE(_T("XTP_WM_TIME_ZONE_CHANGED is sent n"));
  220. }
  221. }
  222. BOOL CXTPTopLevelWndMsgNotifier::IsTimeZoneEqual(const TIME_ZONE_INFORMATION& rTzi1, const TIME_ZONE_INFORMATION& rTzi2) const
  223. {
  224. return  rTzi1.Bias == rTzi2.Bias &&
  225. memcmp(&rTzi1.StandardDate, &rTzi2.StandardDate, sizeof(SYSTEMTIME)) == 0 &&
  226. rTzi1.StandardBias == rTzi2.StandardBias &&
  227. memcmp(&rTzi1.DaylightDate, &rTzi2.DaylightDate, sizeof(SYSTEMTIME)) == 0 &&
  228. rTzi1.DaylightBias == rTzi2.DaylightBias;
  229. //WCHAR StandardName[ 32 ];
  230. //WCHAR DaylightName[ 32 ];
  231. }