diff foosdk/wtl/Include/atlapp.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/atlapp.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,1216 @@
+// 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 __ATLAPP_H__
+#define __ATLAPP_H__
+
+#pragma once
+
+#ifndef __cplusplus
+	#error WTL requires C++ compilation (use a .cpp suffix)
+#endif
+
+#ifndef __ATLBASE_H__
+	#error atlapp.h requires atlbase.h to be included first
+#endif
+
+#ifdef _WIN32_WCE
+	#error WTL10 doesn't support Windows CE
+#endif
+
+#ifdef _ATL_NO_COMMODULE
+	#error WTL requires that _ATL_NO_COMMODULE is not defined
+#endif
+
+#ifdef _ATL_NO_WIN_SUPPORT
+	#error WTL requires that _ATL_NO_WIN_SUPPORT is not defined
+#endif
+
+#if (_MSC_VER < 1400)
+	#error WTL10 requires C++ compiler version 14 (Visual C++ 2005) or higher
+#endif
+
+#if (WINVER < 0x0501)
+	#error WTL requires WINVER >= 0x0501
+#endif
+
+#if (_WIN32_WINNT < 0x0501)
+	#error WTL requires _WIN32_WINNT >= 0x0501
+#endif
+
+#if (_WIN32_IE < 0x0600)
+	#error WTL requires _WIN32_IE >= 0x0600
+#endif
+
+#if (_ATL_VER < 0x0800)
+	#error WTL10 requires ATL version 8 or higher
+#endif
+
+#ifdef _ATL_MIN_CRT
+	#error WTL10 doesn't support _ATL_MIN_CRT
+#endif
+
+#ifdef _ATL_NO_MSIMG
+	#error WTL10 doesn't support _ATL_NO_MSIMG
+#endif
+
+#include <limits.h>
+#ifdef _MT
+  #include <process.h>	// for _beginthreadex
+#endif
+
+#include <commctrl.h>
+#pragma comment(lib, "comctl32.lib")
+
+#include <commdlg.h>
+#include <shellapi.h>
+
+// Check for VS2005 without newer WinSDK
+#if (_MSC_VER == 1400) && !defined(RB_GETEXTENDEDSTYLE)
+	#error WTL10 requires WinSDK 6.0 ot higher
+#endif
+
+#include <uxtheme.h>
+#pragma comment(lib, "uxtheme.lib")
+
+#if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE)
+  #include <VersionHelpers.h>
+#endif
+
+#include "atlres.h"
+
+
+///////////////////////////////////////////////////////////////////////////////
+// WTL version number
+
+#define _WTL_VER	0x1000   // version 10.0
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes in this file:
+//
+// CMessageFilter
+// CIdleHandler
+// CMessageLoop
+//
+// CAppModule
+// CServerAppModule
+//
+// Global functions:
+//   AtlInitCommonControls()
+//   AtlGetDefaultGuiFont()
+//   AtlCreateControlFont()
+//   AtlCreateBoldFont()
+//   AtlGetStringPtr()
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Miscellaneous global support
+
+// define useful macros from winuser.h
+#ifndef IS_INTRESOURCE
+  #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
+#endif // IS_INTRESOURCE
+
+// protect template members from windowsx.h macros
+#ifdef _INC_WINDOWSX
+  #undef SubclassWindow
+#endif // _INC_WINDOWSX
+
+// define useful macros from windowsx.h
+#ifndef GET_X_LPARAM
+  #define GET_X_LPARAM(lParam)	((int)(short)LOWORD(lParam))
+#endif
+#ifndef GET_Y_LPARAM
+  #define GET_Y_LPARAM(lParam)	((int)(short)HIWORD(lParam))
+#endif
+
+// Dummy structs for compiling with /CLR
+#ifdef _MANAGED
+  __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; }
+  __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; }
+  __if_not_exists(_PSP::_PSP) { struct _PSP { }; }
+#endif
+
+// Forward declaration for ATL11 fix
+#if (_ATL_VER >= 0x0B00)
+  namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); }
+#endif
+
+#ifndef WM_MOUSEHWHEEL
+  #define WM_MOUSEHWHEEL                  0x020E
+#endif
+
+// Used for stack allocations with ATL::CTempBuffer
+#ifndef _WTL_STACK_ALLOC_THRESHOLD
+  #define _WTL_STACK_ALLOC_THRESHOLD   512
+#endif
+
+
+namespace WTL
+{
+
+DECLARE_TRACE_CATEGORY(atlTraceUI)
+#ifdef _DEBUG
+  __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI"));
+#endif // _DEBUG
+
+// Common Controls initialization helper
+inline BOOL AtlInitCommonControls(DWORD dwFlags)
+{
+	INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags };
+	BOOL bRet = ::InitCommonControlsEx(&iccx);
+	ATLASSERT(bRet);
+	return bRet;
+}
+
+// Default GUI font helper - "MS Shell Dlg" stock font
+inline HFONT AtlGetDefaultGuiFont()
+{
+	return (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
+}
+
+// Control font helper - default font for controls not in a dialog
+// (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
+inline HFONT AtlCreateControlFont()
+{
+	LOGFONT lf = {};
+	ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
+	HFONT hFont = ::CreateFontIndirect(&lf);
+	ATLASSERT(hFont != NULL);
+	return hFont;
+}
+
+// Bold font helper
+// (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
+inline HFONT AtlCreateBoldFont(HFONT hFont = NULL)
+{
+	LOGFONT lf = {};
+	if(hFont == NULL)
+		ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
+	else
+		ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
+	lf.lfWeight = FW_BOLD;
+	HFONT hFontBold =  ::CreateFontIndirect(&lf);
+	ATLASSERT(hFontBold != NULL);
+	return hFontBold;
+}
+
+// Resource string pointer
+inline LPCWSTR AtlGetStringPtr(UINT uID, int* pch = NULL)
+{
+	LPCWSTR lpstr = NULL;
+	int nRet = ::LoadStringW(ATL::_AtlBaseModule.GetResourceInstance(), uID, (LPWSTR)&lpstr, 0);
+	if(pch != NULL)
+		*pch = nRet;
+	return lpstr;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// RunTimeHelper - helper functions for Windows version and structure sizes
+
+#ifndef _WTL_NO_RUNTIME_STRUCT_SIZE
+
+#ifndef _SIZEOF_STRUCT
+  #define _SIZEOF_STRUCT(structname, member)  (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
+#endif
+
+#if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
+  #define REBARBANDINFO_V6_SIZE   _SIZEOF_STRUCT(REBARBANDINFO, cxHeader)
+#endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
+
+#if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
+  #define LVGROUP_V5_SIZE   _SIZEOF_STRUCT(LVGROUP, uAlign)
+#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
+
+#if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
+  #define LVTILEINFO_V5_SIZE   _SIZEOF_STRUCT(LVTILEINFO, puColumns)
+#endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
+
+#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
+  #define MCHITTESTINFO_V1_SIZE   _SIZEOF_STRUCT(MCHITTESTINFO, st)
+#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
+
+#if (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
+  #define NONCLIENTMETRICS_V1_SIZE   _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont)
+#endif // (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
+
+#ifndef TTTOOLINFO_V2_SIZE
+  #define TTTOOLINFO_V2_SIZE   _SIZEOF_STRUCT(TTTOOLINFO, lParam)
+#endif
+
+#endif // !_WTL_NO_RUNTIME_STRUCT_SIZE
+
+namespace RunTimeHelper
+{
+	inline bool IsCommCtrl6()
+	{
+		DWORD dwMajor = 0, dwMinor = 0;
+		HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
+		return (SUCCEEDED(hRet) && (dwMajor >= 6));
+	}
+
+	inline bool IsVista()
+	{
+#ifdef _versionhelpers_H_INCLUDED_
+		return ::IsWindowsVistaOrGreater();
+#else // !_versionhelpers_H_INCLUDED_
+		OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
+		BOOL bRet = ::GetVersionEx(&ovi);
+		return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6));
+#endif // _versionhelpers_H_INCLUDED_
+	}
+
+	inline bool IsThemeAvailable()
+	{
+		return IsCommCtrl6() && (::IsThemeActive() != FALSE) && (::IsAppThemed() != FALSE);
+	}
+
+	inline bool IsWin7()
+	{
+#ifdef _versionhelpers_H_INCLUDED_
+		return ::IsWindows7OrGreater();
+#else // !_versionhelpers_H_INCLUDED_
+		OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
+		BOOL bRet = ::GetVersionEx(&ovi);
+		return ((bRet != FALSE) && ((ovi.dwMajorVersion > 6) || ((ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1))));
+#endif // _versionhelpers_H_INCLUDED_
+	}
+
+	inline bool IsRibbonUIAvailable()
+	{
+		static INT iRibbonUI = -1;
+
+#if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
+		if (iRibbonUI == -1)
+		{
+			HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll"));
+			if (hRibbonDLL != NULL)
+			{
+				const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } };
+				// block - create instance
+				{
+					ATL::CComPtr<IUnknown> pIUIFramework;
+					iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0;
+				}
+				::FreeLibrary(hRibbonDLL);
+			}
+			else
+			{
+				iRibbonUI = 0;
+			}
+		}
+#endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
+
+		return (iRibbonUI == 1);
+	}
+
+	inline UINT SizeOf_REBARBANDINFO()
+	{
+		UINT uSize = sizeof(REBARBANDINFO);
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
+		if(!(IsVista() && IsCommCtrl6()))
+			uSize = REBARBANDINFO_V6_SIZE;
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
+		return uSize;
+	}
+
+  	inline UINT SizeOf_LVGROUP()
+	{
+		UINT uSize = sizeof(LVGROUP);
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
+		if(!IsVista())
+			uSize = LVGROUP_V5_SIZE;
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
+		return uSize;
+	}
+
+	inline UINT SizeOf_LVTILEINFO()
+	{
+		UINT uSize = sizeof(LVTILEINFO);
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
+		if(!IsVista())
+			uSize = LVTILEINFO_V5_SIZE;
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
+		return uSize;
+	}
+
+	inline UINT SizeOf_MCHITTESTINFO()
+	{
+		UINT uSize = sizeof(MCHITTESTINFO);
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
+		if(!(IsVista() && IsCommCtrl6()))
+			uSize = MCHITTESTINFO_V1_SIZE;
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
+		return uSize;
+	}
+
+	inline UINT SizeOf_NONCLIENTMETRICS()
+	{
+		UINT uSize = sizeof(NONCLIENTMETRICS);
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
+		if(!IsVista())
+			uSize = NONCLIENTMETRICS_V1_SIZE;
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
+		return uSize;
+	}
+
+	inline UINT SizeOf_TOOLINFO()
+	{
+		UINT uSize = sizeof(TOOLINFO);
+#ifndef _WTL_NO_RUNTIME_STRUCT_SIZE
+		if(!IsVista())
+			uSize = TTTOOLINFO_V2_SIZE;
+#endif
+		return uSize;
+	}
+} // namespace RunTimeHelper
+
+
+///////////////////////////////////////////////////////////////////////////////
+// ModuleHelper - helper functions for ATL (deprecated)
+
+namespace ModuleHelper
+{
+	inline HINSTANCE GetModuleInstance()
+	{
+		return ATL::_AtlBaseModule.GetModuleInstance();
+	}
+
+	inline HINSTANCE GetResourceInstance()
+	{
+		return ATL::_AtlBaseModule.GetResourceInstance();
+	}
+
+	inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject)
+	{
+		ATL::_AtlWinModule.AddCreateWndData(pData, pObject);
+	}
+
+	inline void* ExtractCreateWndData()
+	{
+		return ATL::_AtlWinModule.ExtractCreateWndData();
+	}
+} // namespace ModuleHelper
+
+
+///////////////////////////////////////////////////////////////////////////////
+// SecureHelper - WTL10 requires use of secure functions
+// these are here only for compatibility with existing projects
+
+namespace SecureHelper
+{
+	inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
+	{
+		ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc);
+	}
+
+	inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
+	{
+		ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc);
+	}
+
+	inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
+	{
+#ifdef _UNICODE
+		strcpyW_x(lpstrDest, cchDest, lpstrSrc);
+#else
+		strcpyA_x(lpstrDest, cchDest, lpstrSrc);
+#endif
+	}
+
+	inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount)
+	{
+		return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
+	}
+
+	inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount)
+	{
+		return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
+	}
+
+	inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount)
+	{
+#ifdef _UNICODE
+		return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount);
+#else
+		return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount);
+#endif
+	}
+
+	inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
+	{
+		ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc);
+	}
+
+	inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
+	{
+		ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc);
+	}
+
+	inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
+	{
+#ifdef _UNICODE
+		strcatW_x(lpstrDest, cchDest, lpstrSrc);
+#else
+		strcatA_x(lpstrDest, cchDest, lpstrSrc);
+#endif
+	}
+
+	inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
+	{
+		ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc);
+	}
+
+	inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
+	{
+		ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc);
+	}
+
+	inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
+	{
+		return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
+	}
+
+	inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
+	{
+		return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
+	}
+
+	inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
+	{
+		va_list args;
+		va_start(args, lpstrFormat);
+		int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
+		va_end(args);
+		return nRes;
+	}
+
+	inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
+	{
+		va_list args;
+		va_start(args, lpstrFormat);
+		int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
+		va_end(args);
+		return nRes;
+	}
+} // namespace SecureHelper
+
+
+///////////////////////////////////////////////////////////////////////////////
+// MinCrtHelper - WTL10 doesn't support _ATL_MIN_CRT,
+// these are here only for compatibility with existing projects
+
+namespace MinCrtHelper
+{
+	inline int _isspace(TCHAR ch)
+	{
+		return _istspace(ch);
+	}
+
+	inline int _isdigit(TCHAR ch)
+	{
+		return _istdigit(ch);
+	}
+
+	inline int _atoi(LPCTSTR str)
+	{
+		return _ttoi(str);
+	}
+
+	inline LPCTSTR _strrchr(LPCTSTR str, TCHAR ch)
+	{
+		return _tcsrchr(str, ch);
+	}
+
+	inline LPTSTR _strrchr(LPTSTR str, TCHAR ch)
+	{
+		return _tcsrchr(str, ch);
+	}
+} // namespace MinCrtHelper
+
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericWndClass - generic window class usable for subclassing
+
+// Use in dialog templates to specify a placeholder to be subclassed
+// Specify as a custom control with class name WTL_GenericWindow
+// Call Rregister() before creating dialog (for example, in WinMain)
+namespace GenericWndClass
+{
+	inline LPCTSTR GetName()
+	{
+		return _T("WTL_GenericWindow");
+	}
+
+	inline ATOM Register()
+	{
+		WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
+		wc.lpfnWndProc = ::DefWindowProc;
+		wc.hInstance = ModuleHelper::GetModuleInstance();
+		wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
+		wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+		wc.lpszClassName = GetName();
+		ATOM atom = ::RegisterClassEx(&wc);
+		ATLASSERT(atom != 0);
+		return atom;
+	}
+
+	inline BOOL Unregister()   // only needed for DLLs or tmp use
+	{
+		return ::UnregisterClass(GetName(), ModuleHelper::GetModuleInstance());
+	}
+} // namespace GenericWndClass
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CMessageFilter - Interface for message filter support
+
+class CMessageFilter
+{
+public:
+	virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CIdleHandler - Interface for idle processing
+
+class CIdleHandler
+{
+public:
+	virtual BOOL OnIdle() = 0;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CMessageLoop - message loop implementation
+
+class CMessageLoop
+{
+public:
+	ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter;
+	ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler;
+	MSG m_msg;
+
+	CMessageLoop()
+	{ }
+
+	virtual ~CMessageLoop()
+	{ }
+
+// Message filter operations
+	BOOL AddMessageFilter(CMessageFilter* pMessageFilter)
+	{
+		return m_aMsgFilter.Add(pMessageFilter);
+	}
+
+	BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter)
+	{
+		return m_aMsgFilter.Remove(pMessageFilter);
+	}
+
+// Idle handler operations
+	BOOL AddIdleHandler(CIdleHandler* pIdleHandler)
+	{
+		return m_aIdleHandler.Add(pIdleHandler);
+	}
+
+	BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler)
+	{
+		return m_aIdleHandler.Remove(pIdleHandler);
+	}
+
+// message loop
+	int Run()
+	{
+		BOOL bDoIdle = TRUE;
+		int nIdleCount = 0;
+		BOOL bRet;
+
+		for(;;)
+		{
+			while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
+			{
+				if(!OnIdle(nIdleCount++))
+					bDoIdle = FALSE;
+			}
+
+			bRet = ::GetMessage(&m_msg, NULL, 0, 0);
+
+			if(bRet == -1)
+			{
+				ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
+				continue;   // error, don't process
+			}
+			else if(!bRet)
+			{
+				ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
+				break;   // WM_QUIT, exit message loop
+			}
+
+			if(!PreTranslateMessage(&m_msg))
+			{
+				::TranslateMessage(&m_msg);
+				::DispatchMessage(&m_msg);
+			}
+
+			if(IsIdleMessage(&m_msg))
+			{
+				bDoIdle = TRUE;
+				nIdleCount = 0;
+			}
+		}
+
+		return (int)m_msg.wParam;
+	}
+
+	static BOOL IsIdleMessage(MSG* pMsg)
+	{
+		// These messages should NOT cause idle processing
+		switch(pMsg->message)
+		{
+		case WM_MOUSEMOVE:
+		case WM_NCMOUSEMOVE:
+		case WM_PAINT:
+		case 0x0118:	// WM_SYSTIMER (caret blink)
+			return FALSE;
+		}
+
+		return TRUE;
+	}
+
+// Overrideables
+	// Override to change message filtering
+	virtual BOOL PreTranslateMessage(MSG* pMsg)
+	{
+		// loop backwards
+		for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)
+		{
+			CMessageFilter* pMessageFilter = m_aMsgFilter[i];
+			if((pMessageFilter != NULL) && pMessageFilter->PreTranslateMessage(pMsg))
+				return TRUE;
+		}
+		return FALSE;   // not translated
+	}
+
+	// override to change idle processing
+	virtual BOOL OnIdle(int /*nIdleCount*/)
+	{
+		for(int i = 0; i < m_aIdleHandler.GetSize(); i++)
+		{
+			CIdleHandler* pIdleHandler = m_aIdleHandler[i];
+			if(pIdleHandler != NULL)
+				pIdleHandler->OnIdle();
+		}
+		return FALSE;   // don't continue
+	}
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock
+// internal classes to manage critical sections for ATL (deprecated)
+
+class CStaticDataInitCriticalSectionLock
+{
+public:
+	ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
+
+	CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false)
+	{ }
+
+	HRESULT Lock()
+	{
+		return m_cslock.Lock();
+	}
+
+	void Unlock()
+	{
+		m_cslock.Unlock();
+	}
+};
+
+
+class CWindowCreateCriticalSectionLock
+{
+public:
+	ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
+
+	CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false)
+	{ }
+
+	HRESULT Lock()
+	{
+		return m_cslock.Lock();
+	}
+
+	void Unlock()
+	{
+		m_cslock.Unlock();
+	}
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CAppModule - module class for an application
+
+#if (_MSC_VER == 1400)   // VS2005
+  #pragma warning(push)
+  #pragma warning(disable : 4244)
+  #pragma warning(disable : 4312)
+#endif
+
+class CAppModule : public ATL::CComModule
+{
+public:
+	DWORD m_dwMainThreadID;
+	ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap;
+	ATL::CSimpleArray<HWND>* m_pSettingChangeNotify;
+
+// Overrides of CComModule::Init and Term
+	HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
+	{
+		HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID);
+		if(FAILED(hRet))
+			return hRet;
+
+		m_dwMainThreadID = ::GetCurrentThreadId();
+		typedef ATL::CSimpleMap<DWORD, CMessageLoop*>   _mapClass;
+		m_pMsgLoopMap = NULL;
+		ATLTRY(m_pMsgLoopMap = new _mapClass);
+		if(m_pMsgLoopMap == NULL)
+			return E_OUTOFMEMORY;
+		m_pSettingChangeNotify = NULL;
+
+		return hRet;
+	}
+
+	void Term()
+	{
+		TermSettingChangeNotify();
+		delete m_pMsgLoopMap;
+		CComModule::Term();
+	}
+
+// Message loop map methods
+	BOOL AddMessageLoop(CMessageLoop* pMsgLoop)
+	{
+		CStaticDataInitCriticalSectionLock lock;
+		if(FAILED(lock.Lock()))
+		{
+			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
+			ATLASSERT(FALSE);
+			return FALSE;
+		}
+
+		ATLASSERT(pMsgLoop != NULL);
+		ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL);   // not in map yet
+
+		BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop);
+
+		lock.Unlock();
+
+		return bRet;
+	}
+
+	BOOL RemoveMessageLoop()
+	{
+		CStaticDataInitCriticalSectionLock lock;
+		if(FAILED(lock.Lock()))
+		{
+			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
+			ATLASSERT(FALSE);
+			return FALSE;
+		}
+
+		BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId());
+
+		lock.Unlock();
+
+		return bRet;
+	}
+
+	CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const
+	{
+		CStaticDataInitCriticalSectionLock lock;
+		if(FAILED(lock.Lock()))
+		{
+			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
+			ATLASSERT(FALSE);
+			return NULL;
+		}
+
+		CMessageLoop* pLoop =  m_pMsgLoopMap->Lookup(dwThreadID);
+
+		lock.Unlock();
+
+		return pLoop;
+	}
+
+// Setting change notify methods
+	// Note: Call this from the main thread for MSDI apps
+	BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc)
+	{
+		CStaticDataInitCriticalSectionLock lock;
+		if(FAILED(lock.Lock()))
+		{
+			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n"));
+			ATLASSERT(FALSE);
+			return FALSE;
+		}
+
+		if(m_pSettingChangeNotify == NULL)
+		{
+			typedef ATL::CSimpleArray<HWND>   _notifyClass;
+			ATLTRY(m_pSettingChangeNotify = new _notifyClass);
+			ATLASSERT(m_pSettingChangeNotify != NULL);
+		}
+
+		BOOL bRet = (m_pSettingChangeNotify != NULL);
+		if(bRet && (m_pSettingChangeNotify->GetSize() == 0))
+		{
+			// init everything
+			_ATL_EMPTY_DLGTEMPLATE templ;
+			HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc);
+			ATLASSERT(::IsWindow(hNtfWnd));
+			if(::IsWindow(hNtfWnd))
+			{
+				::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this);
+				bRet = m_pSettingChangeNotify->Add(hNtfWnd);
+			}
+			else
+			{
+				bRet = FALSE;
+			}
+		}
+
+		lock.Unlock();
+
+		return bRet;
+	}
+
+	void TermSettingChangeNotify()
+	{
+		CStaticDataInitCriticalSectionLock lock;
+		if(FAILED(lock.Lock()))
+		{
+			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n"));
+			ATLASSERT(FALSE);
+			return;
+		}
+
+		if((m_pSettingChangeNotify != NULL) && (m_pSettingChangeNotify->GetSize() > 0))
+			::DestroyWindow((*m_pSettingChangeNotify)[0]);
+		delete m_pSettingChangeNotify;
+		m_pSettingChangeNotify = NULL;
+
+		lock.Unlock();
+	}
+
+	BOOL AddSettingChangeNotify(HWND hWnd)
+	{
+		CStaticDataInitCriticalSectionLock lock;
+		if(FAILED(lock.Lock()))
+		{
+			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n"));
+			ATLASSERT(FALSE);
+			return FALSE;
+		}
+
+		ATLASSERT(::IsWindow(hWnd));
+		BOOL bRet = FALSE;
+		if(InitSettingChangeNotify() != FALSE)
+			bRet = m_pSettingChangeNotify->Add(hWnd);
+
+		lock.Unlock();
+
+		return bRet;
+	}
+
+	BOOL RemoveSettingChangeNotify(HWND hWnd)
+	{
+		CStaticDataInitCriticalSectionLock lock;
+		if(FAILED(lock.Lock()))
+		{
+			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n"));
+			ATLASSERT(FALSE);
+			return FALSE;
+		}
+
+		BOOL bRet = FALSE;
+		if(m_pSettingChangeNotify != NULL)
+			bRet = m_pSettingChangeNotify->Remove(hWnd);
+
+		lock.Unlock();
+
+		return bRet;
+	}
+
+// Implementation - setting change notify dialog template and dialog procedure
+	struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE
+	{
+		_ATL_EMPTY_DLGTEMPLATE()
+		{
+			memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE));
+			style = WS_POPUP;
+		}
+		WORD wMenu, wClass, wTitle;
+	};
+
+	static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+	{
+		if(uMsg == WM_SETTINGCHANGE)
+		{
+			CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
+			ATLASSERT(pModule != NULL);
+			ATLASSERT(pModule->m_pSettingChangeNotify != NULL);
+			const UINT uTimeout = 1500;   // ms
+			for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++)
+				::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL);
+
+			return TRUE;
+		}
+
+		return FALSE;
+	}
+};
+
+#if (_MSC_VER == 1400)   // VS2005
+  #pragma warning(pop)
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CServerAppModule - module class for a COM server application
+
+class CServerAppModule : public CAppModule
+{
+public:
+	HANDLE m_hEventShutdown;
+	bool m_bActivity;
+	DWORD m_dwTimeOut;
+	DWORD m_dwPause;
+
+// Override of CAppModule::Init
+	HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
+	{
+		m_dwTimeOut = 5000;
+		m_dwPause = 1000;
+		return CAppModule::Init(pObjMap, hInstance, pLibID);
+	}
+
+	void Term()
+	{
+		if((m_hEventShutdown != NULL) && ::CloseHandle(m_hEventShutdown))
+			m_hEventShutdown = NULL;
+		CAppModule::Term();
+	}
+
+// COM Server methods
+	LONG Unlock() throw()
+	{
+		LONG lRet = CComModule::Unlock();
+		if(lRet == 0)
+		{
+			m_bActivity = true;
+			::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero
+		}
+		return lRet;
+	}
+
+	void MonitorShutdown()
+	{
+		for(;;)
+		{
+			::WaitForSingleObject(m_hEventShutdown, INFINITE);
+			DWORD dwWait = 0;
+			do
+			{
+				m_bActivity = false;
+				dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
+			}
+			while(dwWait == WAIT_OBJECT_0);
+			// timed out
+			if(!m_bActivity && (m_nLockCnt == 0)) // if no activity let's really bail
+			{
+#if defined(_WIN32_DCOM) && defined(_ATL_FREE_THREADED)
+				::CoSuspendClassObjects();
+				if(!m_bActivity && (m_nLockCnt == 0))
+#endif
+					break;
+			}
+		}
+		// This handle should be valid now. If it isn't, 
+		// check if _Module.Term was called first (it shouldn't)
+		if(::CloseHandle(m_hEventShutdown))
+			m_hEventShutdown = NULL;
+		::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
+	}
+
+	bool StartMonitor()
+	{
+		m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
+		if(m_hEventShutdown == NULL)
+			return false;
+		DWORD dwThreadID = 0;
+#ifdef _MT
+		HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID);
+#else
+		HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
+#endif
+		bool bRet = (hThread != NULL);
+		if(bRet)
+			::CloseHandle(hThread);
+		return bRet;
+	}
+
+	static DWORD WINAPI MonitorProc(void* pv)
+	{
+		CServerAppModule* p = (CServerAppModule*)pv;
+		p->MonitorShutdown();
+		return 0;
+	}
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CRegKeyEx - not used any more, here only for compatibility with old projects
+
+typedef ATL::CRegKey CRegKeyEx;
+
+} // namespace WTL
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CString forward reference (enables CString use in atluser.h and atlgdi.h)
+
+#if (defined(_WTL_USE_CSTRING) || defined(_WTL_FORWARD_DECLARE_CSTRING)) && !defined(__ATLSTR_H__)
+  #include <atlstr.h>
+#endif
+
+// CString namespace
+#define _CSTRING_NS	ATL
+
+// Type classes namespace
+#define _WTYPES_NS
+
+
+///////////////////////////////////////////////////////////////////////////////
+// General DLL version helpers (removed in ATL11)
+
+#if (_ATL_VER >= 0x0B00)
+
+namespace ATL
+{
+
+inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
+{
+	ATLASSERT(pDllVersionInfo != NULL);
+	if(pDllVersionInfo == NULL)
+		return E_INVALIDARG;
+
+	// We must get this function explicitly because some DLLs don't implement it.
+	DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
+	if(pfnDllGetVersion == NULL)
+		return E_NOTIMPL;
+
+	return (*pfnDllGetVersion)(pDllVersionInfo);
+}
+
+inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
+{
+	HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
+	if(hInstDLL == NULL)
+		return E_FAIL;
+	HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
+	::FreeLibrary(hInstDLL);
+	return hRet;
+}
+
+// Common Control Versions:
+//   Win95/WinNT 4.0    maj=4 min=00
+//   IE 3.x     maj=4 min=70
+//   IE 4.0     maj=4 min=71
+inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
+{
+	ATLASSERT((pdwMajor != NULL) && (pdwMinor != NULL));
+	if((pdwMajor == NULL) || (pdwMinor == NULL))
+		return E_INVALIDARG;
+
+	DLLVERSIONINFO dvi;
+	::ZeroMemory(&dvi, sizeof(dvi));
+	dvi.cbSize = sizeof(dvi);
+	HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
+
+	if(SUCCEEDED(hRet))
+	{
+		*pdwMajor = dvi.dwMajorVersion;
+		*pdwMinor = dvi.dwMinorVersion;
+	}
+	else if(hRet == E_NOTIMPL)
+	{
+		// If DllGetVersion is not there, then the DLL is a version
+		// previous to the one shipped with IE 3.x
+		*pdwMajor = 4;
+		*pdwMinor = 0;
+		hRet = S_OK;
+	}
+
+	return hRet;
+}
+
+// Shell Versions:
+//   Win95/WinNT 4.0                    maj=4 min=00
+//   IE 3.x, IE 4.0 without Web Integrated Desktop  maj=4 min=00
+//   IE 4.0 with Web Integrated Desktop         maj=4 min=71
+//   IE 4.01 with Web Integrated Desktop        maj=4 min=72
+inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
+{
+	ATLASSERT((pdwMajor != NULL) && (pdwMinor != NULL));
+	if((pdwMajor == NULL) || (pdwMinor == NULL))
+		return E_INVALIDARG;
+
+	DLLVERSIONINFO dvi;
+	::ZeroMemory(&dvi, sizeof(dvi));
+	dvi.cbSize = sizeof(dvi);
+	HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
+
+	if(SUCCEEDED(hRet))
+	{
+		*pdwMajor = dvi.dwMajorVersion;
+		*pdwMinor = dvi.dwMinorVersion;
+	}
+	else if(hRet == E_NOTIMPL)
+	{
+		// If DllGetVersion is not there, then the DLL is a version
+		// previous to the one shipped with IE 4.x
+		*pdwMajor = 4;
+		*pdwMinor = 0;
+		hRet = S_OK;
+	}
+
+	return hRet;
+}
+
+} // namespace ATL
+
+#endif // (_ATL_VER >= 0x0B00)
+
+
+// These are always included
+#include "atlwinx.h"
+#include "atluser.h"
+#include "atlgdi.h"
+
+#ifndef _WTL_NO_AUTOMATIC_NAMESPACE
+using namespace WTL;
+#endif // !_WTL_NO_AUTOMATIC_NAMESPACE
+
+#endif // __ATLAPP_H__