// Windows Template Library - WTL version 8.0 // Copyright (C) Microsoft Corporation. All rights reserved. // // This file is a part of the Windows Template Library. // The use and distribution terms for this software are covered by the // Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php) // which can be found in the file CPL.TXT at the root of this distribution. // By using this software in any fashion, you are agreeing to be bound by // the terms of this license. You must not remove this notice, or // any other, from this software. #ifndef __ATLWINX_H__ #define __ATLWINX_H__ #pragma once #ifndef __cplusplus #error ATL requires C++ compilation (use a .cpp suffix) #endif #ifndef __ATLAPP_H__ #error atlwinx.h requires atlapp.h to be included first #endif #if (_ATL_VER >= 0x0700) #include #endif // (_ATL_VER >= 0x0700) /////////////////////////////////////////////////////////////////////////////// // Classes in this file: // // _U_RECT // _U_MENUorID // _U_STRINGorID /////////////////////////////////////////////////////////////////////////////// // Command Chaining Macros #define CHAIN_COMMANDS(theChainClass) \ if(uMsg == WM_COMMAND) \ CHAIN_MSG_MAP(theChainClass) #define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \ if(uMsg == WM_COMMAND) \ CHAIN_MSG_MAP_ALT(theChainClass, msgMapID) #define CHAIN_COMMANDS_MEMBER(theChainMember) \ if(uMsg == WM_COMMAND) \ CHAIN_MSG_MAP_MEMBER(theChainMember) #define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \ if(uMsg == WM_COMMAND) \ CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID) /////////////////////////////////////////////////////////////////////////////// // Macros for parent message map to selectively reflect control messages // NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot // (and overridden in 2 cases - CContainedWindowT and CAxHostWindow) // Since we can't modify ATL, we'll provide the needed additions // in a separate function (that is not a member of CWindowImplRoot) namespace WTL { inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled, UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL) { if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg)) { // The notification message doesn't match the filter. bHandled = FALSE; return 1; } HWND hWndChild = NULL; UINT_PTR idFrom = 0; switch(uMsg) { case WM_COMMAND: if(lParam != NULL) // not from a menu { hWndChild = (HWND)lParam; idFrom = (UINT_PTR)LOWORD(wParam); } break; case WM_NOTIFY: hWndChild = ((LPNMHDR)lParam)->hwndFrom; idFrom = ((LPNMHDR)lParam)->idFrom; break; #ifndef _WIN32_WCE case WM_PARENTNOTIFY: switch(LOWORD(wParam)) { case WM_CREATE: case WM_DESTROY: hWndChild = (HWND)lParam; idFrom = (UINT_PTR)HIWORD(wParam); break; default: hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam)); idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); break; } break; #endif // !_WIN32_WCE case WM_DRAWITEM: if(wParam) // not from a menu { hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem; idFrom = (UINT_PTR)wParam; } break; case WM_MEASUREITEM: if(wParam) // not from a menu { hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID); idFrom = (UINT_PTR)wParam; } break; case WM_COMPAREITEM: if(wParam) // not from a menu { hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem; idFrom = (UINT_PTR)wParam; } break; case WM_DELETEITEM: if(wParam) // not from a menu { hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem; idFrom = (UINT_PTR)wParam; } break; case WM_VKEYTOITEM: case WM_CHARTOITEM: case WM_HSCROLL: case WM_VSCROLL: hWndChild = (HWND)lParam; idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); break; case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORMSGBOX: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: hWndChild = (HWND)lParam; idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild); break; default: break; } if((hWndChild == NULL) || ((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild))) { // Either hWndChild isn't valid, or // hWndChild doesn't match the filter. bHandled = FALSE; return 1; } if((idFromFilter != 0) && (idFromFilter != idFrom)) { // The dialog control id doesn't match the filter. bHandled = FALSE; return 1; } ATLASSERT(::IsWindow(hWndChild)); LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam); if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) { // Try to prevent problems with WM_CTLCOLOR* messages when // the message wasn't really handled bHandled = FALSE; } return lResult; } }; // namespace WTL // Try to prevent problems with WM_CTLCOLOR* messages when // the message wasn't really handled #define REFLECT_NOTIFICATIONS_EX() \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \ bHandled = FALSE; \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \ { \ bHandled = TRUE; \ lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \ { \ bHandled = TRUE; \ lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \ { \ bHandled = TRUE; \ lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \ { \ bHandled = TRUE; \ lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \ { \ bHandled = TRUE; \ lResult = WTL::WtlReflectNotificationsFiltered(m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \ if(bHandled) \ return TRUE; \ } #define REFLECT_COMMAND(id, code) \ if(uMsg == WM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_COMMAND_ID(id) \ if(uMsg == WM_COMMAND && id == LOWORD(wParam)) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_COMMAND_CODE(code) \ if(uMsg == WM_COMMAND && code == HIWORD(wParam)) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_COMMAND_RANGE(idFirst, idLast) \ if(uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \ if(uMsg == WM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFY(id, cd) \ if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFY_ID(id) \ if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFY_CODE(cd) \ if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFY_RANGE(idFirst, idLast) \ if(uMsg == WM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \ if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ { \ bHandled = TRUE; \ lResult = ReflectNotifications(uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } /////////////////////////////////////////////////////////////////////////////// // Reflected message handler macros for message maps (for ATL 3.0) #if (_ATL_VER < 0x0700) #define REFLECTED_COMMAND_HANDLER(id, code, func) \ if(uMsg == OCM_COMMAND && id == LOWORD(wParam) && code == HIWORD(wParam)) \ { \ bHandled = TRUE; \ lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_COMMAND_ID_HANDLER(id, func) \ if(uMsg == OCM_COMMAND && id == LOWORD(wParam)) \ { \ bHandled = TRUE; \ lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_COMMAND_CODE_HANDLER(code, func) \ if(uMsg == OCM_COMMAND && code == HIWORD(wParam)) \ { \ bHandled = TRUE; \ lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_COMMAND_RANGE_HANDLER(idFirst, idLast, func) \ if(uMsg == OCM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ { \ bHandled = TRUE; \ lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_COMMAND_RANGE_CODE_HANDLER(idFirst, idLast, code, func) \ if(uMsg == OCM_COMMAND && code == HIWORD(wParam) && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \ { \ bHandled = TRUE; \ lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_NOTIFY_HANDLER(id, cd, func) \ if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \ { \ bHandled = TRUE; \ lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_NOTIFY_ID_HANDLER(id, func) \ if(uMsg == OCM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom) \ { \ bHandled = TRUE; \ lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_NOTIFY_CODE_HANDLER(cd, func) \ if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \ { \ bHandled = TRUE; \ lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_NOTIFY_RANGE_HANDLER(idFirst, idLast, func) \ if(uMsg == OCM_NOTIFY && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ { \ bHandled = TRUE; \ lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #define REFLECTED_NOTIFY_RANGE_CODE_HANDLER(idFirst, idLast, cd, func) \ if(uMsg == OCM_NOTIFY && cd == ((LPNMHDR)lParam)->code && ((LPNMHDR)lParam)->idFrom >= idFirst && ((LPNMHDR)lParam)->idFrom <= idLast) \ { \ bHandled = TRUE; \ lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \ if(bHandled) \ return TRUE; \ } #endif // (_ATL_VER < 0x0700) /////////////////////////////////////////////////////////////////////////////// // Dual argument helper classes (for ATL 3.0) #if (_ATL_VER < 0x0700) namespace ATL { class _U_RECT { public: _U_RECT(LPRECT lpRect) : m_lpRect(lpRect) { } _U_RECT(RECT& rc) : m_lpRect(&rc) { } LPRECT m_lpRect; }; class _U_MENUorID { public: _U_MENUorID(HMENU hMenu) : m_hMenu(hMenu) { } _U_MENUorID(UINT nID) : m_hMenu((HMENU)LongToHandle(nID)) { } HMENU m_hMenu; }; class _U_STRINGorID { public: _U_STRINGorID(LPCTSTR lpString) : m_lpstr(lpString) { } _U_STRINGorID(UINT nID) : m_lpstr(MAKEINTRESOURCE(nID)) { } LPCTSTR m_lpstr; }; }; // namespace ATL #endif // (_ATL_VER < 0x0700) namespace WTL { /////////////////////////////////////////////////////////////////////////////// // Forward notifications support for message maps (for ATL 3.0) #if (_ATL_VER < 0x0700) // forward notifications support #define FORWARD_NOTIFICATIONS() \ { \ bHandled = TRUE; \ lResult = WTL::Atl3ForwardNotifications(m_hWnd, uMsg, wParam, lParam, bHandled); \ if(bHandled) \ return TRUE; \ } static LRESULT Atl3ForwardNotifications(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { LRESULT lResult = 0; switch(uMsg) { case WM_COMMAND: case WM_NOTIFY: #ifndef _WIN32_WCE case WM_PARENTNOTIFY: #endif // !_WIN32_WCE case WM_DRAWITEM: case WM_MEASUREITEM: case WM_COMPAREITEM: case WM_DELETEITEM: case WM_VKEYTOITEM: case WM_CHARTOITEM: case WM_HSCROLL: case WM_VSCROLL: case WM_CTLCOLORBTN: case WM_CTLCOLORDLG: case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORMSGBOX: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: lResult = ::SendMessage(::GetParent(hWnd), uMsg, wParam, lParam); break; default: bHandled = FALSE; break; } return lResult; } #endif // (_ATL_VER < 0x0700) }; // namespace WTL #endif // __ATLWINX_H__