/thirdparty/wtl/atlwinx.h

http://crashrpt.googlecode.com/ · C++ Header · 525 lines · 414 code · 72 blank · 39 comment · 161 complexity · d50f6135c93b97597a9b580dce2f3010 MD5 · raw file

  1. // Windows Template Library - WTL version 8.1
  2. // Copyright (C) Microsoft Corporation. All rights reserved.
  3. //
  4. // This file is a part of the Windows Template Library.
  5. // The use and distribution terms for this software are covered by the
  6. // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
  7. // which can be found in the file CPL.TXT at the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by
  9. // the terms of this license. You must not remove this notice, or
  10. // any other, from this software.
  11. #ifndef __ATLWINX_H__
  12. #define __ATLWINX_H__
  13. #pragma once
  14. #ifndef __ATLAPP_H__
  15. #error atlwinx.h requires atlapp.h to be included first
  16. #endif
  17. #if (_ATL_VER >= 0x0700)
  18. #include <atlwin.h>
  19. #endif // (_ATL_VER >= 0x0700)
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // Classes in this file:
  22. //
  23. // _U_RECT
  24. // _U_MENUorID
  25. // _U_STRINGorID
  26. ///////////////////////////////////////////////////////////////////////////////
  27. // Command Chaining Macros
  28. #define CHAIN_COMMANDS(theChainClass) \
  29. if(uMsg == WM_COMMAND) \
  30. CHAIN_MSG_MAP(theChainClass)
  31. #define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \
  32. if(uMsg == WM_COMMAND) \
  33. CHAIN_MSG_MAP_ALT(theChainClass, msgMapID)
  34. #define CHAIN_COMMANDS_MEMBER(theChainMember) \
  35. if(uMsg == WM_COMMAND) \
  36. CHAIN_MSG_MAP_MEMBER(theChainMember)
  37. #define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \
  38. if(uMsg == WM_COMMAND) \
  39. CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID)
  40. ///////////////////////////////////////////////////////////////////////////////
  41. // Macros for parent message map to selectively reflect control messages
  42. // NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot
  43. // (and overridden in 2 cases - CContainedWindowT and CAxHostWindow)
  44. // Since we can't modify ATL, we'll provide the needed additions
  45. // in a separate function (that is not a member of CWindowImplRoot)
  46. namespace WTL
  47. {
  48. inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled,
  49. UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL)
  50. {
  51. if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg))
  52. {
  53. // The notification message doesn't match the filter.
  54. bHandled = FALSE;
  55. return 1;
  56. }
  57. HWND hWndChild = NULL;
  58. UINT_PTR idFrom = 0;
  59. switch(uMsg)
  60. {
  61. case WM_COMMAND:
  62. if(lParam != NULL) // not from a menu
  63. {
  64. hWndChild = (HWND)lParam;
  65. idFrom = (UINT_PTR)LOWORD(wParam);
  66. }
  67. break;
  68. case WM_NOTIFY:
  69. hWndChild = ((LPNMHDR)lParam)->hwndFrom;
  70. idFrom = ((LPNMHDR)lParam)->idFrom;
  71. break;
  72. #ifndef _WIN32_WCE
  73. case WM_PARENTNOTIFY:
  74. switch(LOWORD(wParam))
  75. {
  76. case WM_CREATE:
  77. case WM_DESTROY:
  78. hWndChild = (HWND)lParam;
  79. idFrom = (UINT_PTR)HIWORD(wParam);
  80. break;
  81. default:
  82. hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam));
  83. idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
  84. break;
  85. }
  86. break;
  87. #endif // !_WIN32_WCE
  88. case WM_DRAWITEM:
  89. if(wParam) // not from a menu
  90. {
  91. hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
  92. idFrom = (UINT_PTR)wParam;
  93. }
  94. break;
  95. case WM_MEASUREITEM:
  96. if(wParam) // not from a menu
  97. {
  98. hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID);
  99. idFrom = (UINT_PTR)wParam;
  100. }
  101. break;
  102. case WM_COMPAREITEM:
  103. if(wParam) // not from a menu
  104. {
  105. hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem;
  106. idFrom = (UINT_PTR)wParam;
  107. }
  108. break;
  109. case WM_DELETEITEM:
  110. if(wParam) // not from a menu
  111. {
  112. hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem;
  113. idFrom = (UINT_PTR)wParam;
  114. }
  115. break;
  116. case WM_VKEYTOITEM:
  117. case WM_CHARTOITEM:
  118. case WM_HSCROLL:
  119. case WM_VSCROLL:
  120. hWndChild = (HWND)lParam;
  121. idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
  122. break;
  123. case WM_CTLCOLORBTN:
  124. case WM_CTLCOLORDLG:
  125. case WM_CTLCOLOREDIT:
  126. case WM_CTLCOLORLISTBOX:
  127. case WM_CTLCOLORMSGBOX:
  128. case WM_CTLCOLORSCROLLBAR:
  129. case WM_CTLCOLORSTATIC:
  130. hWndChild = (HWND)lParam;
  131. idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
  132. break;
  133. default:
  134. break;
  135. }
  136. if((hWndChild == NULL) ||
  137. ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild)))
  138. {
  139. // Either hWndChild isn't valid, or
  140. // hWndChild doesn't match the filter.
  141. bHandled = FALSE;
  142. return 1;
  143. }
  144. if((idFromFilter != 0) && (idFromFilter != idFrom))
  145. {
  146. // The dialog control id doesn't match the filter.
  147. bHandled = FALSE;
  148. return 1;
  149. }
  150. ATLASSERT(::IsWindow(hWndChild));
  151. LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
  152. if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC))
  153. {
  154. // Try to prevent problems with WM_CTLCOLOR* messages when
  155. // the message wasn't really handled
  156. bHandled = FALSE;
  157. }
  158. return lResult;
  159. }
  160. }; // namespace WTL
  161. // Try to prevent problems with WM_CTLCOLOR* messages when
  162. // the message wasn't really handled
  163. #define REFLECT_NOTIFICATIONS_EX() \
  164. { \
  165. bHandled = TRUE; \
  166. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  167. if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \
  168. bHandled = FALSE; \
  169. if(bHandled) \
  170. return TRUE; \
  171. }
  172. #define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \
  173. { \
  174. bHandled = TRUE; \
  175. lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \
  176. if(bHandled) \
  177. return TRUE; \
  178. }
  179. #define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \
  180. { \
  181. bHandled = TRUE; \
  182. lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \
  183. if(bHandled) \
  184. return TRUE; \
  185. }
  186. #define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \
  187. { \
  188. bHandled = TRUE; \
  189. lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \
  190. if(bHandled) \
  191. return TRUE; \
  192. }
  193. #define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \
  194. { \
  195. bHandled = TRUE; \
  196. lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \
  197. if(bHandled) \
  198. return TRUE; \
  199. }
  200. #define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \
  201. { \
  202. bHandled = TRUE; \
  203. lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \
  204. if(bHandled) \
  205. return TRUE; \
  206. }
  207. #define REFLECT_COMMAND(id, code) \
  208. if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
  209. { \
  210. bHandled = TRUE; \
  211. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  212. if(bHandled) \
  213. return TRUE; \
  214. }
  215. #define REFLECT_COMMAND_ID(id) \
  216. if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \
  217. { \
  218. bHandled = TRUE; \
  219. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  220. if(bHandled) \
  221. return TRUE; \
  222. }
  223. #define REFLECT_COMMAND_CODE(code) \
  224. if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \
  225. { \
  226. bHandled = TRUE; \
  227. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  228. if(bHandled) \
  229. return TRUE; \
  230. }
  231. #define REFLECT_COMMAND_RANGE(idFirst, idLast) \
  232. if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
  233. { \
  234. bHandled = TRUE; \
  235. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  236. if(bHandled) \
  237. return TRUE; \
  238. }
  239. #define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \
  240. if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
  241. { \
  242. bHandled = TRUE; \
  243. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  244. if(bHandled) \
  245. return TRUE; \
  246. }
  247. #define REFLECT_NOTIFY(id, cd) \
  248. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
  249. { \
  250. bHandled = TRUE; \
  251. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  252. if(bHandled) \
  253. return TRUE; \
  254. }
  255. #define REFLECT_NOTIFY_ID(id) \
  256. if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
  257. { \
  258. bHandled = TRUE; \
  259. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  260. if(bHandled) \
  261. return TRUE; \
  262. }
  263. #define REFLECT_NOTIFY_CODE(cd) \
  264. if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
  265. { \
  266. bHandled = TRUE; \
  267. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  268. if(bHandled) \
  269. return TRUE; \
  270. }
  271. #define REFLECT_NOTIFY_RANGE(idFirst, idLast) \
  272. if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
  273. { \
  274. bHandled = TRUE; \
  275. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  276. if(bHandled) \
  277. return TRUE; \
  278. }
  279. #define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \
  280. if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
  281. { \
  282. bHandled = TRUE; \
  283. lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \
  284. if(bHandled) \
  285. return TRUE; \
  286. }
  287. ///////////////////////////////////////////////////////////////////////////////
  288. // Reflected message handler macros for message maps (for ATL 3.0)
  289. #if (_ATL_VER < 0x0700)
  290. #define REFLECTED_COMMAND_HANDLER(id, code, func) \
  291. if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \
  292. { \
  293. bHandled = TRUE; \
  294. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  295. if(bHandled) \
  296. return TRUE; \
  297. }
  298. #define REFLECTED_COMMAND_ID_HANDLER(id, func) \
  299. if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \
  300. { \
  301. bHandled = TRUE; \
  302. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  303. if(bHandled) \
  304. return TRUE; \
  305. }
  306. #define REFLECTED_COMMAND_CODE_HANDLER(code, func) \
  307. if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \
  308. { \
  309. bHandled = TRUE; \
  310. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  311. if(bHandled) \
  312. return TRUE; \
  313. }
  314. #define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
  315. if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
  316. { \
  317. bHandled = TRUE; \
  318. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  319. if(bHandled) \
  320. return TRUE; \
  321. }
  322. #define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \
  323. if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
  324. { \
  325. bHandled = TRUE; \
  326. lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
  327. if(bHandled) \
  328. return TRUE; \
  329. }
  330. #define REFLECTED_NOTIFY_HANDLER(id, cd, func) \
  331. if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
  332. { \
  333. bHandled = TRUE; \
  334. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  335. if(bHandled) \
  336. return TRUE; \
  337. }
  338. #define REFLECTED_NOTIFY_ID_HANDLER(id, func) \
  339. if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \
  340. { \
  341. bHandled = TRUE; \
  342. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  343. if(bHandled) \
  344. return TRUE; \
  345. }
  346. #define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \
  347. if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
  348. { \
  349. bHandled = TRUE; \
  350. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  351. if(bHandled) \
  352. return TRUE; \
  353. }
  354. #define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \
  355. if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
  356. { \
  357. bHandled = TRUE; \
  358. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  359. if(bHandled) \
  360. return TRUE; \
  361. }
  362. #define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \
  363. if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \
  364. { \
  365. bHandled = TRUE; \
  366. lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
  367. if(bHandled) \
  368. return TRUE; \
  369. }
  370. #endif // (_ATL_VER < 0x0700)
  371. ///////////////////////////////////////////////////////////////////////////////
  372. // Dual argument helper classes (for ATL 3.0)
  373. #if (_ATL_VER < 0x0700)
  374. namespace ATL
  375. {
  376. class _U_RECT
  377. {
  378. public:
  379. _U_RECT(LPRECT lpRect) : m_lpRect(lpRect)
  380. { }
  381. _U_RECT(RECT& rc) : m_lpRect(&rc)
  382. { }
  383. LPRECT m_lpRect;
  384. };
  385. class _U_MENUorID
  386. {
  387. public:
  388. _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu)
  389. { }
  390. _U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID))
  391. { }
  392. HMENU m_hMenu;
  393. };
  394. class _U_STRINGorID
  395. {
  396. public:
  397. _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString)
  398. { }
  399. _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID))
  400. { }
  401. LPCTSTR m_lpstr;
  402. };
  403. }; // namespace ATL
  404. #endif // (_ATL_VER < 0x0700)
  405. namespace WTL
  406. {
  407. ///////////////////////////////////////////////////////////////////////////////
  408. // Forward notifications support for message maps (for ATL 3.0)
  409. #if (_ATL_VER < 0x0700)
  410. // forward notifications support
  411. #define FORWARD_NOTIFICATIONS() \
  412. { \
  413. bHandled = TRUE; \
  414. lResult = WTL::Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \
  415. if(bHandled) \
  416. return TRUE; \
  417. }
  418. static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  419. {
  420. LRESULT lResult = 0;
  421. switch(uMsg)
  422. {
  423. case WM_COMMAND:
  424. case WM_NOTIFY:
  425. #ifndef _WIN32_WCE
  426. case WM_PARENTNOTIFY:
  427. #endif // !_WIN32_WCE
  428. case WM_DRAWITEM:
  429. case WM_MEASUREITEM:
  430. case WM_COMPAREITEM:
  431. case WM_DELETEITEM:
  432. case WM_VKEYTOITEM:
  433. case WM_CHARTOITEM:
  434. case WM_HSCROLL:
  435. case WM_VSCROLL:
  436. case WM_CTLCOLORBTN:
  437. case WM_CTLCOLORDLG:
  438. case WM_CTLCOLOREDIT:
  439. case WM_CTLCOLORLISTBOX:
  440. case WM_CTLCOLORMSGBOX:
  441. case WM_CTLCOLORSCROLLBAR:
  442. case WM_CTLCOLORSTATIC:
  443. lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam);
  444. break;
  445. default:
  446. bHandled = FALSE;
  447. break;
  448. }
  449. return lResult;
  450. }
  451. #endif // (_ATL_VER < 0x0700)
  452. }; // namespace WTL
  453. #endif // __ATLWINX_H__