| // 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__ |