diff foosdk/wtl/Include/atlwinx.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/wtl/Include/atlwinx.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,599 @@
+// Windows Template Library - WTL version 10.0
+// Copyright (C) Microsoft Corporation, WTL Team. 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
+// Microsoft Public License (http://opensource.org/licenses/MS-PL)
+// which can be found in the file MS-PL.txt at the root folder.
+
+#ifndef __ATLWINX_H__
+#define __ATLWINX_H__
+
+#pragma once
+
+#ifndef __ATLAPP_H__
+	#error atlwinx.h requires atlapp.h to be included first
+#endif
+
+#include <atlwin.h>
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes in this file:
+//
+// CWindowEx
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Additional macros needed for template classes
+
+#ifndef DECLARE_WND_CLASS_EX2
+  #define DECLARE_WND_CLASS_EX2(WndClassName, EnclosingClass, style, bkgnd) \
+  static ATL::CWndClassInfo& GetWndClassInfo() \
+  { \
+	static ATL::CWndClassInfo wc = \
+	{ \
+		{ sizeof(WNDCLASSEX), style, EnclosingClass::StartWindowProc, \
+		  0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
+		  NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
+	}; \
+	return wc; \
+  }
+#endif // DECLARE_WND_CLASS_EX2
+
+#ifndef DECLARE_WND_SUPERCLASS2
+  #define DECLARE_WND_SUPERCLASS2(WndClassName, EnclosingClass, OrigWndClassName) \
+  static ATL::CWndClassInfo& GetWndClassInfo() \
+  { \
+	static ATL::CWndClassInfo wc = \
+	{ \
+		{ sizeof(WNDCLASSEX), 0, EnclosingClass::StartWindowProc, \
+		  0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
+		  OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \
+	}; \
+	return wc; \
+  }
+#endif // DECLARE_WND_SUPERCLASS2
+
+
+///////////////////////////////////////////////////////////////////////////////
+// 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;
+	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;
+	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 = this->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(this->m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \
+		if(bHandled) \
+			return TRUE; \
+	}
+
+#define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \
+	{ \
+		bHandled = TRUE; \
+		lResult = WTL::WtlReflectNotificationsFiltered(this->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(this->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(this->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(this->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 = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
+		if(bHandled) \
+			return TRUE; \
+	}
+
+#define REFLECT_COMMAND_ID(id) \
+	if((uMsg == WM_COMMAND) && (id == LOWORD(wParam))) \
+	{ \
+		bHandled = TRUE; \
+		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
+		if(bHandled) \
+			return TRUE; \
+	}
+
+#define REFLECT_COMMAND_CODE(code) \
+	if((uMsg == WM_COMMAND) && (code == HIWORD(wParam))) \
+	{ \
+		bHandled = TRUE; \
+		lResult = this->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 = this->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 = this->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 = this->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 = this->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 = this->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 = this->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 = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
+		if(bHandled) \
+			return TRUE; \
+	}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// GetClassLong/SetClassLong redefinition to avoid problems with class members
+
+#ifdef SetClassLongPtrA
+  #undef SetClassLongPtrA
+  inline LONG_PTR SetClassLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
+  {
+	return ::SetClassLongA(hWnd, nIndex, LONG(dwNewLong));
+  }
+#endif
+
+#ifdef SetClassLongPtrW
+  #undef SetClassLongPtrW
+  inline LONG_PTR SetClassLongPtrW(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
+  {
+	return ::SetClassLongW(hWnd, nIndex, LONG(dwNewLong));
+  }
+#endif
+
+#ifdef GetClassLongPtrA
+  #undef GetClassLongPtrA
+  inline LONG_PTR GetClassLongPtrA(HWND hWnd, int nIndex)
+  {
+	return ::GetClassLongA(hWnd, nIndex);
+  }
+#endif
+
+#ifdef GetClassLongPtrW
+  #undef GetClassLongPtrW
+  inline LONG_PTR GetClassLongPtrW(HWND hWnd, int nIndex)
+  {
+	return ::GetClassLongW(hWnd, nIndex);
+  }
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CWindowEx - extension of ATL::CWindow
+
+namespace WTL
+{
+
+class CWindowEx : public ATL::CWindow
+{
+public:
+	CWindowEx(HWND hWnd = NULL) : ATL::CWindow(hWnd)
+	{ }
+
+	CWindowEx& operator =(HWND hWnd)
+	{
+		m_hWnd = hWnd;
+		return *this;
+	}
+
+	operator HWND() const
+	{
+		return m_hWnd;
+	}
+
+// Methods
+	BOOL PrintWindow(HDC hDC, UINT uFlags = 0)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return ::PrintWindow(m_hWnd, hDC, uFlags);
+	}
+
+	BOOL DragDetect(POINT pt)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return ::DragDetect(m_hWnd, pt);
+	}
+
+	BOOL DragDetect()
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+
+		POINT pt = {};
+		::GetCursorPos(&pt);
+		return ::DragDetect(m_hWnd, pt);
+	}
+
+	CWindowEx GetAncestor(UINT uFlags) const
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return CWindowEx(::GetAncestor(m_hWnd, uFlags));
+	}
+
+	// Note: Does not work properly on Vista Aero and above
+	BOOL AnimateWindow(DWORD dwFlags, DWORD dwTime = 200)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return ::AnimateWindow(m_hWnd, dwTime, dwFlags);
+	}
+
+	BOOL FlashWindowEx(DWORD dwFlags, UINT uCount, DWORD dwTimeout = 0)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+
+		FLASHWINFO fi = { sizeof(FLASHWINFO) };
+		fi.hwnd = m_hWnd;
+		fi.dwFlags = dwFlags;
+		fi.uCount = uCount;
+		fi.dwTimeout = dwTimeout;
+		return ::FlashWindowEx(&fi);
+	}
+
+	BOOL StopFlashWindowEx()
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+
+		FLASHWINFO fi = { sizeof(FLASHWINFO) };
+		fi.hwnd = m_hWnd;
+		fi.dwFlags = FLASHW_STOP;
+		return ::FlashWindowEx(&fi);
+	}
+
+// Class long properties
+	DWORD GetClassLong(int nIndex) const
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return ::GetClassLong(m_hWnd, nIndex);
+	}
+
+	DWORD SetClassLong(int nIndex, LONG dwNewLong)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return ::SetClassLong(m_hWnd, nIndex, dwNewLong);
+	}
+
+	ULONG_PTR GetClassLongPtr(int nIndex) const
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return ::GetClassLongPtr(m_hWnd, nIndex);
+	}
+
+	ULONG_PTR SetClassLongPtr(int nIndex, LONG_PTR dwNewLong)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		return ::SetClassLongPtr(m_hWnd, nIndex, dwNewLong);
+	}
+
+// Layered windows
+	BOOL SetLayeredWindowAttributes(COLORREF crlKey, BYTE byteAlpha, DWORD dwFlags)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
+
+		return ::SetLayeredWindowAttributes(m_hWnd, crlKey, byteAlpha, dwFlags);
+	}
+
+	BOOL UpdateLayeredWindow(HDC hdcDst, LPPOINT pptDst, LPSIZE psize, HDC hdcSrc, LPPOINT pptSrc, COLORREF crlKey, BLENDFUNCTION* pblend, DWORD dwFlags)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
+
+		return ::UpdateLayeredWindow(m_hWnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crlKey, pblend, dwFlags);
+	}
+
+	BOOL UpdateLayeredWindow(LPPOINT pptDst = NULL)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
+
+		return ::UpdateLayeredWindow(m_hWnd, NULL, pptDst, NULL, NULL, NULL, CLR_NONE, NULL, 0);
+	}
+
+	BOOL GetLayeredWindowAttributes(COLORREF* pcrlKey, BYTE* pbyteAlpha, DWORD* pdwFlags) const
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
+
+		return ::GetLayeredWindowAttributes(m_hWnd, pcrlKey, pbyteAlpha, pdwFlags);
+	}
+
+// Mouse tracking
+	BOOL StartTrackMouseLeave()
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+
+		TRACKMOUSEEVENT tme = {};
+		tme.cbSize = sizeof(TRACKMOUSEEVENT);
+		tme.dwFlags = TME_LEAVE;
+		tme.hwndTrack = m_hWnd;
+		return ::TrackMouseEvent(&tme);
+	}
+
+	BOOL StartTrackMouse(DWORD dwFlags, DWORD dwHoverTime = HOVER_DEFAULT)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+
+		TRACKMOUSEEVENT tme = {};
+		tme.cbSize = sizeof(TRACKMOUSEEVENT);
+		tme.dwFlags = dwFlags;
+		tme.hwndTrack = m_hWnd;
+		tme.dwHoverTime = dwHoverTime;
+		return ::TrackMouseEvent(&tme);
+	}
+
+	BOOL CancelTrackMouse(DWORD dwType)
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+
+		TRACKMOUSEEVENT tme = {};
+		tme.cbSize = sizeof(TRACKMOUSEEVENT);
+		tme.dwFlags = TME_CANCEL | dwType;
+		tme.hwndTrack = m_hWnd;
+		return ::TrackMouseEvent(&tme);
+	}
+
+// CString support
+#ifdef __ATLSTR_H__
+	int GetWindowText(ATL::CString& strText) const
+	{
+		int nLength = GetWindowTextLength();
+		LPTSTR pszText = strText.GetBuffer(nLength + 1);
+		nLength = ::GetWindowText(m_hWnd, pszText, nLength + 1);
+		strText.ReleaseBuffer(nLength);
+
+		return nLength;
+	}
+
+	UINT GetDlgItemText(int nID, ATL::CString& strText) const
+	{
+		ATLASSERT(::IsWindow(m_hWnd));
+
+		HWND hItem = GetDlgItem(nID);
+		if(hItem != NULL)
+		{
+			int nLength = ::GetWindowTextLength(hItem);
+			LPTSTR pszText = strText.GetBuffer(nLength + 1);
+			nLength = ::GetWindowText(hItem, pszText, nLength + 1);
+			strText.ReleaseBuffer(nLength);
+
+			return nLength;
+		}
+		else
+		{
+			strText.Empty();
+
+			return 0;
+		}
+	}
+#endif // __ATLSTR_H__
+};
+
+} // namespace WTL
+
+#endif // __ATLWINX_H__