1 // Windows Template Library - WTL version 9.0
2 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved.
4 // This file is a part of the Windows Template Library.
5 // The use and distribution terms for this software are covered by the
6 // Common Public License 1.0 (http://opensource.org/licenses/cpl1.0.php)
7 // which can be found in the file CPL.TXT at the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by
9 // the terms of this license. You must not remove this notice, or
10 // any other, from this software.
18 #error WTL requires C++ compilation (use a .cpp suffix)
22 #error atlapp.h requires atlbase.h to be included first
27 #error WTL requires Windows version 4.0 or higher
30 #if (_WIN32_IE < 0x0300)
31 #error WTL requires IE version 3.0 or higher
35 #ifdef _ATL_NO_COMMODULE
36 #error WTL requires that _ATL_NO_COMMODULE is not defined
39 #if (_ATL_VER >= 0x0900) && defined(_ATL_MIN_CRT)
40 #error _ATL_MIN_CRT is not supported with ATL 9.0 and higher
43 #if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT)
44 #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT")
48 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
49 #include <process.h> // for _beginthreadex
52 #if (_ATL_VER < 0x0800) && !defined(_DEBUG)
58 #pragma comment(lib, "comctl32.lib")
61 #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501)
62 #include <VersionHelpers.h>
71 // We need to disable this warning because of template class arguments
72 #pragma warning(disable: 4127)
74 #if (_ATL_VER >= 0x0900) && !defined(_SECURE_ATL)
79 ///////////////////////////////////////////////////////////////////////////////
82 #define _WTL_VER 0x0900
85 ///////////////////////////////////////////////////////////////////////////////
86 // Classes in this file:
98 // AtlGetDefaultGuiFont()
99 // AtlCreateControlFont()
100 // AtlCreateBoldFont()
101 // AtlInitCommonControls()
104 ///////////////////////////////////////////////////////////////////////////////
105 // Global support for Windows CE
109 #ifndef SW_SHOWDEFAULT
110 #define SW_SHOWDEFAULT SW_SHOWNORMAL
111 #endif // !SW_SHOWDEFAULT
113 // These get's OR-ed in a constant and will have no effect.
114 // Defining them reduces the number of #ifdefs required for CE.
115 #define LR_DEFAULTSIZE 0
116 #define LR_LOADFROMFILE 0
119 #define SM_CXCURSOR 13
122 #define SM_CYCURSOR 14
125 inline BOOL
IsMenu(HMENU hMenu
)
127 MENUITEMINFO mii
= { sizeof(MENUITEMINFO
) };
129 BOOL bRet
= ::GetMenuItemInfo(hMenu
, 0, TRUE
, &mii
);
131 bRet
= (::GetLastError() != ERROR_INVALID_MENU_HANDLE
) ? TRUE
: FALSE
;
135 #if (_WIN32_WCE >= 410)
136 extern "C" void WINAPI
ListView_SetItemSpacing(HWND hwndLV
, int iHeight
);
137 #endif // (_WIN32_WCE >= 410)
139 inline int MulDiv(IN
int nNumber
, IN
int nNumerator
, IN
int nDenominator
)
141 __int64 multiple
= nNumber
* nNumerator
;
142 return static_cast<int>(multiple
/ nDenominator
);
145 #if (_ATL_VER >= 0x0800)
147 #ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW
148 #ifdef WS_OVERLAPPEDWINDOW
149 #undef WS_OVERLAPPEDWINDOW
150 #define WS_OVERLAPPEDWINDOW 0
151 #endif // WS_OVERLAPPEDWINDOW
152 #endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW
158 #ifndef WM_WINDOWPOSCHANGING
159 #define WM_WINDOWPOSCHANGING 0
160 #endif // !WM_WINDOWPOSCHANGING
162 #define FreeResource(x)
163 #define UnlockResource(x)
167 inline HRESULT
CComModule::RegisterClassObjects(DWORD
/*dwClsContext*/, DWORD
/*dwFlags*/) throw()
168 { return E_NOTIMPL
; }
169 inline HRESULT
CComModule::RevokeClassObjects() throw()
170 { return E_NOTIMPL
; }
174 #define lstrlenW (int)ATL::lstrlenW
177 inline int WINAPI
lstrlenA(LPCSTR lpszString
)
178 { return ATL::lstrlenA(lpszString
); }
182 #define lstrcpyn ATL::lstrcpynW
185 #ifndef SetWindowLongPtrW
186 inline LONG_PTR
tmp_SetWindowLongPtrW( HWND hWnd
, int nIndex
, LONG_PTR dwNewLong
)
188 return( ::SetWindowLongW( hWnd
, nIndex
, LONG( dwNewLong
) ) );
190 #define SetWindowLongPtrW tmp_SetWindowLongPtrW
193 #ifndef GetWindowLongPtrW
194 inline LONG_PTR
tmp_GetWindowLongPtrW( HWND hWnd
, int nIndex
)
196 return( ::GetWindowLongW( hWnd
, nIndex
) );
198 #define GetWindowLongPtrW tmp_GetWindowLongPtrW
202 #define LongToPtr(x) ((void*)x)
206 #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
209 #else // !(_ATL_VER >= 0x0800)
213 #define lstrlenW (int)::wcslen
216 #define lstrlenA (int)strlen
219 inline LPTSTR
lstrcpyn(LPTSTR lpstrDest
, LPCTSTR lpstrSrc
, int nLength
)
221 if(lpstrDest
== NULL
|| lpstrSrc
== NULL
|| nLength
<= 0)
223 int nLen
= __min(lstrlen(lpstrSrc
), nLength
- 1);
224 LPTSTR lpstrRet
= (LPTSTR
)memcpy(lpstrDest
, lpstrSrc
, nLen
* sizeof(TCHAR
));
231 inline LPWSTR
lstrcpynW(LPWSTR lpstrDest
, LPCWSTR lpstrSrc
, int nLength
)
233 return lstrcpyn(lpstrDest
, lpstrSrc
, nLength
); // WinCE is Unicode only
238 inline LPSTR
lstrcpynA(LPSTR lpstrDest
, LPCSTR lpstrSrc
, int nLength
)
240 if(lpstrDest
== NULL
|| lpstrSrc
== NULL
|| nLength
<= 0)
242 int nLen
= __min(lstrlenA(lpstrSrc
), nLength
- 1);
243 LPSTR lpstrRet
= (LPSTR
)memcpy(lpstrDest
, lpstrSrc
, nLen
* sizeof(char));
249 #ifdef TrackPopupMenu
250 #undef TrackPopupMenu
251 #endif // TrackPopupMenu
253 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
254 static CWndClassInfo& GetWndClassInfo() \
256 static CWndClassInfo wc = \
258 { style, StartWindowProc, \
259 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \
260 NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
266 #define _MAX_FNAME _MAX_PATH
269 #if (_WIN32_WCE < 400)
270 #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i)))
271 #endif // (_WIN32_WCE < 400)
273 #if (_WIN32_WCE < 410)
274 #define WHEEL_PAGESCROLL (UINT_MAX)
275 #define WHEEL_DELTA 120
276 #endif // (_WIN32_WCE < 410)
292 #define VARCMP_NULL 3
295 #ifndef RDW_ALLCHILDREN
296 #define RDW_ALLCHILDREN 0
299 #endif // !(_ATL_VER >= 0x0800)
304 ///////////////////////////////////////////////////////////////////////////////
305 // Global support for using original VC++ 6.0 headers with WTL
307 #if (_MSC_VER < 1300) && !defined(_WIN32_WCE)
313 #define BS_PUSHBOX 0x0000000AL
316 struct __declspec(uuid("000214e6-0000-0000-c000-000000000046")) IShellFolder
;
317 struct __declspec(uuid("000214f9-0000-0000-c000-000000000046")) IShellLinkW
;
318 struct __declspec(uuid("000214ee-0000-0000-c000-000000000046")) IShellLinkA
;
319 #endif // (_MSC_VER < 1300) && !defined(_WIN32_WCE)
321 #ifndef _ATL_NO_OLD_HEADERS_WIN64
322 #if !defined(_WIN64) && (_ATL_VER < 0x0700)
324 #ifndef PSM_INSERTPAGE
325 #define PSM_INSERTPAGE (WM_USER + 119)
326 #endif // !PSM_INSERTPAGE
328 #ifndef GetClassLongPtr
329 #define GetClassLongPtrA GetClassLongA
330 #define GetClassLongPtrW GetClassLongW
332 #define GetClassLongPtr GetClassLongPtrW
334 #define GetClassLongPtr GetClassLongPtrA
336 #endif // !GetClassLongPtr
339 #define GCLP_HICONSM (-34)
340 #endif // !GCLP_HICONSM
342 #ifndef GetWindowLongPtr
343 #define GetWindowLongPtrA GetWindowLongA
344 #define GetWindowLongPtrW GetWindowLongW
346 #define GetWindowLongPtr GetWindowLongPtrW
348 #define GetWindowLongPtr GetWindowLongPtrA
350 #endif // !GetWindowLongPtr
352 #ifndef SetWindowLongPtr
353 #define SetWindowLongPtrA SetWindowLongA
354 #define SetWindowLongPtrW SetWindowLongW
356 #define SetWindowLongPtr SetWindowLongPtrW
358 #define SetWindowLongPtr SetWindowLongPtrA
360 #endif // !SetWindowLongPtr
363 #define GWLP_WNDPROC (-4)
365 #ifndef GWLP_HINSTANCE
366 #define GWLP_HINSTANCE (-6)
368 #ifndef GWLP_HWNDPARENT
369 #define GWLP_HWNDPARENT (-8)
371 #ifndef GWLP_USERDATA
372 #define GWLP_USERDATA (-21)
375 #define GWLP_ID (-12)
378 #ifndef DWLP_MSGRESULT
379 #define DWLP_MSGRESULT 0
382 typedef long LONG_PTR
;
383 typedef unsigned long ULONG_PTR
;
384 typedef ULONG_PTR DWORD_PTR
;
386 #ifndef HandleToUlong
387 #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) )
390 #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) )
393 #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h))
396 #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) )
399 #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) )
402 #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) )
405 #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
408 #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) )
411 #define PtrToShort( p ) ((short)(LONG_PTR)(p) )
414 #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i))
417 #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui))
420 #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l))
423 #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul))
426 #endif // !defined(_WIN64) && (_ATL_VER < 0x0700)
427 #endif // !_ATL_NO_OLD_HEADERS_WIN64
430 ///////////////////////////////////////////////////////////////////////////////
431 // Global support for using original VC++ 7.x headers with WTL
433 #if (_MSC_VER >= 1300) && (_MSC_VER < 1400)
436 #define BS_PUSHBOX 0x0000000AL
439 #pragma warning(disable: 4244) // conversion from 'type1' to 'type2', possible loss of data
441 #endif // (_MSC_VER >= 1300) && (_MSC_VER < 1400)
444 ///////////////////////////////////////////////////////////////////////////////
445 // Global support for old SDK headers
448 #define BTNS_BUTTON TBSTYLE_BUTTON
452 #define BTNS_SEP TBSTYLE_SEP
456 #define BTNS_CHECK TBSTYLE_CHECK
460 #define BTNS_GROUP TBSTYLE_GROUP
463 #ifndef BTNS_CHECKGROUP
464 #define BTNS_CHECKGROUP TBSTYLE_CHECKGROUP
467 #if (_WIN32_IE >= 0x0300)
468 #ifndef BTNS_DROPDOWN
469 #define BTNS_DROPDOWN TBSTYLE_DROPDOWN
473 #if (_WIN32_IE >= 0x0400)
474 #ifndef BTNS_AUTOSIZE
475 #define BTNS_AUTOSIZE TBSTYLE_AUTOSIZE
478 #ifndef BTNS_NOPREFIX
479 #define BTNS_NOPREFIX TBSTYLE_NOPREFIX
484 ///////////////////////////////////////////////////////////////////////////////
485 // Global support for SecureHelper functions
488 #define _TRUNCATE ((size_t)-1)
491 #ifndef _ERRCODE_DEFINED
492 #define _ERRCODE_DEFINED
496 #ifndef _SECURECRT_ERRCODE_VALUES_DEFINED
497 #define _SECURECRT_ERRCODE_VALUES_DEFINED
503 #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
507 ///////////////////////////////////////////////////////////////////////////////
508 // Miscellaneous global support
510 // define useful macros from winuser.h
511 #ifndef IS_INTRESOURCE
512 #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
513 #endif // IS_INTRESOURCE
515 // protect template members from windowsx.h macros
517 #undef SubclassWindow
518 #endif // _INC_WINDOWSX
520 // define useful macros from windowsx.h
522 #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam))
525 #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam))
528 // Dummy structs for compiling with /CLR
529 #if (_MSC_VER >= 1300) && defined(_MANAGED)
530 __if_not_exists(_IMAGELIST::_IMAGELIST
) { struct _IMAGELIST
{ }; }
531 __if_not_exists(_TREEITEM::_TREEITEM
) { struct _TREEITEM
{ }; }
532 __if_not_exists(_PSP::_PSP
) { struct _PSP
{ }; }
535 // Define ATLVERIFY macro for ATL3
536 #if (_ATL_VER < 0x0700)
539 #define ATLVERIFY(expr) ATLASSERT(expr)
541 #define ATLVERIFY(expr) (expr)
544 #endif // (_ATL_VER < 0x0700)
546 // Forward declaration for ATL3 and ATL11 fix
547 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
548 namespace ATL
{ HRESULT
AtlGetCommCtrlVersion(LPDWORD pdwMajor
, LPDWORD pdwMinor
); };
551 #ifndef WM_MOUSEHWHEEL
552 #define WM_MOUSEHWHEEL 0x020E
559 #if (_ATL_VER >= 0x0700)
560 DECLARE_TRACE_CATEGORY(atlTraceUI
);
562 __declspec(selectany
) ATL::CTraceCategory
atlTraceUI(_T("atlTraceUI"));
564 #else // !(_ATL_VER >= 0x0700)
567 atlTraceUI
= 0x10000000
569 #endif // !(_ATL_VER >= 0x0700)
571 // Windows version helper
572 inline bool AtlIsOldWindows()
574 #ifdef _versionhelpers_H_INCLUDED_
575 return !::IsWindowsVersionOrGreater(4, 90, 0);
576 #else // !_versionhelpers_H_INCLUDED_
577 OSVERSIONINFO ovi
= { sizeof(OSVERSIONINFO
) };
578 BOOL bRet
= ::GetVersionEx(&ovi
);
579 return (!bRet
|| !((ovi
.dwMajorVersion
>= 5) || (ovi
.dwMajorVersion
== 4 && ovi
.dwMinorVersion
>= 90)));
580 #endif // _versionhelpers_H_INCLUDED_
583 // Default GUI font helper - "MS Shell Dlg" stock font
584 inline HFONT
AtlGetDefaultGuiFont()
587 return (HFONT
)::GetStockObject(DEFAULT_GUI_FONT
);
589 return (HFONT
)::GetStockObject(SYSTEM_FONT
);
593 // Control font helper - default font for controls not in a dialog
594 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
595 inline HFONT
AtlCreateControlFont()
599 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT
, sizeof(LOGFONT
), &lf
, 0) != FALSE
);
600 HFONT hFont
= ::CreateFontIndirect(&lf
);
601 ATLASSERT(hFont
!= NULL
);
604 return (HFONT
)::GetStockObject(SYSTEM_FONT
);
609 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
610 inline HFONT
AtlCreateBoldFont(HFONT hFont
= NULL
)
615 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT
, sizeof(LOGFONT
), &lf
, 0) != FALSE
);
617 ATLVERIFY(::GetObject(hFont
, sizeof(LOGFONT
), &lf
) == sizeof(LOGFONT
));
620 hFont
= (HFONT
)::GetStockObject(SYSTEM_FONT
);
621 ATLVERIFY(::GetObject(hFont
, sizeof(LOGFONT
), &lf
) == sizeof(LOGFONT
));
623 lf
.lfWeight
= FW_BOLD
;
624 HFONT hFontBold
= ::CreateFontIndirect(&lf
);
625 ATLASSERT(hFontBold
!= NULL
);
629 // Common Controls initialization helper
630 inline BOOL
AtlInitCommonControls(DWORD dwFlags
)
632 INITCOMMONCONTROLSEX iccx
= { sizeof(INITCOMMONCONTROLSEX
), dwFlags
};
633 BOOL bRet
= ::InitCommonControlsEx(&iccx
);
639 ///////////////////////////////////////////////////////////////////////////////
640 // RunTimeHelper - helper functions for Windows version and structure sizes
642 // Not for Windows CE
643 #if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE)
644 #define _WTL_NO_RUNTIME_STRUCT_SIZE
647 #ifndef _WTL_NO_RUNTIME_STRUCT_SIZE
649 #ifndef _SIZEOF_STRUCT
650 #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
653 #if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
654 #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader)
655 #endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
657 #if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
658 #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign)
659 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
661 #if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
662 #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns)
663 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
665 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
666 #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st)
667 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
669 #if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
670 #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont)
671 #endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
673 #if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0501) && !defined(TTTOOLINFO_V2_SIZE)
674 #define TTTOOLINFO_V2_SIZE _SIZEOF_STRUCT(TTTOOLINFO, lParam)
675 #endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0501) && !defined(TTTOOLINFO_V2_SIZE)
677 #endif // !_WTL_NO_RUNTIME_STRUCT_SIZE
679 namespace RunTimeHelper
682 inline bool IsCommCtrl6()
684 DWORD dwMajor
= 0, dwMinor
= 0;
685 HRESULT hRet
= ATL::AtlGetCommCtrlVersion(&dwMajor
, &dwMinor
);
686 return (SUCCEEDED(hRet
) && (dwMajor
>= 6));
689 inline bool IsVista()
691 #ifdef _versionhelpers_H_INCLUDED_
692 return ::IsWindowsVistaOrGreater();
693 #else // !_versionhelpers_H_INCLUDED_
694 OSVERSIONINFO ovi
= { sizeof(OSVERSIONINFO
) };
695 BOOL bRet
= ::GetVersionEx(&ovi
);
696 return ((bRet
!= FALSE
) && (ovi
.dwMajorVersion
>= 6));
697 #endif // _versionhelpers_H_INCLUDED_
700 inline bool IsThemeAvailable()
706 HMODULE hThemeDLL
= ::LoadLibrary(_T("uxtheme.dll"));
707 if(hThemeDLL
!= NULL
)
709 typedef BOOL (STDAPICALLTYPE
*PFN_IsThemeActive
)();
710 PFN_IsThemeActive pfnIsThemeActive
= (PFN_IsThemeActive
)::GetProcAddress(hThemeDLL
, "IsThemeActive");
711 ATLASSERT(pfnIsThemeActive
!= NULL
);
712 bRet
= (pfnIsThemeActive
!= NULL
) && (pfnIsThemeActive() != FALSE
);
715 typedef BOOL (STDAPICALLTYPE
*PFN_IsAppThemed
)();
716 PFN_IsAppThemed pfnIsAppThemed
= (PFN_IsAppThemed
)::GetProcAddress(hThemeDLL
, "IsAppThemed");
717 ATLASSERT(pfnIsAppThemed
!= NULL
);
718 bRet
= (pfnIsAppThemed
!= NULL
) && (pfnIsAppThemed() != FALSE
);
721 ::FreeLibrary(hThemeDLL
);
730 #ifdef _versionhelpers_H_INCLUDED_
731 return ::IsWindows7OrGreater();
732 #else // !_versionhelpers_H_INCLUDED_
733 OSVERSIONINFO ovi
= { sizeof(OSVERSIONINFO
) };
734 BOOL bRet
= ::GetVersionEx(&ovi
);
735 return ((bRet
!= FALSE
) && (ovi
.dwMajorVersion
== 6) && (ovi
.dwMinorVersion
>= 1));
736 #endif // _versionhelpers_H_INCLUDED_
739 inline bool IsRibbonUIAvailable()
741 static INT iRibbonUI
= -1;
743 #if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
746 HMODULE hRibbonDLL
= ::LoadLibrary(_T("propsys.dll"));
747 if (hRibbonDLL
!= NULL
)
749 const GUID CLSID_UIRibbonFramework
= { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } };
750 // block - create instance
752 ATL::CComPtr
<IUnknown
> pIUIFramework
;
753 iRibbonUI
= SUCCEEDED(pIUIFramework
.CoCreateInstance(CLSID_UIRibbonFramework
)) ? 1 : 0;
755 ::FreeLibrary(hRibbonDLL
);
762 #endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
764 return (iRibbonUI
== 1);
767 #endif // !_WIN32_WCE
769 inline int SizeOf_REBARBANDINFO()
771 int nSize
= sizeof(REBARBANDINFO
);
772 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
773 if(!(IsVista() && IsCommCtrl6()))
774 nSize
= REBARBANDINFO_V6_SIZE
;
775 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
779 #if (_WIN32_WINNT >= 0x501)
780 inline int SizeOf_LVGROUP()
782 int nSize
= sizeof(LVGROUP
);
783 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
785 nSize
= LVGROUP_V5_SIZE
;
786 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
790 inline int SizeOf_LVTILEINFO()
792 int nSize
= sizeof(LVTILEINFO
);
793 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
795 nSize
= LVTILEINFO_V5_SIZE
;
796 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
799 #endif // (_WIN32_WINNT >= 0x501)
801 inline int SizeOf_MCHITTESTINFO()
803 int nSize
= sizeof(MCHITTESTINFO
);
804 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
805 if(!(IsVista() && IsCommCtrl6()))
806 nSize
= MCHITTESTINFO_V1_SIZE
;
807 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
812 inline int SizeOf_NONCLIENTMETRICS()
814 int nSize
= sizeof(NONCLIENTMETRICS
);
815 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
817 nSize
= NONCLIENTMETRICS_V1_SIZE
;
818 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
822 inline int SizeOf_TOOLINFO()
824 int nSize
= sizeof(TOOLINFO
);
825 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0501)
827 nSize
= TTTOOLINFO_V2_SIZE
;
828 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0501)
831 #endif // !_WIN32_WCE
835 ///////////////////////////////////////////////////////////////////////////////
836 // ModuleHelper - helper functions for ATL3 and ATL7 module classes
838 namespace ModuleHelper
840 inline HINSTANCE
GetModuleInstance()
842 #if (_ATL_VER >= 0x0700)
843 return ATL::_AtlBaseModule
.GetModuleInstance();
844 #else // !(_ATL_VER >= 0x0700)
845 return ATL::_pModule
->GetModuleInstance();
846 #endif // !(_ATL_VER >= 0x0700)
849 inline HINSTANCE
GetResourceInstance()
851 #if (_ATL_VER >= 0x0700)
852 return ATL::_AtlBaseModule
.GetResourceInstance();
853 #else // !(_ATL_VER >= 0x0700)
854 return ATL::_pModule
->GetResourceInstance();
855 #endif // !(_ATL_VER >= 0x0700)
858 inline void AddCreateWndData(ATL::_AtlCreateWndData
* pData
, void* pObject
)
860 #if (_ATL_VER >= 0x0700)
861 ATL::_AtlWinModule
.AddCreateWndData(pData
, pObject
);
862 #else // !(_ATL_VER >= 0x0700)
863 ATL::_pModule
->AddCreateWndData(pData
, pObject
);
864 #endif // !(_ATL_VER >= 0x0700)
867 inline void* ExtractCreateWndData()
869 #if (_ATL_VER >= 0x0700)
870 return ATL::_AtlWinModule
.ExtractCreateWndData();
871 #else // !(_ATL_VER >= 0x0700)
872 return ATL::_pModule
->ExtractCreateWndData();
873 #endif // !(_ATL_VER >= 0x0700)
878 ///////////////////////////////////////////////////////////////////////////////
879 // SecureHelper - helper functions for VS2005 secure CRT
881 namespace SecureHelper
883 inline void strcpyA_x(char* lpstrDest
, size_t cchDest
, const char* lpstrSrc
)
886 ATL::Checked::strcpy_s(lpstrDest
, cchDest
, lpstrSrc
);
888 if(cchDest
> (size_t)lstrlenA(lpstrSrc
))
889 ATLVERIFY(lstrcpyA(lpstrDest
, lpstrSrc
) != NULL
);
895 inline void strcpyW_x(wchar_t* lpstrDest
, size_t cchDest
, const wchar_t* lpstrSrc
)
898 ATL::Checked::wcscpy_s(lpstrDest
, cchDest
, lpstrSrc
);
900 if(cchDest
> (size_t)lstrlenW(lpstrSrc
))
901 ATLVERIFY(lstrcpyW(lpstrDest
, lpstrSrc
) != NULL
);
907 inline void strcpy_x(LPTSTR lpstrDest
, size_t cchDest
, LPCTSTR lpstrSrc
)
910 strcpyW_x(lpstrDest
, cchDest
, lpstrSrc
);
912 strcpyA_x(lpstrDest
, cchDest
, lpstrSrc
);
916 inline errno_t
strncpyA_x(char* lpstrDest
, size_t cchDest
, const char* lpstrSrc
, size_t cchCount
)
919 return ATL::Checked::strncpy_s(lpstrDest
, cchDest
, lpstrSrc
, cchCount
);
922 if(lpstrDest
== NULL
|| cchDest
== 0 || lpstrSrc
== NULL
)
926 else if(cchCount
== _TRUNCATE
)
928 cchCount
= __min(cchDest
- 1, size_t(lstrlenA(lpstrSrc
)));
931 else if(cchDest
<= cchCount
)
936 if(nRet
== 0 || nRet
== STRUNCATE
)
937 nRet
= (lstrcpynA(lpstrDest
, lpstrSrc
, (int)cchCount
+ 1) != NULL
) ? nRet
: EINVAL
;
938 ATLASSERT(nRet
== 0 || nRet
== STRUNCATE
);
943 inline errno_t
strncpyW_x(wchar_t* lpstrDest
, size_t cchDest
, const wchar_t* lpstrSrc
, size_t cchCount
)
946 return ATL::Checked::wcsncpy_s(lpstrDest
, cchDest
, lpstrSrc
, cchCount
);
949 if(lpstrDest
== NULL
|| cchDest
== 0 || lpstrSrc
== NULL
)
953 else if(cchCount
== _TRUNCATE
)
955 cchCount
= __min(cchDest
- 1, size_t(lstrlenW(lpstrSrc
)));
958 else if(cchDest
<= cchCount
)
963 if(nRet
== 0 || nRet
== STRUNCATE
)
964 nRet
= (lstrcpynW(lpstrDest
, lpstrSrc
, (int)cchCount
+ 1) != NULL
) ? nRet
: EINVAL
;
965 ATLASSERT(nRet
== 0 || nRet
== STRUNCATE
);
970 inline errno_t
strncpy_x(LPTSTR lpstrDest
, size_t cchDest
, LPCTSTR lpstrSrc
, size_t cchCount
)
973 return strncpyW_x(lpstrDest
, cchDest
, lpstrSrc
, cchCount
);
975 return strncpyA_x(lpstrDest
, cchDest
, lpstrSrc
, cchCount
);
979 inline void strcatA_x(char* lpstrDest
, size_t cchDest
, const char* lpstrSrc
)
982 ATL::Checked::strcat_s(lpstrDest
, cchDest
, lpstrSrc
);
984 if(cchDest
> (size_t)lstrlenA(lpstrSrc
))
985 ATLVERIFY(lstrcatA(lpstrDest
, lpstrSrc
) != NULL
);
991 inline void strcatW_x(wchar_t* lpstrDest
, size_t cchDest
, const wchar_t* lpstrSrc
)
994 ATL::Checked::wcscat_s(lpstrDest
, cchDest
, lpstrSrc
);
996 if(cchDest
> (size_t)lstrlenW(lpstrSrc
))
997 ATLVERIFY(lstrcatW(lpstrDest
, lpstrSrc
) != NULL
);
1003 inline void strcat_x(LPTSTR lpstrDest
, size_t cchDest
, LPCTSTR lpstrSrc
)
1006 strcatW_x(lpstrDest
, cchDest
, lpstrSrc
);
1008 strcatA_x(lpstrDest
, cchDest
, lpstrSrc
);
1012 inline void memcpy_x(void* pDest
, size_t cbDest
, const void* pSrc
, size_t cbSrc
)
1015 ATL::Checked::memcpy_s(pDest
, cbDest
, pSrc
, cbSrc
);
1018 memcpy(pDest
, pSrc
, cbSrc
);
1024 inline void memmove_x(void* pDest
, size_t cbDest
, const void* pSrc
, size_t cbSrc
)
1027 ATL::Checked::memmove_s(pDest
, cbDest
, pSrc
, cbSrc
);
1030 memmove(pDest
, pSrc
, cbSrc
);
1036 inline int vsprintf_x(LPTSTR lpstrBuff
, size_t cchBuff
, LPCTSTR lpstrFormat
, va_list args
)
1038 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
1039 return _vstprintf_s(lpstrBuff
, cchBuff
, lpstrFormat
, args
);
1041 cchBuff
; // Avoid unused argument warning
1042 #pragma warning(push)
1043 #pragma warning(disable: 4996)
1044 return _vstprintf(lpstrBuff
, lpstrFormat
, args
);
1045 #pragma warning(pop)
1049 inline int wvsprintf_x(LPTSTR lpstrBuff
, size_t cchBuff
, LPCTSTR lpstrFormat
, va_list args
)
1051 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
1052 return _vstprintf_s(lpstrBuff
, cchBuff
, lpstrFormat
, args
);
1054 cchBuff
; // Avoid unused argument warning
1055 return ::wvsprintf(lpstrBuff
, lpstrFormat
, args
);
1059 inline int sprintf_x(LPTSTR lpstrBuff
, size_t cchBuff
, LPCTSTR lpstrFormat
, ...)
1062 va_start(args
, lpstrFormat
);
1063 int nRes
= vsprintf_x(lpstrBuff
, cchBuff
, lpstrFormat
, args
);
1068 inline int wsprintf_x(LPTSTR lpstrBuff
, size_t cchBuff
, LPCTSTR lpstrFormat
, ...)
1071 va_start(args
, lpstrFormat
);
1072 int nRes
= wvsprintf_x(lpstrBuff
, cchBuff
, lpstrFormat
, args
);
1076 }; // namespace SecureHelper
1079 ///////////////////////////////////////////////////////////////////////////////
1080 // MinCrtHelper - helper functions for using _ATL_MIN_CRT
1082 namespace MinCrtHelper
1084 inline int _isspace(TCHAR ch
)
1086 #ifndef _ATL_MIN_CRT
1087 return _istspace(ch
);
1088 #else // _ATL_MIN_CRT
1090 ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1
, &ch
, 1, &type
);
1091 return (type
& C1_SPACE
) == C1_SPACE
;
1092 #endif // _ATL_MIN_CRT
1095 inline int _isdigit(TCHAR ch
)
1097 #ifndef _ATL_MIN_CRT
1098 return _istdigit(ch
);
1099 #else // _ATL_MIN_CRT
1101 ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1
, &ch
, 1, &type
);
1102 return (type
& C1_DIGIT
) == C1_DIGIT
;
1103 #endif // _ATL_MIN_CRT
1106 inline int _atoi(LPCTSTR str
)
1108 #ifndef _ATL_MIN_CRT
1110 #else // _ATL_MIN_CRT
1111 while(_isspace(*str
) != 0)
1115 TCHAR sign
= ch
; // save sign indication
1116 if(ch
== _T('-') || ch
== _T('+'))
1117 ch
= *str
++; // skip sign
1120 while(_isdigit(ch
) != 0)
1122 total
= 10 * total
+ (ch
- '0'); // accumulate digit
1123 ch
= *str
++; // get next char
1126 return (sign
== '-') ? -total
: total
; // return result, negated if necessary
1127 #endif // _ATL_MIN_CRT
1130 inline LPCTSTR
_strrchr(LPCTSTR str
, TCHAR ch
)
1132 #ifndef _ATL_MIN_CRT
1133 return _tcsrchr(str
, ch
);
1134 #else // _ATL_MIN_CRT
1135 LPCTSTR lpsz
= NULL
;
1140 str
= ::CharNext(str
);
1143 #endif // _ATL_MIN_CRT
1146 inline LPTSTR
_strrchr(LPTSTR str
, TCHAR ch
)
1148 #ifndef _ATL_MIN_CRT
1149 return _tcsrchr(str
, ch
);
1150 #else // _ATL_MIN_CRT
1156 str
= ::CharNext(str
);
1159 #endif // _ATL_MIN_CRT
1161 }; // namespace MinCrtHelper
1164 ///////////////////////////////////////////////////////////////////////////////
1165 // GenericWndClass - generic window class usable for subclassing
1167 // Use in dialog templates to specify a placeholder to be subclassed
1168 // Specify as a custom control with class name WTL_GenericWindow
1169 // Call Rregister() before creating dialog (for example, in WinMain)
1170 namespace GenericWndClass
1172 inline LPCTSTR
GetName()
1174 return _T("WTL_GenericWindow");
1177 inline ATOM
Register()
1179 WNDCLASSEX wc
= { sizeof(WNDCLASSEX
) };
1180 wc
.lpfnWndProc
= ::DefWindowProc
;
1181 wc
.hInstance
= ModuleHelper::GetModuleInstance();
1182 wc
.hCursor
= ::LoadCursor(NULL
, IDC_ARROW
);
1183 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1184 wc
.lpszClassName
= GetName();
1185 ATOM atom
= ::RegisterClassEx(&wc
);
1186 ATLASSERT(atom
!= 0);
1190 inline BOOL
Unregister() // only needed for DLLs or tmp use
1192 return ::UnregisterClass(GetName(), ModuleHelper::GetModuleInstance());
1194 }; // namespace GenericWndClass
1197 ///////////////////////////////////////////////////////////////////////////////
1198 // CMessageFilter - Interface for message filter support
1200 class CMessageFilter
1203 virtual BOOL
PreTranslateMessage(MSG
* pMsg
) = 0;
1207 ///////////////////////////////////////////////////////////////////////////////
1208 // CIdleHandler - Interface for idle processing
1213 virtual BOOL
OnIdle() = 0;
1216 #ifndef _ATL_NO_OLD_NAMES
1217 // for compatilibility with old names only
1218 typedef CIdleHandler CUpdateUIObject
;
1219 #define DoUpdate OnIdle
1220 #endif // !_ATL_NO_OLD_NAMES
1223 ///////////////////////////////////////////////////////////////////////////////
1224 // CMessageLoop - message loop implementation
1229 ATL::CSimpleArray
<CMessageFilter
*> m_aMsgFilter
;
1230 ATL::CSimpleArray
<CIdleHandler
*> m_aIdleHandler
;
1233 // Message filter operations
1234 BOOL
AddMessageFilter(CMessageFilter
* pMessageFilter
)
1236 return m_aMsgFilter
.Add(pMessageFilter
);
1239 BOOL
RemoveMessageFilter(CMessageFilter
* pMessageFilter
)
1241 return m_aMsgFilter
.Remove(pMessageFilter
);
1244 // Idle handler operations
1245 BOOL
AddIdleHandler(CIdleHandler
* pIdleHandler
)
1247 return m_aIdleHandler
.Add(pIdleHandler
);
1250 BOOL
RemoveIdleHandler(CIdleHandler
* pIdleHandler
)
1252 return m_aIdleHandler
.Remove(pIdleHandler
);
1255 #ifndef _ATL_NO_OLD_NAMES
1256 // for compatilibility with old names only
1257 BOOL
AddUpdateUI(CIdleHandler
* pIdleHandler
)
1259 ATLTRACE2(atlTraceUI
, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1260 return AddIdleHandler(pIdleHandler
);
1263 BOOL
RemoveUpdateUI(CIdleHandler
* pIdleHandler
)
1265 ATLTRACE2(atlTraceUI
, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1266 return RemoveIdleHandler(pIdleHandler
);
1268 #endif // !_ATL_NO_OLD_NAMES
1273 BOOL bDoIdle
= TRUE
;
1279 while(bDoIdle
&& !::PeekMessage(&m_msg
, NULL
, 0, 0, PM_NOREMOVE
))
1281 if(!OnIdle(nIdleCount
++))
1285 bRet
= ::GetMessage(&m_msg
, NULL
, 0, 0);
1289 ATLTRACE2(atlTraceUI
, 0, _T("::GetMessage returned -1 (error)\n"));
1290 continue; // error, don't process
1294 ATLTRACE2(atlTraceUI
, 0, _T("CMessageLoop::Run - exiting\n"));
1295 break; // WM_QUIT, exit message loop
1298 if(!PreTranslateMessage(&m_msg
))
1300 ::TranslateMessage(&m_msg
);
1301 ::DispatchMessage(&m_msg
);
1304 if(IsIdleMessage(&m_msg
))
1311 return (int)m_msg
.wParam
;
1314 static BOOL
IsIdleMessage(MSG
* pMsg
)
1316 // These messages should NOT cause idle processing
1317 switch(pMsg
->message
)
1321 case WM_NCMOUSEMOVE
:
1322 #endif // !_WIN32_WCE
1324 case 0x0118: // WM_SYSTIMER (caret blink)
1332 // Override to change message filtering
1333 virtual BOOL
PreTranslateMessage(MSG
* pMsg
)
1336 for(int i
= m_aMsgFilter
.GetSize() - 1; i
>= 0; i
--)
1338 CMessageFilter
* pMessageFilter
= m_aMsgFilter
[i
];
1339 if(pMessageFilter
!= NULL
&& pMessageFilter
->PreTranslateMessage(pMsg
))
1342 return FALSE
; // not translated
1345 // override to change idle processing
1346 virtual BOOL
OnIdle(int /*nIdleCount*/)
1348 for(int i
= 0; i
< m_aIdleHandler
.GetSize(); i
++)
1350 CIdleHandler
* pIdleHandler
= m_aIdleHandler
[i
];
1351 if(pIdleHandler
!= NULL
)
1352 pIdleHandler
->OnIdle();
1354 return FALSE
; // don't continue
1359 ///////////////////////////////////////////////////////////////////////////////
1360 // CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock
1361 // internal classes to manage critical sections for both ATL3 and ATL7
1363 class CStaticDataInitCriticalSectionLock
1366 #if (_ATL_VER >= 0x0700)
1367 ATL::CComCritSecLock
<ATL::CComCriticalSection
> m_cslock
;
1369 CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule
->m_csStaticDataInitAndTypeInfo
, false)
1371 #endif // (_ATL_VER >= 0x0700)
1375 #if (_ATL_VER >= 0x0700)
1376 return m_cslock
.Lock();
1377 #else // !(_ATL_VER >= 0x0700)
1378 ::EnterCriticalSection(&ATL::_pModule
->m_csStaticDataInit
);
1380 #endif // !(_ATL_VER >= 0x0700)
1385 #if (_ATL_VER >= 0x0700)
1387 #else // !(_ATL_VER >= 0x0700)
1388 ::LeaveCriticalSection(&ATL::_pModule
->m_csStaticDataInit
);
1389 #endif // !(_ATL_VER >= 0x0700)
1394 class CWindowCreateCriticalSectionLock
1397 #if (_ATL_VER >= 0x0700)
1398 ATL::CComCritSecLock
<ATL::CComCriticalSection
> m_cslock
;
1400 CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule
.m_csWindowCreate
, false)
1402 #endif // (_ATL_VER >= 0x0700)
1406 #if (_ATL_VER >= 0x0700)
1407 return m_cslock
.Lock();
1408 #else // !(_ATL_VER >= 0x0700)
1409 ::EnterCriticalSection(&ATL::_pModule
->m_csWindowCreate
);
1411 #endif // !(_ATL_VER >= 0x0700)
1416 #if (_ATL_VER >= 0x0700)
1418 #else // !(_ATL_VER >= 0x0700)
1419 ::LeaveCriticalSection(&ATL::_pModule
->m_csWindowCreate
);
1420 #endif // !(_ATL_VER >= 0x0700)
1425 ///////////////////////////////////////////////////////////////////////////////
1426 // CTempBuffer - helper class for stack allocations for ATL3
1428 #ifndef _WTL_STACK_ALLOC_THRESHOLD
1429 #define _WTL_STACK_ALLOC_THRESHOLD 512
1432 #if (_ATL_VER >= 0x0700)
1434 using ATL::CTempBuffer
;
1436 #else // !(_ATL_VER >= 0x0700)
1440 #define SIZE_MAX _UI64_MAX
1442 #define SIZE_MAX UINT_MAX
1446 #pragma warning(push)
1447 #pragma warning(disable: 4284) // warning for operator ->
1449 template<typename T
, int t_nFixedBytes
= 128>
1453 CTempBuffer() : m_p(NULL
)
1457 CTempBuffer(size_t nElements
) : m_p(NULL
)
1459 Allocate(nElements
);
1464 if(m_p
!= reinterpret_cast<T
*>(m_abFixedBuffer
))
1473 T
* operator ->() const
1475 ATLASSERT(m_p
!= NULL
);
1479 T
* Allocate(size_t nElements
)
1481 ATLASSERT(nElements
<= (SIZE_MAX
/ sizeof(T
)));
1482 return AllocateBytes(nElements
* sizeof(T
));
1485 T
* AllocateBytes(size_t nBytes
)
1487 ATLASSERT(m_p
== NULL
);
1488 if(nBytes
> t_nFixedBytes
)
1489 m_p
= static_cast<T
*>(malloc(nBytes
));
1491 m_p
= reinterpret_cast<T
*>(m_abFixedBuffer
);
1498 BYTE m_abFixedBuffer
[t_nFixedBytes
];
1501 #pragma warning(pop)
1503 #endif // !(_ATL_VER >= 0x0700)
1506 ///////////////////////////////////////////////////////////////////////////////
1507 // CAppModule - module class for an application
1509 class CAppModule
: public ATL::CComModule
1512 DWORD m_dwMainThreadID
;
1513 ATL::CSimpleMap
<DWORD
, CMessageLoop
*>* m_pMsgLoopMap
;
1514 ATL::CSimpleArray
<HWND
>* m_pSettingChangeNotify
;
1516 // Overrides of CComModule::Init and Term
1517 HRESULT
Init(ATL::_ATL_OBJMAP_ENTRY
* pObjMap
, HINSTANCE hInstance
, const GUID
* pLibID
= NULL
)
1519 HRESULT hRet
= CComModule::Init(pObjMap
, hInstance
, pLibID
);
1523 m_dwMainThreadID
= ::GetCurrentThreadId();
1524 typedef ATL::CSimpleMap
<DWORD
, CMessageLoop
*> _mapClass
;
1525 m_pMsgLoopMap
= NULL
;
1526 ATLTRY(m_pMsgLoopMap
= new _mapClass
);
1527 if(m_pMsgLoopMap
== NULL
)
1528 return E_OUTOFMEMORY
;
1529 m_pSettingChangeNotify
= NULL
;
1536 TermSettingChangeNotify();
1537 delete m_pMsgLoopMap
;
1541 // Message loop map methods
1542 BOOL
AddMessageLoop(CMessageLoop
* pMsgLoop
)
1544 CStaticDataInitCriticalSectionLock lock
;
1545 if(FAILED(lock
.Lock()))
1547 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
1552 ATLASSERT(pMsgLoop
!= NULL
);
1553 ATLASSERT(m_pMsgLoopMap
->Lookup(::GetCurrentThreadId()) == NULL
); // not in map yet
1555 BOOL bRet
= m_pMsgLoopMap
->Add(::GetCurrentThreadId(), pMsgLoop
);
1562 BOOL
RemoveMessageLoop()
1564 CStaticDataInitCriticalSectionLock lock
;
1565 if(FAILED(lock
.Lock()))
1567 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
1572 BOOL bRet
= m_pMsgLoopMap
->Remove(::GetCurrentThreadId());
1579 CMessageLoop
* GetMessageLoop(DWORD dwThreadID
= ::GetCurrentThreadId()) const
1581 CStaticDataInitCriticalSectionLock lock
;
1582 if(FAILED(lock
.Lock()))
1584 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
1589 CMessageLoop
* pLoop
= m_pMsgLoopMap
->Lookup(dwThreadID
);
1596 // Setting change notify methods
1597 // Note: Call this from the main thread for MSDI apps
1598 BOOL
InitSettingChangeNotify(DLGPROC pfnDlgProc
= _SettingChangeDlgProc
)
1600 CStaticDataInitCriticalSectionLock lock
;
1601 if(FAILED(lock
.Lock()))
1603 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n"));
1608 if(m_pSettingChangeNotify
== NULL
)
1610 typedef ATL::CSimpleArray
<HWND
> _notifyClass
;
1611 ATLTRY(m_pSettingChangeNotify
= new _notifyClass
);
1612 ATLASSERT(m_pSettingChangeNotify
!= NULL
);
1615 BOOL bRet
= (m_pSettingChangeNotify
!= NULL
);
1616 if(bRet
&& m_pSettingChangeNotify
->GetSize() == 0)
1619 _ATL_EMPTY_DLGTEMPLATE templ
;
1620 HWND hNtfWnd
= ::CreateDialogIndirect(GetModuleInstance(), &templ
, NULL
, pfnDlgProc
);
1621 ATLASSERT(::IsWindow(hNtfWnd
));
1622 if(::IsWindow(hNtfWnd
))
1624 // need conditional code because types don't match in winuser.h
1626 ::SetWindowLongPtr(hNtfWnd
, GWLP_USERDATA
, (LONG_PTR
)this);
1628 ::SetWindowLongPtr(hNtfWnd
, GWLP_USERDATA
, PtrToLong(this));
1630 bRet
= m_pSettingChangeNotify
->Add(hNtfWnd
);
1643 void TermSettingChangeNotify()
1645 CStaticDataInitCriticalSectionLock lock
;
1646 if(FAILED(lock
.Lock()))
1648 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n"));
1653 if(m_pSettingChangeNotify
!= NULL
&& m_pSettingChangeNotify
->GetSize() > 0)
1654 ::DestroyWindow((*m_pSettingChangeNotify
)[0]);
1655 delete m_pSettingChangeNotify
;
1656 m_pSettingChangeNotify
= NULL
;
1661 BOOL
AddSettingChangeNotify(HWND hWnd
)
1663 CStaticDataInitCriticalSectionLock lock
;
1664 if(FAILED(lock
.Lock()))
1666 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n"));
1671 ATLASSERT(::IsWindow(hWnd
));
1673 if(InitSettingChangeNotify() != FALSE
)
1674 bRet
= m_pSettingChangeNotify
->Add(hWnd
);
1681 BOOL
RemoveSettingChangeNotify(HWND hWnd
)
1683 CStaticDataInitCriticalSectionLock lock
;
1684 if(FAILED(lock
.Lock()))
1686 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n"));
1692 if(m_pSettingChangeNotify
!= NULL
)
1693 bRet
= m_pSettingChangeNotify
->Remove(hWnd
);
1700 // Implementation - setting change notify dialog template and dialog procedure
1701 struct _ATL_EMPTY_DLGTEMPLATE
: DLGTEMPLATE
1703 _ATL_EMPTY_DLGTEMPLATE()
1705 memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE
));
1708 WORD wMenu
, wClass
, wTitle
;
1712 static INT_PTR CALLBACK
_SettingChangeDlgProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1714 static BOOL CALLBACK
_SettingChangeDlgProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1717 if(uMsg
== WM_SETTINGCHANGE
)
1719 // need conditional code because types don't match in winuser.h
1721 CAppModule
* pModule
= (CAppModule
*)::GetWindowLongPtr(hWnd
, GWLP_USERDATA
);
1723 CAppModule
* pModule
= (CAppModule
*)LongToPtr(::GetWindowLongPtr(hWnd
, GWLP_USERDATA
));
1725 ATLASSERT(pModule
!= NULL
);
1726 ATLASSERT(pModule
->m_pSettingChangeNotify
!= NULL
);
1727 const UINT uTimeout
= 1500; // ms
1728 for(int i
= 1; i
< pModule
->m_pSettingChangeNotify
->GetSize(); i
++)
1730 #if !defined(_WIN32_WCE)
1731 ::SendMessageTimeout((*pModule
->m_pSettingChangeNotify
)[i
], uMsg
, wParam
, lParam
, SMTO_ABORTIFHUNG
, uTimeout
, NULL
);
1732 #elif(_WIN32_WCE >= 400) // CE specific
1733 ::SendMessageTimeout((*pModule
->m_pSettingChangeNotify
)[i
], uMsg
, wParam
, lParam
, SMTO_NORMAL
, uTimeout
, NULL
);
1734 #else // _WIN32_WCE < 400 specific
1736 ::SendMessage((*pModule
->m_pSettingChangeNotify
)[i
], uMsg
, wParam
, lParam
);
1746 ///////////////////////////////////////////////////////////////////////////////
1747 // CServerAppModule - module class for a COM server application
1749 class CServerAppModule
: public CAppModule
1752 HANDLE m_hEventShutdown
;
1757 // Override of CAppModule::Init
1758 HRESULT
Init(ATL::_ATL_OBJMAP_ENTRY
* pObjMap
, HINSTANCE hInstance
, const GUID
* pLibID
= NULL
)
1762 return CAppModule::Init(pObjMap
, hInstance
, pLibID
);
1767 if(m_hEventShutdown
!= NULL
&& ::CloseHandle(m_hEventShutdown
))
1768 m_hEventShutdown
= NULL
;
1772 // COM Server methods
1775 LONG lRet
= CComModule::Unlock();
1779 ::SetEvent(m_hEventShutdown
); // tell monitor that we transitioned to zero
1784 void MonitorShutdown()
1788 ::WaitForSingleObject(m_hEventShutdown
, INFINITE
);
1792 m_bActivity
= false;
1793 dwWait
= ::WaitForSingleObject(m_hEventShutdown
, m_dwTimeOut
);
1795 while(dwWait
== WAIT_OBJECT_0
);
1797 if(!m_bActivity
&& m_nLockCnt
== 0) // if no activity let's really bail
1799 #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE)
1800 ::CoSuspendClassObjects();
1801 if(!m_bActivity
&& m_nLockCnt
== 0)
1806 // This handle should be valid now. If it isn't,
1807 // check if _Module.Term was called first (it shouldn't)
1808 if(::CloseHandle(m_hEventShutdown
))
1809 m_hEventShutdown
= NULL
;
1810 ::PostThreadMessage(m_dwMainThreadID
, WM_QUIT
, 0, 0);
1815 m_hEventShutdown
= ::CreateEvent(NULL
, false, false, NULL
);
1816 if(m_hEventShutdown
== NULL
)
1818 DWORD dwThreadID
= 0;
1819 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
1820 HANDLE hThread
= (HANDLE
)_beginthreadex(NULL
, 0, (UINT (WINAPI
*)(void*))MonitorProc
, this, 0, (UINT
*)&dwThreadID
);
1822 HANDLE hThread
= ::CreateThread(NULL
, 0, MonitorProc
, this, 0, &dwThreadID
);
1824 bool bRet
= (hThread
!= NULL
);
1826 ::CloseHandle(hThread
);
1830 static DWORD WINAPI
MonitorProc(void* pv
)
1832 CServerAppModule
* p
= (CServerAppModule
*)pv
;
1833 p
->MonitorShutdown();
1837 #if (_ATL_VER < 0x0700)
1838 // search for an occurence of string p2 in string p1
1839 static LPCTSTR
FindOneOf(LPCTSTR p1
, LPCTSTR p2
)
1841 while(p1
!= NULL
&& *p1
!= NULL
)
1844 while(p
!= NULL
&& *p
!= NULL
)
1847 return ::CharNext(p1
);
1850 p1
= ::CharNext(p1
);
1854 #endif // (_ATL_VER < 0x0700)
1858 ///////////////////////////////////////////////////////////////////////////////
1859 // CRegKeyEx - adds type-specific methods to ATL3 CRegKey
1861 #if (_ATL_VER < 0x0700)
1863 class CRegKeyEx
: public ATL::CRegKey
1866 // Constructors and operators
1867 CRegKeyEx(HKEY hKey
= NULL
)
1872 CRegKeyEx(CRegKeyEx
& key
)
1874 Attach(key
.Detach());
1877 CRegKeyEx
& operator =(CRegKeyEx
& key
)
1880 Attach(key
.Detach());
1885 LONG
SetValue(LPCTSTR pszValueName
, DWORD dwType
, const void* pValue
, ULONG nBytes
)
1887 ATLASSERT(m_hKey
!= NULL
);
1888 return ::RegSetValueEx(m_hKey
, pszValueName
, NULL
, dwType
, static_cast<const BYTE
*>(pValue
), nBytes
);
1891 LONG
SetGUIDValue(LPCTSTR pszValueName
, REFGUID guidValue
)
1893 ATLASSERT(m_hKey
!= NULL
);
1895 OLECHAR szGUID
[64] = { 0 };
1896 ::StringFromGUID2(guidValue
, szGUID
, 64);
1899 LPCTSTR lpstr
= OLE2CT(szGUID
);
1902 return E_OUTOFMEMORY
;
1904 return SetStringValue(pszValueName
, lpstr
);
1907 LONG
SetBinaryValue(LPCTSTR pszValueName
, const void* pValue
, ULONG nBytes
)
1909 ATLASSERT(m_hKey
!= NULL
);
1910 return ::RegSetValueEx(m_hKey
, pszValueName
, NULL
, REG_BINARY
, reinterpret_cast<const BYTE
*>(pValue
), nBytes
);
1913 LONG
SetDWORDValue(LPCTSTR pszValueName
, DWORD dwValue
)
1915 ATLASSERT(m_hKey
!= NULL
);
1916 return ::RegSetValueEx(m_hKey
, pszValueName
, NULL
, REG_DWORD
, reinterpret_cast<const BYTE
*>(&dwValue
), sizeof(DWORD
));
1920 LONG
SetQWORDValue(LPCTSTR pszValueName
, ULONGLONG qwValue
)
1922 ATLASSERT(m_hKey
!= NULL
);
1923 return ::RegSetValueEx(m_hKey
, pszValueName
, NULL
, REG_QWORD
, reinterpret_cast<const BYTE
*>(&qwValue
), sizeof(ULONGLONG
));
1927 LONG
SetStringValue(LPCTSTR pszValueName
, LPCTSTR pszValue
, DWORD dwType
= REG_SZ
)
1929 ATLASSERT(m_hKey
!= NULL
);
1930 if(pszValue
== NULL
)
1933 return ERROR_INVALID_DATA
;
1935 ATLASSERT((dwType
== REG_SZ
) || (dwType
== REG_EXPAND_SZ
));
1937 return ::RegSetValueEx(m_hKey
, pszValueName
, NULL
, dwType
, reinterpret_cast<const BYTE
*>(pszValue
), (lstrlen(pszValue
) + 1) * sizeof(TCHAR
));
1940 LONG
SetMultiStringValue(LPCTSTR pszValueName
, LPCTSTR pszValue
)
1942 ATLASSERT(m_hKey
!= NULL
);
1943 if(pszValue
== NULL
)
1946 return ERROR_INVALID_DATA
;
1951 LPCTSTR pszTemp
= pszValue
;
1954 nLength
= lstrlen(pszTemp
) + 1;
1956 nBytes
+= nLength
* sizeof(TCHAR
);
1957 } while (nLength
!= 1);
1959 return ::RegSetValueEx(m_hKey
, pszValueName
, NULL
, REG_MULTI_SZ
, reinterpret_cast<const BYTE
*>(pszValue
), nBytes
);
1962 LONG
QueryValue(LPCTSTR pszValueName
, DWORD
* pdwType
, void* pData
, ULONG
* pnBytes
)
1964 ATLASSERT(m_hKey
!= NULL
);
1965 return ::RegQueryValueEx(m_hKey
, pszValueName
, NULL
, pdwType
, static_cast<LPBYTE
>(pData
), pnBytes
);
1968 LONG
QueryGUIDValue(LPCTSTR pszValueName
, GUID
& guidValue
)
1970 ATLASSERT(m_hKey
!= NULL
);
1972 guidValue
= GUID_NULL
;
1974 TCHAR szGUID
[64] = { 0 };
1976 LONG lRes
= QueryStringValue(pszValueName
, szGUID
, &nCount
);
1978 if (lRes
!= ERROR_SUCCESS
)
1981 if(szGUID
[0] != _T('{'))
1982 return ERROR_INVALID_DATA
;
1985 LPOLESTR lpstr
= T2OLE(szGUID
);
1988 return E_OUTOFMEMORY
;
1991 HRESULT hr
= ::CLSIDFromString(lpstr
, &guidValue
);
1993 return ERROR_INVALID_DATA
;
1995 return ERROR_SUCCESS
;
1998 LONG
QueryBinaryValue(LPCTSTR pszValueName
, void* pValue
, ULONG
* pnBytes
)
2000 ATLASSERT(pnBytes
!= NULL
);
2001 ATLASSERT(m_hKey
!= NULL
);
2004 LONG lRes
= ::RegQueryValueEx(m_hKey
, pszValueName
, NULL
, &dwType
, reinterpret_cast<LPBYTE
>(pValue
), pnBytes
);
2005 if (lRes
!= ERROR_SUCCESS
)
2007 if (dwType
!= REG_BINARY
)
2008 return ERROR_INVALID_DATA
;
2010 return ERROR_SUCCESS
;
2013 LONG
QueryDWORDValue(LPCTSTR pszValueName
, DWORD
& dwValue
)
2015 ATLASSERT(m_hKey
!= NULL
);
2017 ULONG nBytes
= sizeof(DWORD
);
2019 LONG lRes
= ::RegQueryValueEx(m_hKey
, pszValueName
, NULL
, &dwType
, reinterpret_cast<LPBYTE
>(&dwValue
), &nBytes
);
2020 if (lRes
!= ERROR_SUCCESS
)
2022 if (dwType
!= REG_DWORD
)
2023 return ERROR_INVALID_DATA
;
2025 return ERROR_SUCCESS
;
2029 LONG
QueryQWORDValue(LPCTSTR pszValueName
, ULONGLONG
& qwValue
)
2031 ATLASSERT(m_hKey
!= NULL
);
2033 ULONG nBytes
= sizeof(ULONGLONG
);
2035 LONG lRes
= ::RegQueryValueEx(m_hKey
, pszValueName
, NULL
, &dwType
, reinterpret_cast<LPBYTE
>(&qwValue
), &nBytes
);
2036 if (lRes
!= ERROR_SUCCESS
)
2038 if (dwType
!= REG_QWORD
)
2039 return ERROR_INVALID_DATA
;
2041 return ERROR_SUCCESS
;
2045 LONG
QueryStringValue(LPCTSTR pszValueName
, LPTSTR pszValue
, ULONG
* pnChars
)
2047 ATLASSERT(m_hKey
!= NULL
);
2048 ATLASSERT(pnChars
!= NULL
);
2050 ULONG nBytes
= (*pnChars
) * sizeof(TCHAR
);
2053 LONG lRes
= ::RegQueryValueEx(m_hKey
, pszValueName
, NULL
, &dwType
, reinterpret_cast<LPBYTE
>(pszValue
), &nBytes
);
2055 if (lRes
!= ERROR_SUCCESS
)
2060 if(dwType
!= REG_SZ
&& dwType
!= REG_EXPAND_SZ
)
2062 return ERROR_INVALID_DATA
;
2065 if (pszValue
!= NULL
)
2069 if ((nBytes
% sizeof(TCHAR
) != 0) || (pszValue
[nBytes
/ sizeof(TCHAR
) -1] != 0))
2070 return ERROR_INVALID_DATA
;
2074 pszValue
[0] = _T('\0');
2078 *pnChars
= nBytes
/ sizeof(TCHAR
);
2080 return ERROR_SUCCESS
;
2083 LONG
QueryMultiStringValue(LPCTSTR pszValueName
, LPTSTR pszValue
, ULONG
* pnChars
)
2085 ATLASSERT(m_hKey
!= NULL
);
2086 ATLASSERT(pnChars
!= NULL
);
2088 if (pszValue
!= NULL
&& *pnChars
< 2)
2089 return ERROR_INSUFFICIENT_BUFFER
;
2091 ULONG nBytes
= (*pnChars
) * sizeof(TCHAR
);
2094 LONG lRes
= ::RegQueryValueEx(m_hKey
, pszValueName
, NULL
, &dwType
, reinterpret_cast<LPBYTE
>(pszValue
), &nBytes
);
2095 if (lRes
!= ERROR_SUCCESS
)
2097 if (dwType
!= REG_MULTI_SZ
)
2098 return ERROR_INVALID_DATA
;
2099 if (pszValue
!= NULL
&& (nBytes
% sizeof(TCHAR
) != 0 || nBytes
/ sizeof(TCHAR
) < 1 || pszValue
[nBytes
/ sizeof(TCHAR
) - 1] != 0 || ((nBytes
/ sizeof(TCHAR
)) > 1 && pszValue
[nBytes
/ sizeof(TCHAR
) - 2] != 0)))
2100 return ERROR_INVALID_DATA
;
2102 *pnChars
= nBytes
/ sizeof(TCHAR
);
2104 return ERROR_SUCCESS
;
2108 #else // !(_ATL_VER < 0x0700)
2110 typedef ATL::CRegKey CRegKeyEx
;
2112 #endif // !(_ATL_VER < 0x0700)
2115 ///////////////////////////////////////////////////////////////////////////////
2116 // CString forward reference (enables CString use in atluser.h and atlgdi.h)
2118 #if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
2119 #define _WTL_USE_CSTRING
2120 #endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
2122 #ifdef _WTL_USE_CSTRING
2123 class CString
; // forward declaration (include atlmisc.h for the whole class)
2124 #endif // _WTL_USE_CSTRING
2126 // CString namespace
2129 #define _CSTRING_NS ATL
2131 #define _CSTRING_NS WTL
2133 #endif // _CSTRING_NS
2135 // Type classes namespace
2137 #ifdef __ATLTYPES_H__
2140 #define _WTYPES_NS WTL
2142 #endif // _WTYPES_NS
2147 ///////////////////////////////////////////////////////////////////////////////
2148 // General DLL version helpers
2149 // (ATL3: excluded from atlbase.h if _ATL_DLL is defined; ATL11: removed)
2151 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
2156 inline HRESULT
AtlGetDllVersion(HINSTANCE hInstDLL
, DLLVERSIONINFO
* pDllVersionInfo
)
2158 ATLASSERT(pDllVersionInfo
!= NULL
);
2159 if(pDllVersionInfo
== NULL
)
2160 return E_INVALIDARG
;
2162 // We must get this function explicitly because some DLLs don't implement it.
2163 DLLGETVERSIONPROC pfnDllGetVersion
= (DLLGETVERSIONPROC
)::GetProcAddress(hInstDLL
, "DllGetVersion");
2164 if(pfnDllGetVersion
== NULL
)
2167 return (*pfnDllGetVersion
)(pDllVersionInfo
);
2170 inline HRESULT
AtlGetDllVersion(LPCTSTR lpstrDllName
, DLLVERSIONINFO
* pDllVersionInfo
)
2172 HINSTANCE hInstDLL
= ::LoadLibrary(lpstrDllName
);
2173 if(hInstDLL
== NULL
)
2175 HRESULT hRet
= AtlGetDllVersion(hInstDLL
, pDllVersionInfo
);
2176 ::FreeLibrary(hInstDLL
);
2180 // Common Control Versions:
2181 // Win95/WinNT 4.0 maj=4 min=00
2182 // IE 3.x maj=4 min=70
2183 // IE 4.0 maj=4 min=71
2184 inline HRESULT
AtlGetCommCtrlVersion(LPDWORD pdwMajor
, LPDWORD pdwMinor
)
2186 ATLASSERT(pdwMajor
!= NULL
&& pdwMinor
!= NULL
);
2187 if(pdwMajor
== NULL
|| pdwMinor
== NULL
)
2188 return E_INVALIDARG
;
2191 ::ZeroMemory(&dvi
, sizeof(dvi
));
2192 dvi
.cbSize
= sizeof(dvi
);
2193 HRESULT hRet
= AtlGetDllVersion(_T("comctl32.dll"), &dvi
);
2197 *pdwMajor
= dvi
.dwMajorVersion
;
2198 *pdwMinor
= dvi
.dwMinorVersion
;
2200 else if(hRet
== E_NOTIMPL
)
2202 // If DllGetVersion is not there, then the DLL is a version
2203 // previous to the one shipped with IE 3.x
2213 // Win95/WinNT 4.0 maj=4 min=00
2214 // IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00
2215 // IE 4.0 with Web Integrated Desktop maj=4 min=71
2216 // IE 4.01 with Web Integrated Desktop maj=4 min=72
2217 inline HRESULT
AtlGetShellVersion(LPDWORD pdwMajor
, LPDWORD pdwMinor
)
2219 ATLASSERT(pdwMajor
!= NULL
&& pdwMinor
!= NULL
);
2220 if(pdwMajor
== NULL
|| pdwMinor
== NULL
)
2221 return E_INVALIDARG
;
2224 ::ZeroMemory(&dvi
, sizeof(dvi
));
2225 dvi
.cbSize
= sizeof(dvi
);
2226 HRESULT hRet
= AtlGetDllVersion(_T("shell32.dll"), &dvi
);
2230 *pdwMajor
= dvi
.dwMajorVersion
;
2231 *pdwMinor
= dvi
.dwMinorVersion
;
2233 else if(hRet
== E_NOTIMPL
)
2235 // If DllGetVersion is not there, then the DLL is a version
2236 // previous to the one shipped with IE 4.x
2247 #endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE)
2250 // These are always included
2251 #include "atlwinx.h"
2252 #include "atluser.h"
2255 #ifndef _WTL_NO_AUTOMATIC_NAMESPACE
2256 using namespace WTL
;
2257 #endif // !_WTL_NO_AUTOMATIC_NAMESPACE
2259 #endif // __ATLAPP_H__