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

对话框与窗口

开发平台:

Visual C++

  1. // XTPNotifyConnection.cpp: implementation of the CXTPNotifyConnection and CXTPNotifySink classes.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO 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 "XTPNotifyConnection.h"
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. #pragma warning(disable: 4571) // warning C4571: catch(...) blocks compiled with /EHs do not catch or re-throw Structured Exceptions
  28. /////////////////////////////////////////////////////////////////////////////
  29. static LPCTSTR XTP_NOTIFICATION_SINK_MT_MSGWND_NAME  = _T("XTPNotificationSinkMT_MsgWnd");
  30. /////////////////////////////////////////////////////////////////////////////
  31. //class CEmptySyncObject : public CSyncObject
  32. CXTPNotifyConnection::CEmptySyncObject::CEmptySyncObject() :
  33. CSyncObject(_T("XTPEmptySyncObject"))
  34. {
  35. }
  36. ////////////////////////////////////////////////////////////////////////////
  37. CXTPNotifyConnection::CXTPNotifyConnection()
  38. {
  39. m_nSendQueueCacheSize = 0;
  40. }
  41. CXTPNotifyConnection::~CXTPNotifyConnection()
  42. {
  43. RemoveAll();
  44. }
  45. void CXTPNotifyConnection::RemoveAll()
  46. {
  47. CSingleLock singleLock(GetDataLock(), TRUE);
  48. int nCount = (int)m_arrConnections.GetSize();
  49. for (int i = 0; i < nCount; i++)
  50. {
  51. CONNECTION_DESCRIPTOR* pCurElem = m_arrConnections[i];
  52. ASSERT(pCurElem);
  53. if (pCurElem)
  54. {
  55. delete pCurElem;
  56. }
  57. m_arrConnections[i] = NULL;
  58. }
  59. m_arrConnections.RemoveAll();
  60. }
  61. XTP_CONNECTION_ID CXTPNotifyConnection::Advise(XTP_NOTIFY_CODE Event, CXTPNotifySink* pSink)
  62. {
  63. ASSERT(pSink);
  64. CSingleLock singleLock(GetDataLock(), TRUE);
  65. CONNECTION_DESCRIPTOR* pNewElem = new CONNECTION_DESCRIPTOR;
  66. if (!pNewElem)
  67. {
  68. return 0;
  69. }
  70. pNewElem->dwConnectionID = (XTP_CONNECTION_ID)pNewElem;
  71. pNewElem->dwNotifyCode = Event;
  72. pNewElem->pSink = pSink;
  73. m_arrConnections.Add(pNewElem);
  74. return pNewElem->dwConnectionID;
  75. }
  76. void  CXTPNotifyConnection::Unadvise(XTP_CONNECTION_ID ConnectionID)
  77. {
  78. CSingleLock singleLock(GetDataLock(), TRUE);
  79. try
  80. {
  81. int nCount = (int)m_arrConnections.GetSize();
  82. int nFIndex = FindConnection(ConnectionID);
  83. if (nFIndex >= 0 && nFIndex < nCount)
  84. {
  85. CONNECTION_DESCRIPTOR* pElem = m_arrConnections[nFIndex];
  86. ASSERT(pElem);
  87. if (pElem)
  88. {
  89. delete pElem;
  90. }
  91. m_arrConnections.RemoveAt(nFIndex);
  92. }
  93. else
  94. {
  95. ASSERT(FALSE);
  96. }
  97. }
  98. catch(...)
  99. {
  100. ASSERT(FALSE);
  101. TRACE(_T("EXCEPTION! CXTPNotifyConnection::Unadvise(ConnectionID = %d)n"), ConnectionID);
  102. }
  103. }
  104. BOOL CXTPNotifyConnection::SendEvent(XTP_NOTIFY_CODE Event,
  105. WPARAM wParam , LPARAM lParam, DWORD dwFlags)
  106. {
  107. CSingleLock singleLock(GetDataLock(), TRUE);
  108. InternalAddRef();
  109. int nCount = (int)m_arrConnections.GetSize();
  110. if (m_arrSendQueueCache.GetSize() < nCount + m_nSendQueueCacheSize)
  111. {
  112. m_arrSendQueueCache.SetSize(nCount + m_nSendQueueCacheSize);
  113. }
  114. //******************************************************************************
  115. int nFirstLocalClientIndex = m_nSendQueueCacheSize;
  116. int i;
  117. for (i = 0; i < nCount; i++)
  118. {
  119. CONNECTION_DESCRIPTOR* pElem = m_arrConnections[i];
  120. ASSERT(pElem);
  121. if (pElem && pElem->dwNotifyCode == Event)
  122. {
  123. m_arrSendQueueCache.SetAt(m_nSendQueueCacheSize, *pElem);
  124. m_nSendQueueCacheSize++;
  125. }
  126. }
  127. int nLastLocalClientIndex = m_nSendQueueCacheSize-1;
  128. singleLock.Unlock();
  129. //************************************************************************
  130. for (i = nFirstLocalClientIndex; i <= nLastLocalClientIndex; i++)
  131. {
  132. singleLock.Lock();
  133. if (i >= m_arrSendQueueCache.GetSize())
  134. {
  135. ASSERT(FALSE);
  136. return FALSE;
  137. }
  138. CONNECTION_DESCRIPTOR& rElem = m_arrSendQueueCache.ElementAt(i);
  139. int nFIndex = FindConnection(rElem.dwConnectionID);
  140. if (nFIndex < 0)
  141. {
  142. // Unadvise was called inside OnEvent(...) Call
  143. continue;
  144. }
  145. try
  146. {
  147. CXTPNotifySink* ptrSink = rElem.pSink;
  148. singleLock.Unlock();
  149. if (ptrSink)
  150. {
  151. ptrSink->OnEvent(Event, wParam, lParam, dwFlags);
  152. }
  153. else
  154. {
  155. ASSERT(FALSE);
  156. TRACE(_T("CXTPNotifyConnection::SendEvent(Event = %d, wParam = %d, lParam = %d, dwFlags = %x) pSink = %xn"),
  157. Event, wParam, lParam, dwFlags, rElem.pSink);
  158. }
  159. }
  160. catch(...)
  161. {
  162. ASSERT(FALSE);
  163. TRACE(_T("EXCEPTION! CXTPNotifyConnection::SendEvent(Event = %d, wParam = %d, lParam = %d, dwFlags = %x)n"),
  164. Event, wParam, lParam, dwFlags);
  165. }
  166. }
  167. //==============================================================================
  168. singleLock.Lock();
  169. m_nSendQueueCacheSize = nFirstLocalClientIndex;
  170. singleLock.Unlock();
  171. InternalRelease();
  172. return (nFirstLocalClientIndex <= nLastLocalClientIndex);
  173. }
  174. int CXTPNotifyConnection::FindConnection(XTP_CONNECTION_ID ConnectionID)
  175. {
  176. CSingleLock singleLock(GetDataLock(), TRUE);
  177. int nCount = (int)m_arrConnections.GetSize();
  178. for (int i = 0; i < nCount; i++)
  179. {
  180. CONNECTION_DESCRIPTOR* pCurElem = m_arrConnections[i];
  181. ASSERT(pCurElem);
  182. if (pCurElem)
  183. {
  184. if (pCurElem->dwConnectionID == ConnectionID)
  185. {
  186. return i;
  187. }
  188. }
  189. }
  190. return -1;
  191. }
  192. ////////////////////////////////////////////////////////////////////////////
  193. //class CXTPNotifyConnectionMT : public CXTPNotifyConnection
  194. CXTPNotifyConnectionMT::CXTPNotifyConnectionMT()
  195. {
  196. }
  197. CXTPNotifyConnectionMT::~CXTPNotifyConnectionMT()
  198. {
  199. }
  200. ////////////////////////////////////////////////////////////////////////////
  201. BEGIN_MESSAGE_MAP(CXTPNotifySinkImplMTMsgWnd, CWnd)
  202. ON_REGISTERED_MESSAGE(xtp_wm_NotificationSinkMTOnEvent, OnInterThreadEvent)
  203. END_MESSAGE_MAP()
  204. CXTPNotifySinkImplMTMsgWnd::CXTPNotifySinkImplMTMsgWnd()
  205. {
  206. }
  207. CXTPNotifySinkImplMTMsgWnd::~CXTPNotifySinkImplMTMsgWnd()
  208. {
  209. }
  210. BOOL CXTPNotifySinkImplMTMsgWnd::CreateWnd()
  211. {
  212. LPCTSTR pcszSimpleWndClass = AfxRegisterWndClass(0);
  213. CRect rcEmpty(0, 0, 0, 0);
  214. BOOL bCreated = CreateEx(0, pcszSimpleWndClass,
  215. XTP_NOTIFICATION_SINK_MT_MSGWND_NAME,
  216. WS_POPUP, rcEmpty, NULL, 0);
  217. ASSERT(bCreated);
  218. return bCreated;
  219. }
  220. //////////////////////////////////////////////////////////////////////////
  221. // CXTPNotifySink
  222. CXTPNotifySink::CXTPNotifySink()
  223. {
  224. }
  225. CXTPNotifySink::~CXTPNotifySink()
  226. {
  227. UnadviseAll();
  228. }
  229. XTP_CONNECTION_ID CXTPNotifySink::Advise(CXTPNotifyConnection* pConnection,
  230. XTP_NOTIFY_CODE dwNotifyCode)
  231. {
  232. ASSERT(pConnection);
  233. if (!pConnection)
  234. {
  235. return 0;
  236. }
  237. XTP_CONNECTION_ID dwConnectionID = pConnection->Advise(dwNotifyCode, this);
  238. ASSERT(dwConnectionID);
  239. if (dwConnectionID)
  240. {
  241. ADVISE_DESCRIPTOR advDataNew;
  242. ASSERT(!m_mapAdviseData.Lookup(dwConnectionID, advDataNew));
  243. advDataNew.dwConnectionID = dwConnectionID;
  244. advDataNew.pConnection = pConnection;
  245. advDataNew.dwNotifyCode = dwNotifyCode;
  246. pConnection->InternalAddRef();
  247. m_mapAdviseData.SetAt(dwConnectionID, advDataNew);
  248. }
  249. return dwConnectionID;
  250. }
  251. void CXTPNotifySink::UnadviseAll()
  252. {
  253. XTP_CONNECTION_ID ConnectionID = 0;
  254. ADVISE_DESCRIPTOR advData;
  255. POSITION pos = m_mapAdviseData.GetStartPosition();
  256. while (pos)
  257. {
  258. m_mapAdviseData.GetNextAssoc(pos, ConnectionID, advData);
  259. if (advData.pConnection)
  260. {
  261. advData.pConnection->Unadvise(advData.dwConnectionID);
  262. advData.pConnection->InternalRelease();
  263. }
  264. }
  265. m_mapAdviseData.RemoveAll();
  266. }
  267. void CXTPNotifySink::Unadvise(XTP_CONNECTION_ID ConnectionID)
  268. {
  269. ADVISE_DESCRIPTOR advData;
  270. if (m_mapAdviseData.Lookup(ConnectionID, advData))
  271. {
  272. if (advData.pConnection)
  273. {
  274. advData.pConnection->Unadvise(advData.dwConnectionID);
  275. advData.pConnection->InternalRelease();
  276. }
  277. m_mapAdviseData.RemoveKey(ConnectionID);
  278. }
  279. else
  280. {
  281. ASSERT(FALSE);
  282. }
  283. }