Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

434 lines
9.0 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLAPP_H__
  11. #define __ATLAPP_H__
  12. #ifndef __cplusplus
  13. #error ATL requires C++ compilation (use a .cpp suffix)
  14. #endif
  15. #ifndef __ATLBASE_H__
  16. #error atlapp.h requires atlbase.h to be included first
  17. #endif
  18. namespace ATL
  19. {
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Forward declarations
  22. class CMessageFilter;
  23. class CUpdateUIObject;
  24. class CMessageLoop;
  25. /////////////////////////////////////////////////////////////////////////////
  26. // Collection helpers - CSimpleArray & CSimpleMap for ATL 2.0/2.1
  27. #if (_ATL_VER < 0x0300)
  28. #ifndef ATLASSERT
  29. #define ATLASSERT(expr) _ASSERTE(expr)
  30. #endif
  31. #ifndef ATLTRACE2
  32. #define ATLTRACE2(cat, lev, msg) ATLTRACE(msg)
  33. #endif
  34. #ifndef ATLINLINE
  35. #define ATLINLINE inline
  36. #endif
  37. template <class T>
  38. class CSimpleArray
  39. {
  40. public:
  41. T* m_aT;
  42. int m_nSize;
  43. int m_nAllocSize;
  44. // Construction/destruction
  45. CSimpleArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  46. { }
  47. ~CSimpleArray()
  48. {
  49. RemoveAll();
  50. }
  51. // Operations
  52. int GetSize() const
  53. {
  54. return m_nSize;
  55. }
  56. BOOL Add(T& t)
  57. {
  58. if(m_nSize == m_nAllocSize)
  59. {
  60. T* aT;
  61. int nNewAllocSize = (m_nAllocSize == 0) ? 1 : (m_nSize * 2);
  62. aT = (T*)realloc(m_aT, nNewAllocSize * sizeof(T));
  63. if(aT == NULL)
  64. return FALSE;
  65. m_nAllocSize = nNewAllocSize;
  66. m_aT = aT;
  67. }
  68. m_nSize++;
  69. SetAtIndex(m_nSize - 1, t);
  70. return TRUE;
  71. }
  72. BOOL Remove(T& t)
  73. {
  74. int nIndex = Find(t);
  75. if(nIndex == -1)
  76. return FALSE;
  77. return RemoveAt(nIndex);
  78. }
  79. BOOL RemoveAt(int nIndex)
  80. {
  81. if(nIndex != (m_nSize - 1))
  82. memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(T));
  83. m_nSize--;
  84. return TRUE;
  85. }
  86. void RemoveAll()
  87. {
  88. if(m_nSize > 0)
  89. {
  90. free(m_aT);
  91. m_aT = NULL;
  92. m_nSize = 0;
  93. m_nAllocSize = 0;
  94. }
  95. }
  96. T& operator[] (int nIndex) const
  97. {
  98. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  99. return m_aT[nIndex];
  100. }
  101. T* GetData() const
  102. {
  103. return m_aT;
  104. }
  105. // Implementation
  106. void SetAtIndex(int nIndex, T& t)
  107. {
  108. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  109. m_aT[nIndex] = t;
  110. }
  111. int Find(T& t) const
  112. {
  113. for(int i = 0; i < m_nSize; i++)
  114. {
  115. if(m_aT[i] == t)
  116. return i;
  117. }
  118. return -1; // not found
  119. }
  120. };
  121. // for arrays of simple types
  122. template <class T>
  123. class CSimpleValArray : public CSimpleArray< T >
  124. {
  125. public:
  126. BOOL Add(T t)
  127. {
  128. return CSimpleArray< T >::Add(t);
  129. }
  130. BOOL Remove(T t)
  131. {
  132. return CSimpleArray< T >::Remove(t);
  133. }
  134. T operator[] (int nIndex) const
  135. {
  136. return CSimpleArray< T >::operator[](nIndex);
  137. }
  138. };
  139. // intended for small number of simple types or pointers
  140. template <class TKey, class TVal>
  141. class CSimpleMap
  142. {
  143. public:
  144. TKey* m_aKey;
  145. TVal* m_aVal;
  146. int m_nSize;
  147. // Construction/destruction
  148. CSimpleMap() : m_aKey(NULL), m_aVal(NULL), m_nSize(0)
  149. { }
  150. ~CSimpleMap()
  151. {
  152. RemoveAll();
  153. }
  154. // Operations
  155. int GetSize() const
  156. {
  157. return m_nSize;
  158. }
  159. BOOL Add(TKey key, TVal val)
  160. {
  161. TKey* pKey;
  162. pKey = (TKey*)realloc(m_aKey, (m_nSize + 1) * sizeof(TKey));
  163. if(pKey == NULL)
  164. return FALSE;
  165. m_aKey = pKey;
  166. TVal* pVal;
  167. pVal = (TVal*)realloc(m_aVal, (m_nSize + 1) * sizeof(TVal));
  168. if(pVal == NULL)
  169. return FALSE;
  170. m_aVal = pVal;
  171. m_nSize++;
  172. SetAtIndex(m_nSize - 1, key, val);
  173. return TRUE;
  174. }
  175. BOOL Remove(TKey key)
  176. {
  177. int nIndex = FindKey(key);
  178. if(nIndex == -1)
  179. return FALSE;
  180. if(nIndex != (m_nSize - 1))
  181. {
  182. memmove((void*)&m_aKey[nIndex], (void*)&m_aKey[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TKey));
  183. memmove((void*)&m_aVal[nIndex], (void*)&m_aVal[nIndex + 1], (m_nSize - (nIndex + 1)) * sizeof(TVal));
  184. }
  185. TKey* pKey;
  186. pKey = (TKey*)realloc(m_aKey, (m_nSize - 1) * sizeof(TKey));
  187. if(pKey != NULL || m_nSize == 1)
  188. m_aKey = pKey;
  189. TVal* pVal;
  190. pVal = (TVal*)realloc(m_aVal, (m_nSize - 1) * sizeof(TVal));
  191. if(pVal != NULL || m_nSize == 1)
  192. m_aVal = pVal;
  193. m_nSize--;
  194. return TRUE;
  195. }
  196. void RemoveAll()
  197. {
  198. if(m_nSize > 0)
  199. {
  200. free(m_aKey);
  201. free(m_aVal);
  202. m_aKey = NULL;
  203. m_aVal = NULL;
  204. m_nSize = 0;
  205. }
  206. }
  207. BOOL SetAt(TKey key, TVal val)
  208. {
  209. int nIndex = FindKey(key);
  210. if(nIndex == -1)
  211. return FALSE;
  212. SetAtIndex(nIndex, key, val);
  213. return TRUE;
  214. }
  215. TVal Lookup(TKey key) const
  216. {
  217. int nIndex = FindKey(key);
  218. if(nIndex == -1)
  219. return NULL; // must be able to convert
  220. return GetValueAt(nIndex);
  221. }
  222. TKey ReverseLookup(TVal val) const
  223. {
  224. int nIndex = FindVal(val);
  225. if(nIndex == -1)
  226. return NULL; // must be able to convert
  227. return GetKeyAt(nIndex);
  228. }
  229. TKey& GetKeyAt(int nIndex) const
  230. {
  231. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  232. return m_aKey[nIndex];
  233. }
  234. TVal& GetValueAt(int nIndex) const
  235. {
  236. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  237. return m_aVal[nIndex];
  238. }
  239. // Implementation
  240. void SetAtIndex(int nIndex, TKey& key, TVal& val)
  241. {
  242. ATLASSERT(nIndex >= 0 && nIndex < m_nSize);
  243. m_aKey[nIndex] = key;
  244. m_aVal[nIndex] = val;
  245. }
  246. int FindKey(TKey& key) const
  247. {
  248. for(int i = 0; i < m_nSize; i++)
  249. {
  250. if(m_aKey[i] == key)
  251. return i;
  252. }
  253. return -1; // not found
  254. }
  255. int FindVal(TVal& val) const
  256. {
  257. for(int i = 0; i < m_nSize; i++)
  258. {
  259. if(m_aVal[i] == val)
  260. return i;
  261. }
  262. return -1; // not found
  263. }
  264. };
  265. // WM_FORWARDMSG - used to forward a message to another window for processing
  266. // WPARAM - DWORD dwUserData - defined by user
  267. // LPARAM - LPMSG pMsg - a pointer to the MSG structure
  268. // return value - 0 if the message was not processed, nonzero if it was
  269. #define WM_FORWARDMSG 0x037F
  270. #endif //(_ATL_VER < 0x0300)
  271. /////////////////////////////////////////////////////////////////////////////
  272. // CMessageFilter - Interface for message filter support
  273. class ATL_NO_VTABLE CMessageFilter
  274. {
  275. public:
  276. virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
  277. };
  278. /////////////////////////////////////////////////////////////////////////////
  279. // CUpdateUIObject - Interface for update UI support
  280. class ATL_NO_VTABLE CUpdateUIObject
  281. {
  282. public:
  283. virtual BOOL DoUpdate() = 0;
  284. };
  285. /////////////////////////////////////////////////////////////////////////////
  286. // CMessageLoop - message loop implementation
  287. class CMessageLoop
  288. {
  289. public:
  290. CSimpleArray<CMessageFilter*> m_aMsgFilter;
  291. CSimpleArray<CUpdateUIObject*> m_aUpdateUI;
  292. MSG m_msg;
  293. // Message filter operations
  294. BOOL AddMessageFilter(CMessageFilter* pMessageFilter)
  295. {
  296. return m_aMsgFilter.Add(pMessageFilter);
  297. }
  298. BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter)
  299. {
  300. return m_aMsgFilter.Remove(pMessageFilter);
  301. }
  302. // Update UI operations
  303. BOOL AddUpdateUI(CUpdateUIObject* pUpdateUI)
  304. {
  305. return m_aUpdateUI.Add(pUpdateUI);
  306. }
  307. BOOL RemoveUpdateUI(CUpdateUIObject* pUpdateUI)
  308. {
  309. return m_aUpdateUI.Remove(pUpdateUI);
  310. }
  311. // message loop
  312. int Run()
  313. {
  314. BOOL bDoIdle = TRUE;
  315. int nIdleCount = 0;
  316. BOOL bRet;
  317. for(;;)
  318. {
  319. while(!::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE) && bDoIdle)
  320. {
  321. if(!OnIdle(nIdleCount++))
  322. bDoIdle = FALSE;
  323. }
  324. bRet = ::GetMessage(&m_msg, NULL, 0, 0);
  325. if(bRet == -1)
  326. {
  327. ATLTRACE2(atlTraceWindowing, 0, _T("::GetMessage returned -1 (error)\n"));
  328. continue; // error, don't process
  329. }
  330. else if(!bRet)
  331. {
  332. ATLTRACE2(atlTraceWindowing, 0, _T("CMessageLoop::Run - exiting\n"));
  333. break; // WM_QUIT, exit message loop
  334. }
  335. if(!PreTranslateMessage(&m_msg))
  336. {
  337. ::TranslateMessage(&m_msg);
  338. ::DispatchMessage(&m_msg);
  339. }
  340. if(IsIdleMessage(&m_msg))
  341. {
  342. bDoIdle = TRUE;
  343. nIdleCount = 0;
  344. }
  345. }
  346. return (int)m_msg.wParam;
  347. }
  348. static BOOL IsIdleMessage(MSG* pMsg)
  349. {
  350. // These messages should NOT cause idle processing
  351. switch(pMsg->message)
  352. {
  353. case WM_MOUSEMOVE:
  354. #ifndef UNDER_CE
  355. case WM_NCMOUSEMOVE:
  356. #endif //!UNDER_CE
  357. case WM_PAINT:
  358. case 0x0118: // WM_SYSTIMER (caret blink)
  359. return FALSE;
  360. }
  361. return TRUE;
  362. }
  363. // Overrideables
  364. // Override to change message filtering
  365. virtual BOOL PreTranslateMessage(MSG* pMsg)
  366. {
  367. // loop backwards
  368. for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)
  369. {
  370. CMessageFilter* pMessageFilter = m_aMsgFilter[i];
  371. if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg))
  372. return TRUE;
  373. }
  374. return FALSE; // not translated
  375. }
  376. // override to change idle UI updates
  377. virtual BOOL OnIdle(int /*nIdleCount*/)
  378. {
  379. for(int i = 0; i < m_aUpdateUI.GetSize(); i++)
  380. {
  381. CUpdateUIObject* pUpdateUI = m_aUpdateUI[i];
  382. if(pUpdateUI != NULL)
  383. pUpdateUI->DoUpdate();
  384. }
  385. return FALSE; // don't continue
  386. }
  387. };
  388. }; //namespace ATL
  389. #endif // __ATLAPP_H__