Index: third_party/wtl/include/atlapp.h |
diff --git a/third_party/wtl/include/atlapp.h b/third_party/wtl/include/atlapp.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4a5e6a7064a85ab2f3715ce9781f6afe22b684d2 |
--- /dev/null |
+++ b/third_party/wtl/include/atlapp.h |
@@ -0,0 +1,1686 @@ |
+// 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 |
+// Microsoft Permissive License (Ms-PL) which can be found in the file |
+// Ms-PL.txt at the root of this distribution. |
+ |
+#ifndef __ATLAPP_H__ |
+#define __ATLAPP_H__ |
+ |
+#pragma once |
+ |
+#ifndef __cplusplus |
+ #error ATL requires C++ compilation (use a .cpp suffix) |
+#endif |
+ |
+#ifndef __ATLBASE_H__ |
+ #error atlapp.h requires atlbase.h to be included first |
+#endif |
+ |
+#ifndef _WIN32_WCE |
+ #if (WINVER < 0x0400) |
+ #error WTL requires Windows version 4.0 or higher |
+ #endif |
+ |
+ #if (_WIN32_IE < 0x0300) |
+ #error WTL requires IE version 3.0 or higher |
+ #endif |
+#endif |
+ |
+#ifdef _ATL_NO_COMMODULE |
+ #error WTL requires that _ATL_NO_COMMODULE is not defined |
+#endif // _ATL_NO_COMMODULE |
+ |
+#if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) |
+ #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT") |
+#endif // defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) |
+ |
+#include <limits.h> |
+#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) |
+ #include <process.h> // for _beginthreadex |
+#endif |
+ |
+#if (_ATL_VER < 0x0800) && !defined(_DEBUG) |
+ #include <stdio.h> |
+#endif |
+ |
+#include <commctrl.h> |
+#ifndef _WIN32_WCE |
+#pragma comment(lib, "comctl32.lib") |
+#endif // !_WIN32_WCE |
+ |
+#ifndef _WIN32_WCE |
+ #include "atlres.h" |
+#else // CE specific |
+ #include "atlresce.h" |
+#endif // _WIN32_WCE |
+ |
+// We need to disable this warning because of template class arguments |
+#pragma warning(disable: 4127) |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// WTL version number |
+ |
+#define _WTL_VER 0x0800 |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// Classes in this file: |
+// |
+// CMessageFilter |
+// CIdleHandler |
+// CMessageLoop |
+// |
+// CAppModule |
+// CServerAppModule |
+// |
+// Global functions: |
+// AtlGetDefaultGuiFont() |
+// AtlCreateBoldFont() |
+// AtlInitCommonControls() |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// Global support for Windows CE |
+ |
+#ifdef _WIN32_WCE |
+ |
+#ifndef SW_SHOWDEFAULT |
+ #define SW_SHOWDEFAULT SW_SHOWNORMAL |
+#endif // !SW_SHOWDEFAULT |
+ |
+// These get's OR-ed in a constant and will have no effect. |
+// Defining them reduces the number of #ifdefs required for CE. |
+#define LR_DEFAULTSIZE 0 |
+#define LR_LOADFROMFILE 0 |
+ |
+#ifndef SM_CXCURSOR |
+ #define SM_CXCURSOR 13 |
+#endif |
+#ifndef SM_CYCURSOR |
+ #define SM_CYCURSOR 14 |
+#endif |
+ |
+inline BOOL IsMenu(HMENU hMenu) |
+{ |
+ MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; |
+ ::SetLastError(0); |
+ BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii); |
+ if(!bRet) |
+ bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE : FALSE; |
+ return bRet; |
+} |
+ |
+#if (_WIN32_WCE >= 410) |
+extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight); |
+#endif // (_WIN32_WCE >= 410) |
+ |
+inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator) |
+{ |
+ __int64 multiple = nNumber * nNumerator; |
+ return static_cast<int>(multiple / nDenominator); |
+} |
+ |
+#if (_ATL_VER >= 0x0800) |
+ |
+#ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW |
+ #ifdef WS_OVERLAPPEDWINDOW |
+ #undef WS_OVERLAPPEDWINDOW |
+ #define WS_OVERLAPPEDWINDOW 0 |
+ #endif // WS_OVERLAPPEDWINDOW |
+#endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW |
+ |
+#ifndef RDW_FRAME |
+ #define RDW_FRAME 0 |
+#endif // !RDW_FRAME |
+ |
+#ifndef WM_WINDOWPOSCHANGING |
+ #define WM_WINDOWPOSCHANGING 0 |
+#endif // !WM_WINDOWPOSCHANGING |
+ |
+#define FreeResource(x) |
+#define UnlockResource(x) |
+ |
+namespace ATL |
+{ |
+ inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw() |
+ { return E_NOTIMPL; } |
+ inline HRESULT CComModule::RevokeClassObjects() throw() |
+ { return E_NOTIMPL; } |
+}; // namespace ATL |
+ |
+#ifndef lstrlenW |
+ #define lstrlenW (int)ATL::lstrlenW |
+#endif // lstrlenW |
+ |
+inline int WINAPI lstrlenA(LPCSTR lpszString) |
+{ return ATL::lstrlenA(lpszString); } |
+ |
+#ifdef lstrcpyn |
+ #undef lstrcpyn |
+ #define lstrcpyn ATL::lstrcpynW |
+#endif // lstrcpyn |
+ |
+#ifndef SetWindowLongPtrW |
+ inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong ) |
+ { |
+ return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) ); |
+ } |
+ #define SetWindowLongPtrW tmp_SetWindowLongPtrW |
+#endif |
+ |
+#ifndef GetWindowLongPtrW |
+ inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex ) |
+ { |
+ return( ::GetWindowLongW( hWnd, nIndex ) ); |
+ } |
+ #define GetWindowLongPtrW tmp_GetWindowLongPtrW |
+#endif |
+ |
+#ifndef LongToPtr |
+ #define LongToPtr(x) ((void*)x) |
+#endif |
+ |
+#ifndef PtrToInt |
+ #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) |
+#endif |
+ |
+#else // !(_ATL_VER >= 0x0800) |
+ |
+#ifdef lstrlenW |
+ #undef lstrlenW |
+ #define lstrlenW (int)::wcslen |
+#endif // lstrlenW |
+ |
+#define lstrlenA (int)strlen |
+ |
+#ifndef lstrcpyn |
+ inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength) |
+ { |
+ if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) |
+ return NULL; |
+ int nLen = __min(lstrlen(lpstrSrc), nLength - 1); |
+ LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR)); |
+ lpstrDest[nLen] = 0; |
+ return lpstrRet; |
+ } |
+#endif // !lstrcpyn |
+ |
+#ifndef lstrcpynW |
+ inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength) |
+ { |
+ return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode only |
+ } |
+#endif // !lstrcpynW |
+ |
+#ifndef lstrcpynA |
+ inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength) |
+ { |
+ if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) |
+ return NULL; |
+ int nLen = __min(lstrlenA(lpstrSrc), nLength - 1); |
+ LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char)); |
+ lpstrDest[nLen] = 0; |
+ return lpstrRet; |
+ } |
+#endif // !lstrcpyn |
+ |
+#ifdef TrackPopupMenu |
+ #undef TrackPopupMenu |
+#endif // TrackPopupMenu |
+ |
+#define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \ |
+static CWndClassInfo& GetWndClassInfo() \ |
+{ \ |
+ static CWndClassInfo wc = \ |
+ { \ |
+ { style, StartWindowProc, \ |
+ 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \ |
+ NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \ |
+ }; \ |
+ return wc; \ |
+} |
+ |
+#ifndef _MAX_FNAME |
+ #define _MAX_FNAME _MAX_PATH |
+#endif // _MAX_FNAME |
+ |
+#if (_WIN32_WCE < 400) |
+ #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i))) |
+#endif // (_WIN32_WCE < 400) |
+ |
+#if (_WIN32_WCE < 410) |
+ #define WHEEL_PAGESCROLL (UINT_MAX) |
+ #define WHEEL_DELTA 120 |
+#endif // (_WIN32_WCE < 410) |
+ |
+#ifdef DrawIcon |
+ #undef DrawIcon |
+#endif |
+ |
+#ifndef VARCMP_LT |
+ #define VARCMP_LT 0 |
+#endif |
+#ifndef VARCMP_EQ |
+ #define VARCMP_EQ 1 |
+#endif |
+#ifndef VARCMP_GT |
+ #define VARCMP_GT 2 |
+#endif |
+#ifndef VARCMP_NULL |
+ #define VARCMP_NULL 3 |
+#endif |
+ |
+#ifndef RDW_ALLCHILDREN |
+ #define RDW_ALLCHILDREN 0 |
+#endif |
+ |
+#endif // !(_ATL_VER >= 0x0800) |
+ |
+#endif // _WIN32_WCE |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// Global support for using original VC++ 6.0 headers with WTL |
+ |
+#ifndef _ATL_NO_OLD_HEADERS_WIN64 |
+#if !defined(_WIN64) && (_ATL_VER < 0x0700) |
+ |
+ #ifndef PSM_INSERTPAGE |
+ #define PSM_INSERTPAGE (WM_USER + 119) |
+ #endif // !PSM_INSERTPAGE |
+ |
+ #ifndef GetClassLongPtr |
+ #define GetClassLongPtrA GetClassLongA |
+ #define GetClassLongPtrW GetClassLongW |
+ #ifdef UNICODE |
+ #define GetClassLongPtr GetClassLongPtrW |
+ #else |
+ #define GetClassLongPtr GetClassLongPtrA |
+ #endif // !UNICODE |
+ #endif // !GetClassLongPtr |
+ |
+ #ifndef GCLP_HICONSM |
+ #define GCLP_HICONSM (-34) |
+ #endif // !GCLP_HICONSM |
+ |
+ #ifndef GetWindowLongPtr |
+ #define GetWindowLongPtrA GetWindowLongA |
+ #define GetWindowLongPtrW GetWindowLongW |
+ #ifdef UNICODE |
+ #define GetWindowLongPtr GetWindowLongPtrW |
+ #else |
+ #define GetWindowLongPtr GetWindowLongPtrA |
+ #endif // !UNICODE |
+ #endif // !GetWindowLongPtr |
+ |
+ #ifndef SetWindowLongPtr |
+ #define SetWindowLongPtrA SetWindowLongA |
+ #define SetWindowLongPtrW SetWindowLongW |
+ #ifdef UNICODE |
+ #define SetWindowLongPtr SetWindowLongPtrW |
+ #else |
+ #define SetWindowLongPtr SetWindowLongPtrA |
+ #endif // !UNICODE |
+ #endif // !SetWindowLongPtr |
+ |
+ #ifndef GWLP_WNDPROC |
+ #define GWLP_WNDPROC (-4) |
+ #endif |
+ #ifndef GWLP_HINSTANCE |
+ #define GWLP_HINSTANCE (-6) |
+ #endif |
+ #ifndef GWLP_HWNDPARENT |
+ #define GWLP_HWNDPARENT (-8) |
+ #endif |
+ #ifndef GWLP_USERDATA |
+ #define GWLP_USERDATA (-21) |
+ #endif |
+ #ifndef GWLP_ID |
+ #define GWLP_ID (-12) |
+ #endif |
+ |
+ #ifndef DWLP_MSGRESULT |
+ #define DWLP_MSGRESULT 0 |
+ #endif |
+ |
+ typedef long LONG_PTR; |
+ typedef unsigned long ULONG_PTR; |
+ typedef ULONG_PTR DWORD_PTR; |
+ |
+ #ifndef HandleToUlong |
+ #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) ) |
+ #endif |
+ #ifndef HandleToLong |
+ #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) ) |
+ #endif |
+ #ifndef LongToHandle |
+ #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h)) |
+ #endif |
+ #ifndef PtrToUlong |
+ #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) |
+ #endif |
+ #ifndef PtrToLong |
+ #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) ) |
+ #endif |
+ #ifndef PtrToUint |
+ #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) ) |
+ #endif |
+ #ifndef PtrToInt |
+ #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) |
+ #endif |
+ #ifndef PtrToUshort |
+ #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) ) |
+ #endif |
+ #ifndef PtrToShort |
+ #define PtrToShort( p ) ((short)(LONG_PTR)(p) ) |
+ #endif |
+ #ifndef IntToPtr |
+ #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i)) |
+ #endif |
+ #ifndef UIntToPtr |
+ #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui)) |
+ #endif |
+ #ifndef LongToPtr |
+ #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l)) |
+ #endif |
+ #ifndef ULongToPtr |
+ #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul)) |
+ #endif |
+ |
+#endif // !defined(_WIN64) && (_ATL_VER < 0x0700) |
+#endif // !_ATL_NO_OLD_HEADERS_WIN64 |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// Global support for SecureHelper functions |
+ |
+#ifndef _TRUNCATE |
+ #define _TRUNCATE ((size_t)-1) |
+#endif |
+ |
+#ifndef _ERRCODE_DEFINED |
+ #define _ERRCODE_DEFINED |
+ typedef int errno_t; |
+#endif |
+ |
+#ifndef _SECURECRT_ERRCODE_VALUES_DEFINED |
+ #define _SECURECRT_ERRCODE_VALUES_DEFINED |
+ #define EINVAL 22 |
+ #define STRUNCATE 80 |
+#endif |
+ |
+#ifndef _countof |
+ #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) |
+#endif |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// 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 |
+#if (_MSC_VER >= 1300) && defined(_MANAGED) |
+ __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; } |
+ __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; } |
+ __if_not_exists(_PSP::_PSP) { struct _PSP { }; } |
+#endif |
+ |
+// Define ATLVERIFY macro for ATL3 |
+#if (_ATL_VER < 0x0700) |
+ #ifndef ATLVERIFY |
+ #ifdef _DEBUG |
+ #define ATLVERIFY(expr) ATLASSERT(expr) |
+ #else |
+ #define ATLVERIFY(expr) (expr) |
+ #endif // DEBUG |
+ #endif // ATLVERIFY |
+#endif // (_ATL_VER < 0x0700) |
+ |
+// Forward declaration for ATL3 and ATL11 fix |
+#if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE) |
+ namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); }; |
+#endif |
+ |
+ |
+namespace WTL |
+{ |
+ |
+#if (_ATL_VER >= 0x0700) |
+ DECLARE_TRACE_CATEGORY(atlTraceUI); |
+ #ifdef _DEBUG |
+ __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI")); |
+ #endif // _DEBUG |
+#else // !(_ATL_VER >= 0x0700) |
+ enum wtlTraceFlags |
+ { |
+ atlTraceUI = 0x10000000 |
+ }; |
+#endif // !(_ATL_VER >= 0x0700) |
+ |
+// Windows version helper |
+inline bool AtlIsOldWindows() |
+{ |
+ OSVERSIONINFO ovi = { 0 }; |
+ ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
+ BOOL bRet = ::GetVersionEx(&ovi); |
+ return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90))); |
+} |
+ |
+// default GUI font helper |
+inline HFONT AtlGetDefaultGuiFont() |
+{ |
+#ifndef _WIN32_WCE |
+ return (HFONT)::GetStockObject(DEFAULT_GUI_FONT); |
+#else // CE specific |
+ return (HFONT)::GetStockObject(SYSTEM_FONT); |
+#endif // _WIN32_WCE |
+} |
+ |
+// bold font helper (NOTE: Caller owns the font, and should destroy it when done using it) |
+inline HFONT AtlCreateBoldFont(HFONT hFont = NULL) |
+{ |
+ if(hFont == NULL) |
+ hFont = AtlGetDefaultGuiFont(); |
+ ATLASSERT(hFont != NULL); |
+ HFONT hFontBold = NULL; |
+ LOGFONT lf = { 0 }; |
+ if(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)) |
+ { |
+ lf.lfWeight = FW_BOLD; |
+ hFontBold = ::CreateFontIndirect(&lf); |
+ ATLASSERT(hFontBold != NULL); |
+ } |
+ else |
+ { |
+ ATLASSERT(FALSE); |
+ } |
+ return hFontBold; |
+} |
+ |
+// Common Controls initialization helper |
+inline BOOL AtlInitCommonControls(DWORD dwFlags) |
+{ |
+ INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags }; |
+ BOOL bRet = ::InitCommonControlsEx(&iccx); |
+ ATLASSERT(bRet); |
+ return bRet; |
+} |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// RunTimeHelper - helper functions for Windows version and structure sizes |
+ |
+// Not for Windows CE |
+#if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) |
+ #define _WTL_NO_RUNTIME_STRUCT_SIZE |
+#endif |
+ |
+#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 !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) |
+ #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont) |
+#endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) |
+ |
+#endif // !_WTL_NO_RUNTIME_STRUCT_SIZE |
+ |
+namespace RunTimeHelper |
+{ |
+#ifndef _WIN32_WCE |
+ inline bool IsCommCtrl6() |
+ { |
+ DWORD dwMajor = 0, dwMinor = 0; |
+ HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); |
+ return (SUCCEEDED(hRet) && (dwMajor >= 6)); |
+ } |
+ |
+ inline bool IsVista() |
+ { |
+ OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; |
+ BOOL bRet = ::GetVersionEx(&ovi); |
+ return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6)); |
+ } |
+#endif // !_WIN32_WCE |
+ |
+ inline int SizeOf_REBARBANDINFO() |
+ { |
+ int nSize = sizeof(REBARBANDINFO); |
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) |
+ if(!(IsVista() && IsCommCtrl6())) |
+ nSize = REBARBANDINFO_V6_SIZE; |
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) |
+ return nSize; |
+ } |
+ |
+#if (_WIN32_WINNT >= 0x501) |
+ inline int SizeOf_LVGROUP() |
+ { |
+ int nSize = sizeof(LVGROUP); |
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) |
+ if(!IsVista()) |
+ nSize = LVGROUP_V5_SIZE; |
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) |
+ return nSize; |
+ } |
+ |
+ inline int SizeOf_LVTILEINFO() |
+ { |
+ int nSize = sizeof(LVTILEINFO); |
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) |
+ if(!IsVista()) |
+ nSize = LVTILEINFO_V5_SIZE; |
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) |
+ return nSize; |
+ } |
+#endif // (_WIN32_WINNT >= 0x501) |
+ |
+ inline int SizeOf_MCHITTESTINFO() |
+ { |
+ int nSize = sizeof(MCHITTESTINFO); |
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) |
+ if(!(IsVista() && IsCommCtrl6())) |
+ nSize = MCHITTESTINFO_V1_SIZE; |
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) |
+ return nSize; |
+ } |
+ |
+#ifndef _WIN32_WCE |
+ inline int SizeOf_NONCLIENTMETRICS() |
+ { |
+ int nSize = sizeof(NONCLIENTMETRICS); |
+#if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) |
+ if(!IsVista()) |
+ nSize = NONCLIENTMETRICS_V1_SIZE; |
+#endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) |
+ return nSize; |
+ } |
+#endif // !_WIN32_WCE |
+}; |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// ModuleHelper - helper functions for ATL3 and ATL7 module classes |
+ |
+namespace ModuleHelper |
+{ |
+ inline HINSTANCE GetModuleInstance() |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ return ATL::_AtlBaseModule.GetModuleInstance(); |
+#else // !(_ATL_VER >= 0x0700) |
+ return ATL::_pModule->GetModuleInstance(); |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+ |
+ inline HINSTANCE GetResourceInstance() |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ return ATL::_AtlBaseModule.GetResourceInstance(); |
+#else // !(_ATL_VER >= 0x0700) |
+ return ATL::_pModule->GetResourceInstance(); |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+ |
+ inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject) |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ ATL::_AtlWinModule.AddCreateWndData(pData, pObject); |
+#else // !(_ATL_VER >= 0x0700) |
+ ATL::_pModule->AddCreateWndData(pData, pObject); |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+ |
+ inline void* ExtractCreateWndData() |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ return ATL::_AtlWinModule.ExtractCreateWndData(); |
+#else // !(_ATL_VER >= 0x0700) |
+ return ATL::_pModule->ExtractCreateWndData(); |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+}; |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// SecureHelper - helper functions for VS2005 secure CRT |
+ |
+namespace SecureHelper |
+{ |
+ inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) |
+ { |
+#if _SECURE_ATL |
+ ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc); |
+#else |
+ if(cchDest > (size_t)lstrlenA(lpstrSrc)) |
+ ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL); |
+ else |
+ ATLASSERT(FALSE); |
+#endif |
+ } |
+ |
+ inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) |
+ { |
+#if _SECURE_ATL |
+ ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc); |
+#else |
+ if(cchDest > (size_t)lstrlenW(lpstrSrc)) |
+ ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL); |
+ else |
+ ATLASSERT(FALSE); |
+#endif |
+ } |
+ |
+ 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) |
+ { |
+#if _SECURE_ATL |
+ return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); |
+#else |
+ errno_t nRet = 0; |
+ if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) |
+ { |
+ nRet = EINVAL; |
+ } |
+ else if(cchCount == _TRUNCATE) |
+ { |
+ cchCount = __min(cchDest - 1, size_t(lstrlenA(lpstrSrc))); |
+ nRet = STRUNCATE; |
+ } |
+ else if(cchDest <= cchCount) |
+ { |
+ lpstrDest[0] = 0; |
+ nRet = EINVAL; |
+ } |
+ if(nRet == 0 || nRet == STRUNCATE) |
+ nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; |
+ ATLASSERT(nRet == 0 || nRet == STRUNCATE); |
+ return nRet; |
+#endif |
+ } |
+ |
+ inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount) |
+ { |
+#if _SECURE_ATL |
+ return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); |
+#else |
+ errno_t nRet = 0; |
+ if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) |
+ { |
+ nRet = EINVAL; |
+ } |
+ else if(cchCount == _TRUNCATE) |
+ { |
+ cchCount = __min(cchDest - 1, size_t(lstrlenW(lpstrSrc))); |
+ nRet = STRUNCATE; |
+ } |
+ else if(cchDest <= cchCount) |
+ { |
+ lpstrDest[0] = 0; |
+ nRet = EINVAL; |
+ } |
+ if(nRet == 0 || nRet == STRUNCATE) |
+ nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL; |
+ ATLASSERT(nRet == 0 || nRet == STRUNCATE); |
+ return nRet; |
+#endif |
+ } |
+ |
+ 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) |
+ { |
+#if _SECURE_ATL |
+ ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc); |
+#else |
+ if(cchDest > (size_t)lstrlenA(lpstrSrc)) |
+ ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL); |
+ else |
+ ATLASSERT(FALSE); |
+#endif |
+ } |
+ |
+ inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) |
+ { |
+#if _SECURE_ATL |
+ ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc); |
+#else |
+ if(cchDest > (size_t)lstrlenW(lpstrSrc)) |
+ ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL); |
+ else |
+ ATLASSERT(FALSE); |
+#endif |
+ } |
+ |
+ 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) |
+ { |
+#if _SECURE_ATL |
+ ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc); |
+#else |
+ if(cbDest >= cbSrc) |
+ memcpy(pDest, pSrc, cbSrc); |
+ else |
+ ATLASSERT(FALSE); |
+#endif |
+ } |
+ |
+ inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) |
+ { |
+#if _SECURE_ATL |
+ ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc); |
+#else |
+ if(cbDest >= cbSrc) |
+ memmove(pDest, pSrc, cbSrc); |
+ else |
+ ATLASSERT(FALSE); |
+#endif |
+ } |
+ |
+ inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) |
+ { |
+#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) |
+ return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); |
+#else |
+ cchBuff; // Avoid unused argument warning |
+ return _vstprintf(lpstrBuff, lpstrFormat, args); |
+#endif |
+ } |
+ |
+ inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) |
+ { |
+#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) |
+ return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); |
+#else |
+ cchBuff; // Avoid unused argument warning |
+ return ::wvsprintf(lpstrBuff, lpstrFormat, args); |
+#endif |
+ } |
+ |
+ 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 |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// 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; |
+}; |
+ |
+#ifndef _ATL_NO_OLD_NAMES |
+ // for compatilibility with old names only |
+ typedef CIdleHandler CUpdateUIObject; |
+ #define DoUpdate OnIdle |
+#endif // !_ATL_NO_OLD_NAMES |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// CMessageLoop - message loop implementation |
+ |
+class CMessageLoop |
+{ |
+public: |
+ ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter; |
+ ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler; |
+ MSG m_msg; |
+ |
+// 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); |
+ } |
+ |
+#ifndef _ATL_NO_OLD_NAMES |
+ // for compatilibility with old names only |
+ BOOL AddUpdateUI(CIdleHandler* pIdleHandler) |
+ { |
+ ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); |
+ return AddIdleHandler(pIdleHandler); |
+ } |
+ |
+ BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler) |
+ { |
+ ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); |
+ return RemoveIdleHandler(pIdleHandler); |
+ } |
+#endif // !_ATL_NO_OLD_NAMES |
+ |
+// 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: |
+#ifndef _WIN32_WCE |
+ case WM_NCMOUSEMOVE: |
+#endif // !_WIN32_WCE |
+ 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 both ATL3 and ATL7 |
+ |
+class CStaticDataInitCriticalSectionLock |
+{ |
+public: |
+#if (_ATL_VER >= 0x0700) |
+ ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock; |
+ |
+ CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false) |
+ { } |
+#endif // (_ATL_VER >= 0x0700) |
+ |
+ HRESULT Lock() |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ return m_cslock.Lock(); |
+#else // !(_ATL_VER >= 0x0700) |
+ ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit); |
+ return S_OK; |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+ |
+ void Unlock() |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ m_cslock.Unlock(); |
+#else // !(_ATL_VER >= 0x0700) |
+ ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit); |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+}; |
+ |
+ |
+class CWindowCreateCriticalSectionLock |
+{ |
+public: |
+#if (_ATL_VER >= 0x0700) |
+ ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock; |
+ |
+ CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false) |
+ { } |
+#endif // (_ATL_VER >= 0x0700) |
+ |
+ HRESULT Lock() |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ return m_cslock.Lock(); |
+#else // !(_ATL_VER >= 0x0700) |
+ ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate); |
+ return S_OK; |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+ |
+ void Unlock() |
+ { |
+#if (_ATL_VER >= 0x0700) |
+ m_cslock.Unlock(); |
+#else // !(_ATL_VER >= 0x0700) |
+ ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate); |
+#endif // !(_ATL_VER >= 0x0700) |
+ } |
+}; |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// CTempBuffer - helper class for stack allocations for ATL3 |
+ |
+#ifndef _WTL_STACK_ALLOC_THRESHOLD |
+ #define _WTL_STACK_ALLOC_THRESHOLD 512 |
+#endif |
+ |
+#if (_ATL_VER >= 0x0700) |
+ |
+using ATL::CTempBuffer; |
+ |
+#else // !(_ATL_VER >= 0x0700) |
+ |
+#ifndef SIZE_MAX |
+ #ifdef _WIN64 |
+ #define SIZE_MAX _UI64_MAX |
+ #else |
+ #define SIZE_MAX UINT_MAX |
+ #endif |
+#endif |
+ |
+#pragma warning(disable: 4284) // warning for operator -> |
+ |
+template<typename T, int t_nFixedBytes = 128> |
+class CTempBuffer |
+{ |
+public: |
+ CTempBuffer() : m_p(NULL) |
+ { |
+ } |
+ |
+ CTempBuffer(size_t nElements) : m_p(NULL) |
+ { |
+ Allocate(nElements); |
+ } |
+ |
+ ~CTempBuffer() |
+ { |
+ if(m_p != reinterpret_cast<T*>(m_abFixedBuffer)) |
+ free(m_p); |
+ } |
+ |
+ operator T*() const |
+ { |
+ return m_p; |
+ } |
+ |
+ T* operator ->() const |
+ { |
+ ATLASSERT(m_p != NULL); |
+ return m_p; |
+ } |
+ |
+ T* Allocate(size_t nElements) |
+ { |
+ ATLASSERT(nElements <= (SIZE_MAX / sizeof(T))); |
+ return AllocateBytes(nElements * sizeof(T)); |
+ } |
+ |
+ T* AllocateBytes(size_t nBytes) |
+ { |
+ ATLASSERT(m_p == NULL); |
+ if(nBytes > t_nFixedBytes) |
+ m_p = static_cast<T*>(malloc(nBytes)); |
+ else |
+ m_p = reinterpret_cast<T*>(m_abFixedBuffer); |
+ |
+ return m_p; |
+ } |
+ |
+private: |
+ T* m_p; |
+ BYTE m_abFixedBuffer[t_nFixedBytes]; |
+}; |
+ |
+#pragma warning(default: 4284) |
+ |
+#endif // !(_ATL_VER >= 0x0700) |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// CAppModule - module class for an application |
+ |
+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)) |
+ { |
+// need conditional code because types don't match in winuser.h |
+#ifdef _WIN64 |
+ ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this); |
+#else |
+ ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrToLong(this)); |
+#endif |
+ 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; |
+ }; |
+ |
+#ifdef _WIN64 |
+ static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
+#else |
+ static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
+#endif |
+ { |
+ if(uMsg == WM_SETTINGCHANGE) |
+ { |
+// need conditional code because types don't match in winuser.h |
+#ifdef _WIN64 |
+ CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); |
+#else |
+ CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); |
+#endif |
+ ATLASSERT(pModule != NULL); |
+ ATLASSERT(pModule->m_pSettingChangeNotify != NULL); |
+ const UINT uTimeout = 1500; // ms |
+ for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++) |
+ { |
+#if !defined(_WIN32_WCE) |
+ ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL); |
+#elif(_WIN32_WCE >= 400) // CE specific |
+ ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL); |
+#else // _WIN32_WCE < 400 specific |
+ uTimeout; |
+ ::SendMessage((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam); |
+#endif |
+ } |
+ return TRUE; |
+ } |
+ return FALSE; |
+ } |
+}; |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// 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() |
+ { |
+ 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 ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE) |
+ ::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; |
+#if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) |
+ 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; |
+ } |
+ |
+#if (_ATL_VER < 0x0700) |
+ // search for an occurence of string p2 in string p1 |
+ static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) |
+ { |
+ while(p1 != NULL && *p1 != NULL) |
+ { |
+ LPCTSTR p = p2; |
+ while(p != NULL && *p != NULL) |
+ { |
+ if(*p1 == *p) |
+ return ::CharNext(p1); |
+ p = ::CharNext(p); |
+ } |
+ p1 = ::CharNext(p1); |
+ } |
+ return NULL; |
+ } |
+#endif // (_ATL_VER < 0x0700) |
+}; |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// CString forward reference (enables CString use in atluser.h and atlgdi.h) |
+ |
+#if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) |
+ #define _WTL_USE_CSTRING |
+#endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) |
+ |
+#ifdef _WTL_USE_CSTRING |
+ class CString; // forward declaration (include atlmisc.h for the whole class) |
+#endif // _WTL_USE_CSTRING |
+ |
+// CString namespace |
+#ifndef _CSTRING_NS |
+ #ifdef __ATLSTR_H__ |
+ #define _CSTRING_NS ATL |
+ #else |
+ #define _CSTRING_NS WTL |
+ #endif |
+#endif // _CSTRING_NS |
+ |
+// Type classes namespace |
+#ifndef _WTYPES_NS |
+ #ifdef __ATLTYPES_H__ |
+ #define _WTYPES_NS |
+ #else |
+ #define _WTYPES_NS WTL |
+ #endif |
+#endif // _WTYPES_NS |
+ |
+}; // namespace WTL |
+ |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// General DLL version helpers |
+// (ATL3: excluded from atlbase.h if _ATL_DLL is defined; ATL11: removed) |
+ |
+#if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE) |
+ |
+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 < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) |
+ |
+ |
+// 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__ |