crashrpt
atlapp.h
1 // Windows Template Library - WTL version 8.1
2 // Copyright (C) Microsoft Corporation. All rights reserved.
3 //
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.
11 
12 #ifndef __ATLAPP_H__
13 #define __ATLAPP_H__
14 
15 #pragma once
16 
17 #ifndef __cplusplus
18  #error WTL requires C++ compilation (use a .cpp suffix)
19 #endif
20 
21 #ifndef __ATLBASE_H__
22  #error atlapp.h requires atlbase.h to be included first
23 #endif
24 
25 #ifndef _WIN32_WCE
26  #if (WINVER < 0x0400)
27  #error WTL requires Windows version 4.0 or higher
28  #endif
29 
30  #if (_WIN32_IE < 0x0300)
31  #error WTL requires IE version 3.0 or higher
32  #endif
33 #endif
34 
35 #ifdef _ATL_NO_COMMODULE
36  #error WTL requires that _ATL_NO_COMMODULE is not defined
37 #endif
38 
39 #if (_ATL_VER >= 0x0900) && defined(_ATL_MIN_CRT)
40  #error _ATL_MIN_CRT is not supported with ATL 9.0 and higher
41 #endif
42 
43 #if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT)
44  #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT")
45 #endif
46 
47 #include <limits.h>
48 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
49  #include <process.h> // for _beginthreadex
50 #endif
51 
52 #if (_ATL_VER < 0x0800) && !defined(_DEBUG)
53  #include <stdio.h>
54 #endif
55 
56 #include <commctrl.h>
57 #ifndef _WIN32_WCE
58  #pragma comment(lib, "comctl32.lib")
59 #endif
60 
61 #ifndef _WIN32_WCE
62  #include "atlres.h"
63 #else // CE specific
64  #include "atlresce.h"
65 #endif // _WIN32_WCE
66 
67 // We need to disable this warning because of template class arguments
68 #pragma warning(disable: 4127)
69 
70 #if (_ATL_VER >= 0x0900) && !defined(_SECURE_ATL)
71  #define _SECURE_ATL 1
72 #endif
73 
74 
76 // WTL version number
77 
78 #define _WTL_VER 0x0810
79 
80 
82 // Classes in this file:
83 //
84 // CMessageFilter
85 // CIdleHandler
86 // CMessageLoop
87 //
88 // CAppModule
89 // CServerAppModule
90 //
91 // CRegKeyEx
92 //
93 // Global functions:
94 // AtlGetDefaultGuiFont()
95 // AtlCreateControlFont()
96 // AtlCreateBoldFont()
97 // AtlInitCommonControls()
98 
99 
101 // Global support for Windows CE
102 
103 #ifdef _WIN32_WCE
104 
105 #ifndef SW_SHOWDEFAULT
106  #define SW_SHOWDEFAULT SW_SHOWNORMAL
107 #endif // !SW_SHOWDEFAULT
108 
109 // These get's OR-ed in a constant and will have no effect.
110 // Defining them reduces the number of #ifdefs required for CE.
111 #define LR_DEFAULTSIZE 0
112 #define LR_LOADFROMFILE 0
113 
114 #ifndef SM_CXCURSOR
115  #define SM_CXCURSOR 13
116 #endif
117 #ifndef SM_CYCURSOR
118  #define SM_CYCURSOR 14
119 #endif
120 
121 inline BOOL IsMenu(HMENU hMenu)
122 {
123  MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
124  ::SetLastError(0);
125  BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii);
126  if(!bRet)
127  bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE : FALSE;
128  return bRet;
129 }
130 
131 #if (_WIN32_WCE >= 410)
132 extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight);
133 #endif // (_WIN32_WCE >= 410)
134 
135 inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator)
136 {
137  __int64 multiple = nNumber * nNumerator;
138  return static_cast<int>(multiple / nDenominator);
139 }
140 
141 #if (_ATL_VER >= 0x0800)
142 
143 #ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW
144  #ifdef WS_OVERLAPPEDWINDOW
145  #undef WS_OVERLAPPEDWINDOW
146  #define WS_OVERLAPPEDWINDOW 0
147  #endif // WS_OVERLAPPEDWINDOW
148 #endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW
149 
150 #ifndef RDW_FRAME
151  #define RDW_FRAME 0
152 #endif // !RDW_FRAME
153 
154 #ifndef WM_WINDOWPOSCHANGING
155  #define WM_WINDOWPOSCHANGING 0
156 #endif // !WM_WINDOWPOSCHANGING
157 
158 #define FreeResource(x)
159 #define UnlockResource(x)
160 
161 namespace ATL
162 {
163  inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw()
164  { return E_NOTIMPL; }
165  inline HRESULT CComModule::RevokeClassObjects() throw()
166  { return E_NOTIMPL; }
167 }; // namespace ATL
168 
169 #ifndef lstrlenW
170  #define lstrlenW (int)ATL::lstrlenW
171 #endif // lstrlenW
172 
173 inline int WINAPI lstrlenA(LPCSTR lpszString)
174 { return ATL::lstrlenA(lpszString); }
175 
176 #ifdef lstrcpyn
177  #undef lstrcpyn
178  #define lstrcpyn ATL::lstrcpynW
179 #endif // lstrcpyn
180 
181 #ifndef SetWindowLongPtrW
182  inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
183  {
184  return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) );
185  }
186  #define SetWindowLongPtrW tmp_SetWindowLongPtrW
187 #endif
188 
189 #ifndef GetWindowLongPtrW
190  inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex )
191  {
192  return( ::GetWindowLongW( hWnd, nIndex ) );
193  }
194  #define GetWindowLongPtrW tmp_GetWindowLongPtrW
195 #endif
196 
197 #ifndef LongToPtr
198  #define LongToPtr(x) ((void*)x)
199 #endif
200 
201 #ifndef PtrToInt
202  #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
203 #endif
204 
205 #else // !(_ATL_VER >= 0x0800)
206 
207 #ifdef lstrlenW
208  #undef lstrlenW
209  #define lstrlenW (int)::wcslen
210 #endif // lstrlenW
211 
212 #define lstrlenA (int)strlen
213 
214 #ifndef lstrcpyn
215  inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength)
216  {
217  if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0)
218  return NULL;
219  int nLen = min(lstrlen(lpstrSrc), nLength - 1);
220  LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR));
221  lpstrDest[nLen] = 0;
222  return lpstrRet;
223  }
224 #endif // !lstrcpyn
225 
226 #ifndef lstrcpynW
227  inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength)
228  {
229  return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode only
230  }
231 #endif // !lstrcpynW
232 
233 #ifndef lstrcpynA
234  inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength)
235  {
236  if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0)
237  return NULL;
238  int nLen = min(lstrlenA(lpstrSrc), nLength - 1);
239  LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char));
240  lpstrDest[nLen] = 0;
241  return lpstrRet;
242  }
243 #endif // !lstrcpyn
244 
245 #ifdef TrackPopupMenu
246  #undef TrackPopupMenu
247 #endif // TrackPopupMenu
248 
249 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
250 static CWndClassInfo& GetWndClassInfo() \
251 { \
252  static CWndClassInfo wc = \
253  { \
254  { style, StartWindowProc, \
255  0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \
256  NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
257  }; \
258  return wc; \
259 }
260 
261 #ifndef _MAX_FNAME
262  #define _MAX_FNAME _MAX_PATH
263 #endif // _MAX_FNAME
264 
265 #if (_WIN32_WCE < 400)
266  #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i)))
267 #endif // (_WIN32_WCE < 400)
268 
269 #if (_WIN32_WCE < 410)
270  #define WHEEL_PAGESCROLL (UINT_MAX)
271  #define WHEEL_DELTA 120
272 #endif // (_WIN32_WCE < 410)
273 
274 #ifdef DrawIcon
275  #undef DrawIcon
276 #endif
277 
278 #ifndef VARCMP_LT
279  #define VARCMP_LT 0
280 #endif
281 #ifndef VARCMP_EQ
282  #define VARCMP_EQ 1
283 #endif
284 #ifndef VARCMP_GT
285  #define VARCMP_GT 2
286 #endif
287 #ifndef VARCMP_NULL
288  #define VARCMP_NULL 3
289 #endif
290 
291 #ifndef RDW_ALLCHILDREN
292  #define RDW_ALLCHILDREN 0
293 #endif
294 
295 #endif // !(_ATL_VER >= 0x0800)
296 
297 #endif // _WIN32_WCE
298 
299 
301 // Global support for using original VC++ 6.0 headers with WTL
302 
303 #ifndef _ATL_NO_OLD_HEADERS_WIN64
304 #if !defined(_WIN64) && (_ATL_VER < 0x0700)
305 
306  #ifndef PSM_INSERTPAGE
307  #define PSM_INSERTPAGE (WM_USER + 119)
308  #endif // !PSM_INSERTPAGE
309 
310  #ifndef GetClassLongPtr
311  #define GetClassLongPtrA GetClassLongA
312  #define GetClassLongPtrW GetClassLongW
313  #ifdef UNICODE
314  #define GetClassLongPtr GetClassLongPtrW
315  #else
316  #define GetClassLongPtr GetClassLongPtrA
317  #endif // !UNICODE
318  #endif // !GetClassLongPtr
319 
320  #ifndef GCLP_HICONSM
321  #define GCLP_HICONSM (-34)
322  #endif // !GCLP_HICONSM
323 
324  #ifndef GetWindowLongPtr
325  #define GetWindowLongPtrA GetWindowLongA
326  #define GetWindowLongPtrW GetWindowLongW
327  #ifdef UNICODE
328  #define GetWindowLongPtr GetWindowLongPtrW
329  #else
330  #define GetWindowLongPtr GetWindowLongPtrA
331  #endif // !UNICODE
332  #endif // !GetWindowLongPtr
333 
334  #ifndef SetWindowLongPtr
335  #define SetWindowLongPtrA SetWindowLongA
336  #define SetWindowLongPtrW SetWindowLongW
337  #ifdef UNICODE
338  #define SetWindowLongPtr SetWindowLongPtrW
339  #else
340  #define SetWindowLongPtr SetWindowLongPtrA
341  #endif // !UNICODE
342  #endif // !SetWindowLongPtr
343 
344  #ifndef GWLP_WNDPROC
345  #define GWLP_WNDPROC (-4)
346  #endif
347  #ifndef GWLP_HINSTANCE
348  #define GWLP_HINSTANCE (-6)
349  #endif
350  #ifndef GWLP_HWNDPARENT
351  #define GWLP_HWNDPARENT (-8)
352  #endif
353  #ifndef GWLP_USERDATA
354  #define GWLP_USERDATA (-21)
355  #endif
356  #ifndef GWLP_ID
357  #define GWLP_ID (-12)
358  #endif
359 
360  #ifndef DWLP_MSGRESULT
361  #define DWLP_MSGRESULT 0
362  #endif
363 
364  typedef long LONG_PTR;
365  typedef unsigned long ULONG_PTR;
366  typedef ULONG_PTR DWORD_PTR;
367 
368  #ifndef HandleToUlong
369  #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) )
370  #endif
371  #ifndef HandleToLong
372  #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) )
373  #endif
374  #ifndef LongToHandle
375  #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h))
376  #endif
377  #ifndef PtrToUlong
378  #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) )
379  #endif
380  #ifndef PtrToLong
381  #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) )
382  #endif
383  #ifndef PtrToUint
384  #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) )
385  #endif
386  #ifndef PtrToInt
387  #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
388  #endif
389  #ifndef PtrToUshort
390  #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) )
391  #endif
392  #ifndef PtrToShort
393  #define PtrToShort( p ) ((short)(LONG_PTR)(p) )
394  #endif
395  #ifndef IntToPtr
396  #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i))
397  #endif
398  #ifndef UIntToPtr
399  #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui))
400  #endif
401  #ifndef LongToPtr
402  #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l))
403  #endif
404  #ifndef ULongToPtr
405  #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul))
406  #endif
407 
408 #endif // !defined(_WIN64) && (_ATL_VER < 0x0700)
409 #endif // !_ATL_NO_OLD_HEADERS_WIN64
410 
411 
413 // Global support for SecureHelper functions
414 
415 #ifndef _TRUNCATE
416  #define _TRUNCATE ((size_t)-1)
417 #endif
418 
419 #ifndef _ERRCODE_DEFINED
420  #define _ERRCODE_DEFINED
421  typedef int errno_t;
422 #endif
423 
424 #ifndef _SECURECRT_ERRCODE_VALUES_DEFINED
425  #define _SECURECRT_ERRCODE_VALUES_DEFINED
426  #define EINVAL 22
427  #define STRUNCATE 80
428 #endif
429 
430 #ifndef _countof
431  #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
432 #endif
433 
434 
436 // Miscellaneous global support
437 
438 // define useful macros from winuser.h
439 #ifndef IS_INTRESOURCE
440  #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
441 #endif // IS_INTRESOURCE
442 
443 // protect template members from windowsx.h macros
444 #ifdef _INC_WINDOWSX
445  #undef SubclassWindow
446 #endif // _INC_WINDOWSX
447 
448 // define useful macros from windowsx.h
449 #ifndef GET_X_LPARAM
450  #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam))
451 #endif
452 #ifndef GET_Y_LPARAM
453  #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam))
454 #endif
455 
456 // Dummy structs for compiling with /CLR
457 #if (_MSC_VER >= 1300) && defined(_MANAGED)
458  __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; }
459  __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; }
460  __if_not_exists(_PSP::_PSP) { struct _PSP { }; }
461 #endif
462 
463 // Define ATLVERIFY macro for ATL3
464 #if (_ATL_VER < 0x0700)
465  #ifndef ATLVERIFY
466  #ifdef _DEBUG
467  #define ATLVERIFY(expr) ATLASSERT(expr)
468  #else
469  #define ATLVERIFY(expr) (expr)
470  #endif // DEBUG
471  #endif // ATLVERIFY
472 #endif // (_ATL_VER < 0x0700)
473 
474 // Forward declaration for ATL3 and ATL11 fix
475 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
476  namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); };
477 #endif
478 
479 #ifndef WM_MOUSEHWHEEL
480  #define WM_MOUSEHWHEEL 0x020E
481 #endif
482 
483 
484 namespace WTL
485 {
486 
487 #if (_ATL_VER >= 0x0700)
488  DECLARE_TRACE_CATEGORY(atlTraceUI);
489  #ifdef _DEBUG
490  __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI"));
491  #endif // _DEBUG
492 #else // !(_ATL_VER >= 0x0700)
493  enum wtlTraceFlags
494  {
495  atlTraceUI = 0x10000000
496  };
497 #endif // !(_ATL_VER >= 0x0700)
498 
499 // Windows version helper
500 inline bool AtlIsOldWindows()
501 {
502  OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
503  BOOL bRet = ::GetVersionEx(&ovi);
504  return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90)));
505 }
506 
507 // Default GUI font helper - "MS Shell Dlg" stock font
508 inline HFONT AtlGetDefaultGuiFont()
509 {
510 #ifndef _WIN32_WCE
511  return (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
512 #else // CE specific
513  return (HFONT)::GetStockObject(SYSTEM_FONT);
514 #endif // _WIN32_WCE
515 }
516 
517 // Control font helper - default font for controls not in a dialog
518 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
519 inline HFONT AtlCreateControlFont()
520 {
521 #ifndef _WIN32_WCE
522  LOGFONT lf = { 0 };
523  ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
524  HFONT hFont = ::CreateFontIndirect(&lf);
525  ATLASSERT(hFont != NULL);
526  return hFont;
527 #else // CE specific
528  return (HFONT)::GetStockObject(SYSTEM_FONT);
529 #endif // _WIN32_WCE
530 }
531 
532 // Bold font helper
533 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
534 inline HFONT AtlCreateBoldFont(HFONT hFont = NULL)
535 {
536  LOGFONT lf = { 0 };
537 #ifndef _WIN32_WCE
538  if(hFont == NULL)
539  ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
540  else
541  ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
542 #else // CE specific
543  if(hFont == NULL)
544  hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
545  ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
546 #endif // _WIN32_WCE
547  lf.lfWeight = FW_BOLD;
548  HFONT hFontBold = ::CreateFontIndirect(&lf);
549  ATLASSERT(hFontBold != NULL);
550  return hFontBold;
551 }
552 
553 // Common Controls initialization helper
554 inline BOOL AtlInitCommonControls(DWORD dwFlags)
555 {
556  INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags };
557  BOOL bRet = ::InitCommonControlsEx(&iccx);
558  ATLASSERT(bRet);
559  return bRet;
560 }
561 
562 
564 // RunTimeHelper - helper functions for Windows version and structure sizes
565 
566 // Not for Windows CE
567 #if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE)
568  #define _WTL_NO_RUNTIME_STRUCT_SIZE
569 #endif
570 
571 #ifndef _WTL_NO_RUNTIME_STRUCT_SIZE
572 
573 #ifndef _SIZEOF_STRUCT
574  #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
575 #endif
576 
577 #if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
578  #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader)
579 #endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
580 
581 #if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
582  #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign)
583 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
584 
585 #if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
586  #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns)
587 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
588 
589 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
590  #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st)
591 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
592 
593 #if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
594  #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont)
595 #endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
596 
597 #endif // !_WTL_NO_RUNTIME_STRUCT_SIZE
598 
599 namespace RunTimeHelper
600 {
601 #ifndef _WIN32_WCE
602  inline bool IsCommCtrl6()
603  {
604  DWORD dwMajor = 0, dwMinor = 0;
605  HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
606  return (SUCCEEDED(hRet) && (dwMajor >= 6));
607  }
608 
609  inline bool IsVista()
610  {
611  OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
612  BOOL bRet = ::GetVersionEx(&ovi);
613  return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6));
614  }
615 
616  inline bool IsThemeAvailable()
617  {
618  bool bRet = false;
619 
620  if(IsCommCtrl6())
621  {
622  HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
623  if(hThemeDLL != NULL)
624  {
625  typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)();
626  PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive");
627  ATLASSERT(pfnIsThemeActive != NULL);
628  bRet = (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE);
629  if(bRet)
630  {
631  typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)();
632  PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed");
633  ATLASSERT(pfnIsAppThemed != NULL);
634  bRet = (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE);
635  }
636 
637  ::FreeLibrary(hThemeDLL);
638  }
639  }
640 
641  return bRet;
642  }
643 
644  inline bool IsWin7()
645  {
646  OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
647  BOOL bRet = ::GetVersionEx(&ovi);
648  return ((bRet != FALSE) && (ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1));
649  }
650 
651  inline bool IsRibbonUIAvailable()
652  {
653  static INT iRibbonUI = -1;
654 
655 #if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
656  if (iRibbonUI == -1)
657  {
658  HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll"));
659  if (hRibbonDLL != NULL)
660  {
661  const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } };
662  // block - create instance
663  {
664  ATL::CComPtr<IUnknown> pIUIFramework;
665  iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0;
666  }
667  ::FreeLibrary(hRibbonDLL);
668  }
669  else
670  {
671  iRibbonUI = 0;
672  }
673  }
674 #endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
675 
676  return (iRibbonUI == 1);
677  }
678 
679 #endif // !_WIN32_WCE
680 
681  inline int SizeOf_REBARBANDINFO()
682  {
683  int nSize = sizeof(REBARBANDINFO);
684 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
685  if(!(IsVista() && IsCommCtrl6()))
686  nSize = REBARBANDINFO_V6_SIZE;
687 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
688  return nSize;
689  }
690 
691 #if (_WIN32_WINNT >= 0x501)
692  inline int SizeOf_LVGROUP()
693  {
694  int nSize = sizeof(LVGROUP);
695 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
696  if(!IsVista())
697  nSize = LVGROUP_V5_SIZE;
698 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
699  return nSize;
700  }
701 
702  inline int SizeOf_LVTILEINFO()
703  {
704  int nSize = sizeof(LVTILEINFO);
705 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
706  if(!IsVista())
707  nSize = LVTILEINFO_V5_SIZE;
708 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
709  return nSize;
710  }
711 #endif // (_WIN32_WINNT >= 0x501)
712 
713  inline int SizeOf_MCHITTESTINFO()
714  {
715  int nSize = sizeof(MCHITTESTINFO);
716 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
717  if(!(IsVista() && IsCommCtrl6()))
718  nSize = MCHITTESTINFO_V1_SIZE;
719 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
720  return nSize;
721  }
722 
723 #ifndef _WIN32_WCE
724  inline int SizeOf_NONCLIENTMETRICS()
725  {
726  int nSize = sizeof(NONCLIENTMETRICS);
727 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
728  if(!IsVista())
729  nSize = NONCLIENTMETRICS_V1_SIZE;
730 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
731  return nSize;
732  }
733 #endif // !_WIN32_WCE
734 };
735 
736 
738 // ModuleHelper - helper functions for ATL3 and ATL7 module classes
739 
740 namespace ModuleHelper
741 {
742  inline HINSTANCE GetModuleInstance()
743  {
744 #if (_ATL_VER >= 0x0700)
745  return ATL::_AtlBaseModule.GetModuleInstance();
746 #else // !(_ATL_VER >= 0x0700)
747  return ATL::_pModule->GetModuleInstance();
748 #endif // !(_ATL_VER >= 0x0700)
749  }
750 
751  inline HINSTANCE GetResourceInstance()
752  {
753 #if (_ATL_VER >= 0x0700)
754  return ATL::_AtlBaseModule.GetResourceInstance();
755 #else // !(_ATL_VER >= 0x0700)
756  return ATL::_pModule->GetResourceInstance();
757 #endif // !(_ATL_VER >= 0x0700)
758  }
759 
760  inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject)
761  {
762 #if (_ATL_VER >= 0x0700)
763  ATL::_AtlWinModule.AddCreateWndData(pData, pObject);
764 #else // !(_ATL_VER >= 0x0700)
765  ATL::_pModule->AddCreateWndData(pData, pObject);
766 #endif // !(_ATL_VER >= 0x0700)
767  }
768 
769  inline void* ExtractCreateWndData()
770  {
771 #if (_ATL_VER >= 0x0700)
772  return ATL::_AtlWinModule.ExtractCreateWndData();
773 #else // !(_ATL_VER >= 0x0700)
774  return ATL::_pModule->ExtractCreateWndData();
775 #endif // !(_ATL_VER >= 0x0700)
776  }
777 };
778 
779 
781 // SecureHelper - helper functions for VS2005 secure CRT
782 
783 namespace SecureHelper
784 {
785  inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
786  {
787 #if _SECURE_ATL
788  ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc);
789 #else
790  if(cchDest > (size_t)lstrlenA(lpstrSrc))
791  ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL);
792  else
793  ATLASSERT(FALSE);
794 #endif
795  }
796 
797  inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
798  {
799 #if _SECURE_ATL
800  ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc);
801 #else
802  if(cchDest > (size_t)lstrlenW(lpstrSrc))
803  ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL);
804  else
805  ATLASSERT(FALSE);
806 #endif
807  }
808 
809  inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
810  {
811 #ifdef _UNICODE
812  strcpyW_x(lpstrDest, cchDest, lpstrSrc);
813 #else
814  strcpyA_x(lpstrDest, cchDest, lpstrSrc);
815 #endif
816  }
817 
818  inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount)
819  {
820 #if _SECURE_ATL
821  return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
822 #else
823  errno_t nRet = 0;
824  if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL)
825  {
826  nRet = EINVAL;
827  }
828  else if(cchCount == _TRUNCATE)
829  {
830  cchCount = min(cchDest - 1, size_t(lstrlenA(lpstrSrc)));
831  nRet = STRUNCATE;
832  }
833  else if(cchDest <= cchCount)
834  {
835  lpstrDest[0] = 0;
836  nRet = EINVAL;
837  }
838  if(nRet == 0 || nRet == STRUNCATE)
839  nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL;
840  ATLASSERT(nRet == 0 || nRet == STRUNCATE);
841  return nRet;
842 #endif
843  }
844 
845  inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount)
846  {
847 #if _SECURE_ATL
848  return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
849 #else
850  errno_t nRet = 0;
851  if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL)
852  {
853  nRet = EINVAL;
854  }
855  else if(cchCount == _TRUNCATE)
856  {
857  cchCount = min(cchDest - 1, size_t(lstrlenW(lpstrSrc)));
858  nRet = STRUNCATE;
859  }
860  else if(cchDest <= cchCount)
861  {
862  lpstrDest[0] = 0;
863  nRet = EINVAL;
864  }
865  if(nRet == 0 || nRet == STRUNCATE)
866  nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL;
867  ATLASSERT(nRet == 0 || nRet == STRUNCATE);
868  return nRet;
869 #endif
870  }
871 
872  inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount)
873  {
874 #ifdef _UNICODE
875  return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount);
876 #else
877  return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount);
878 #endif
879  }
880 
881  inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
882  {
883 #if _SECURE_ATL
884  ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc);
885 #else
886  if(cchDest > (size_t)lstrlenA(lpstrSrc))
887  ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL);
888  else
889  ATLASSERT(FALSE);
890 #endif
891  }
892 
893  inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
894  {
895 #if _SECURE_ATL
896  ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc);
897 #else
898  if(cchDest > (size_t)lstrlenW(lpstrSrc))
899  ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL);
900  else
901  ATLASSERT(FALSE);
902 #endif
903  }
904 
905  inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
906  {
907 #ifdef _UNICODE
908  strcatW_x(lpstrDest, cchDest, lpstrSrc);
909 #else
910  strcatA_x(lpstrDest, cchDest, lpstrSrc);
911 #endif
912  }
913 
914  inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
915  {
916 #if _SECURE_ATL
917  ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc);
918 #else
919  if(cbDest >= cbSrc)
920  memcpy(pDest, pSrc, cbSrc);
921  else
922  ATLASSERT(FALSE);
923 #endif
924  }
925 
926  inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
927  {
928 #if _SECURE_ATL
929  ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc);
930 #else
931  if(cbDest >= cbSrc)
932  memmove(pDest, pSrc, cbSrc);
933  else
934  ATLASSERT(FALSE);
935 #endif
936  }
937 
938  inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
939  {
940 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
941  return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
942 #else
943  cchBuff; // Avoid unused argument warning
944 #pragma warning(disable: 4996)
945  return _vstprintf(lpstrBuff, lpstrFormat, args);
946 #pragma warning(default: 4996)
947 #endif
948  }
949 
950  inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
951  {
952 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
953  return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
954 #else
955  cchBuff; // Avoid unused argument warning
956  return ::wvsprintf(lpstrBuff, lpstrFormat, args);
957 #endif
958  }
959 
960  inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
961  {
962  va_list args;
963  va_start(args, lpstrFormat);
964  int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
965  va_end(args);
966  return nRes;
967  }
968 
969  inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
970  {
971  va_list args;
972  va_start(args, lpstrFormat);
973  int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
974  va_end(args);
975  return nRes;
976  }
977 }; // namespace SecureHelper
978 
979 
981 // MinCrtHelper - helper functions for using _ATL_MIN_CRT
982 
983 namespace MinCrtHelper
984 {
985  inline int _isspace(TCHAR ch)
986  {
987 #ifndef _ATL_MIN_CRT
988  return _istspace(ch);
989 #else // _ATL_MIN_CRT
990  WORD type = 0;
991  ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
992  return (type & C1_SPACE) == C1_SPACE;
993 #endif // _ATL_MIN_CRT
994  }
995 
996  inline int _isdigit(TCHAR ch)
997  {
998 #ifndef _ATL_MIN_CRT
999  return _istdigit(ch);
1000 #else // _ATL_MIN_CRT
1001  WORD type = 0;
1002  ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
1003  return (type & C1_DIGIT) == C1_DIGIT;
1004 #endif // _ATL_MIN_CRT
1005  }
1006 
1007  inline int _atoi(LPCTSTR str)
1008  {
1009 #ifndef _ATL_MIN_CRT
1010  return _ttoi(str);
1011 #else // _ATL_MIN_CRT
1012  while(_isspace(*str) != 0)
1013  ++str;
1014 
1015  TCHAR ch = *str++;
1016  TCHAR sign = ch; // save sign indication
1017  if(ch == _T('-') || ch == _T('+'))
1018  ch = *str++; // skip sign
1019 
1020  int total = 0;
1021  while(_isdigit(ch) != 0)
1022  {
1023  total = 10 * total + (ch - '0'); // accumulate digit
1024  ch = *str++; // get next char
1025  }
1026 
1027  return (sign == '-') ? -total : total; // return result, negated if necessary
1028 #endif // _ATL_MIN_CRT
1029  }
1030 
1031  inline LPCTSTR _strrchr(LPCTSTR str, TCHAR ch)
1032  {
1033 #ifndef _ATL_MIN_CRT
1034  return _tcsrchr(str, ch);
1035 #else // _ATL_MIN_CRT
1036  LPCTSTR lpsz = NULL;
1037  while(*str != 0)
1038  {
1039  if(*str == ch)
1040  lpsz = str;
1041  str = ::CharNext(str);
1042  }
1043  return lpsz;
1044 #endif // _ATL_MIN_CRT
1045  }
1046 
1047  inline LPTSTR _strrchr(LPTSTR str, TCHAR ch)
1048  {
1049 #ifndef _ATL_MIN_CRT
1050  return _tcsrchr(str, ch);
1051 #else // _ATL_MIN_CRT
1052  LPTSTR lpsz = NULL;
1053  while(*str != 0)
1054  {
1055  if(*str == ch)
1056  lpsz = str;
1057  str = ::CharNext(str);
1058  }
1059  return lpsz;
1060 #endif // _ATL_MIN_CRT
1061  }
1062 }; // namespace MinCrtHelper
1063 
1064 
1066 // CMessageFilter - Interface for message filter support
1067 
1069 {
1070 public:
1071  virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
1072 };
1073 
1074 
1076 // CIdleHandler - Interface for idle processing
1077 
1079 {
1080 public:
1081  virtual BOOL OnIdle() = 0;
1082 };
1083 
1084 #ifndef _ATL_NO_OLD_NAMES
1085  // for compatilibility with old names only
1086  typedef CIdleHandler CUpdateUIObject;
1087  #define DoUpdate OnIdle
1088 #endif // !_ATL_NO_OLD_NAMES
1089 
1090 
1092 // CMessageLoop - message loop implementation
1093 
1095 {
1096 public:
1097  ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter;
1098  ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler;
1099  MSG m_msg;
1100 
1101 // Message filter operations
1102  BOOL AddMessageFilter(CMessageFilter* pMessageFilter)
1103  {
1104  return m_aMsgFilter.Add(pMessageFilter);
1105  }
1106 
1107  BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter)
1108  {
1109  return m_aMsgFilter.Remove(pMessageFilter);
1110  }
1111 
1112 // Idle handler operations
1113  BOOL AddIdleHandler(CIdleHandler* pIdleHandler)
1114  {
1115  return m_aIdleHandler.Add(pIdleHandler);
1116  }
1117 
1118  BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler)
1119  {
1120  return m_aIdleHandler.Remove(pIdleHandler);
1121  }
1122 
1123 #ifndef _ATL_NO_OLD_NAMES
1124  // for compatilibility with old names only
1125  BOOL AddUpdateUI(CIdleHandler* pIdleHandler)
1126  {
1127  ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1128  return AddIdleHandler(pIdleHandler);
1129  }
1130 
1131  BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler)
1132  {
1133  ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1134  return RemoveIdleHandler(pIdleHandler);
1135  }
1136 #endif // !_ATL_NO_OLD_NAMES
1137 
1138 // message loop
1139  int Run()
1140  {
1141  BOOL bDoIdle = TRUE;
1142  int nIdleCount = 0;
1143  BOOL bRet;
1144 
1145  for(;;)
1146  {
1147  while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
1148  {
1149  if(!OnIdle(nIdleCount++))
1150  bDoIdle = FALSE;
1151  }
1152 
1153  bRet = ::GetMessage(&m_msg, NULL, 0, 0);
1154 
1155  if(bRet == -1)
1156  {
1157  ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
1158  continue; // error, don't process
1159  }
1160  else if(!bRet)
1161  {
1162  ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
1163  break; // WM_QUIT, exit message loop
1164  }
1165 
1166  if(!PreTranslateMessage(&m_msg))
1167  {
1168  ::TranslateMessage(&m_msg);
1169  ::DispatchMessage(&m_msg);
1170  }
1171 
1172  if(IsIdleMessage(&m_msg))
1173  {
1174  bDoIdle = TRUE;
1175  nIdleCount = 0;
1176  }
1177  }
1178 
1179  return (int)m_msg.wParam;
1180  }
1181 
1182  static BOOL IsIdleMessage(MSG* pMsg)
1183  {
1184  // These messages should NOT cause idle processing
1185  switch(pMsg->message)
1186  {
1187  case WM_MOUSEMOVE:
1188 #ifndef _WIN32_WCE
1189  case WM_NCMOUSEMOVE:
1190 #endif // !_WIN32_WCE
1191  case WM_PAINT:
1192  case 0x0118: // WM_SYSTIMER (caret blink)
1193  return FALSE;
1194  }
1195 
1196  return TRUE;
1197  }
1198 
1199 // Overrideables
1200  // Override to change message filtering
1201  virtual BOOL PreTranslateMessage(MSG* pMsg)
1202  {
1203  // loop backwards
1204  for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)
1205  {
1206  CMessageFilter* pMessageFilter = m_aMsgFilter[i];
1207  if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg))
1208  return TRUE;
1209  }
1210  return FALSE; // not translated
1211  }
1212 
1213  // override to change idle processing
1214  virtual BOOL OnIdle(int /*nIdleCount*/)
1215  {
1216  for(int i = 0; i < m_aIdleHandler.GetSize(); i++)
1217  {
1218  CIdleHandler* pIdleHandler = m_aIdleHandler[i];
1219  if(pIdleHandler != NULL)
1220  pIdleHandler->OnIdle();
1221  }
1222  return FALSE; // don't continue
1223  }
1224 };
1225 
1226 
1228 // CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock
1229 // internal classes to manage critical sections for both ATL3 and ATL7
1230 
1232 {
1233 public:
1234 #if (_ATL_VER >= 0x0700)
1235  ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1236 
1237  CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false)
1238  { }
1239 #endif // (_ATL_VER >= 0x0700)
1240 
1241  HRESULT Lock()
1242  {
1243 #if (_ATL_VER >= 0x0700)
1244  return m_cslock.Lock();
1245 #else // !(_ATL_VER >= 0x0700)
1246  ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit);
1247  return S_OK;
1248 #endif // !(_ATL_VER >= 0x0700)
1249  }
1250 
1251  void Unlock()
1252  {
1253 #if (_ATL_VER >= 0x0700)
1254  m_cslock.Unlock();
1255 #else // !(_ATL_VER >= 0x0700)
1256  ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit);
1257 #endif // !(_ATL_VER >= 0x0700)
1258  }
1259 };
1260 
1261 
1263 {
1264 public:
1265 #if (_ATL_VER >= 0x0700)
1266  ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1267 
1268  CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false)
1269  { }
1270 #endif // (_ATL_VER >= 0x0700)
1271 
1272  HRESULT Lock()
1273  {
1274 #if (_ATL_VER >= 0x0700)
1275  return m_cslock.Lock();
1276 #else // !(_ATL_VER >= 0x0700)
1277  ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate);
1278  return S_OK;
1279 #endif // !(_ATL_VER >= 0x0700)
1280  }
1281 
1282  void Unlock()
1283  {
1284 #if (_ATL_VER >= 0x0700)
1285  m_cslock.Unlock();
1286 #else // !(_ATL_VER >= 0x0700)
1287  ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate);
1288 #endif // !(_ATL_VER >= 0x0700)
1289  }
1290 };
1291 
1292 
1294 // CTempBuffer - helper class for stack allocations for ATL3
1295 
1296 #ifndef _WTL_STACK_ALLOC_THRESHOLD
1297  #define _WTL_STACK_ALLOC_THRESHOLD 512
1298 #endif
1299 
1300 #if (_ATL_VER >= 0x0700)
1301 
1302 using ATL::CTempBuffer;
1303 
1304 #else // !(_ATL_VER >= 0x0700)
1305 
1306 #ifndef SIZE_MAX
1307  #ifdef _WIN64
1308  #define SIZE_MAX _UI64_MAX
1309  #else
1310  #define SIZE_MAX UINT_MAX
1311  #endif
1312 #endif
1313 
1314 #pragma warning(disable: 4284) // warning for operator ->
1315 
1316 template<typename T, int t_nFixedBytes = 128>
1318 {
1319 public:
1320  CTempBuffer() : m_p(NULL)
1321  {
1322  }
1323 
1324  CTempBuffer(size_t nElements) : m_p(NULL)
1325  {
1326  Allocate(nElements);
1327  }
1328 
1329  ~CTempBuffer()
1330  {
1331  if(m_p != reinterpret_cast<T*>(m_abFixedBuffer))
1332  free(m_p);
1333  }
1334 
1335  operator T*() const
1336  {
1337  return m_p;
1338  }
1339 
1340  T* operator ->() const
1341  {
1342  ATLASSERT(m_p != NULL);
1343  return m_p;
1344  }
1345 
1346  T* Allocate(size_t nElements)
1347  {
1348  ATLASSERT(nElements <= (SIZE_MAX / sizeof(T)));
1349  return AllocateBytes(nElements * sizeof(T));
1350  }
1351 
1352  T* AllocateBytes(size_t nBytes)
1353  {
1354  ATLASSERT(m_p == NULL);
1355  if(nBytes > t_nFixedBytes)
1356  m_p = static_cast<T*>(malloc(nBytes));
1357  else
1358  m_p = reinterpret_cast<T*>(m_abFixedBuffer);
1359 
1360  return m_p;
1361  }
1362 
1363 private:
1364  T* m_p;
1365  BYTE m_abFixedBuffer[t_nFixedBytes];
1366 };
1367 
1368 #pragma warning(default: 4284)
1369 
1370 #endif // !(_ATL_VER >= 0x0700)
1371 
1372 
1374 // CAppModule - module class for an application
1375 
1376 class CAppModule : public ATL::CComModule
1377 {
1378 public:
1379  DWORD m_dwMainThreadID;
1380  ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap;
1381  ATL::CSimpleArray<HWND>* m_pSettingChangeNotify;
1382 
1383 // Overrides of CComModule::Init and Term
1384  HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
1385  {
1386  HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID);
1387  if(FAILED(hRet))
1388  return hRet;
1389 
1390  m_dwMainThreadID = ::GetCurrentThreadId();
1391  typedef ATL::CSimpleMap<DWORD, CMessageLoop*> _mapClass;
1392  m_pMsgLoopMap = NULL;
1393  ATLTRY(m_pMsgLoopMap = new _mapClass);
1394  if(m_pMsgLoopMap == NULL)
1395  return E_OUTOFMEMORY;
1396  m_pSettingChangeNotify = NULL;
1397 
1398  return hRet;
1399  }
1400 
1401  void Term()
1402  {
1403  TermSettingChangeNotify();
1404  delete m_pMsgLoopMap;
1405  CComModule::Term();
1406  }
1407 
1408 // Message loop map methods
1409  BOOL AddMessageLoop(CMessageLoop* pMsgLoop)
1410  {
1412  if(FAILED(lock.Lock()))
1413  {
1414  ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
1415  ATLASSERT(FALSE);
1416  return FALSE;
1417  }
1418 
1419  ATLASSERT(pMsgLoop != NULL);
1420  ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL); // not in map yet
1421 
1422  BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop);
1423 
1424  lock.Unlock();
1425 
1426  return bRet;
1427  }
1428 
1429  BOOL RemoveMessageLoop()
1430  {
1432  if(FAILED(lock.Lock()))
1433  {
1434  ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
1435  ATLASSERT(FALSE);
1436  return FALSE;
1437  }
1438 
1439  BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId());
1440 
1441  lock.Unlock();
1442 
1443  return bRet;
1444  }
1445 
1446  CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const
1447  {
1449  if(FAILED(lock.Lock()))
1450  {
1451  ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
1452  ATLASSERT(FALSE);
1453  return NULL;
1454  }
1455 
1456  CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID);
1457 
1458  lock.Unlock();
1459 
1460  return pLoop;
1461  }
1462 
1463 // Setting change notify methods
1464  // Note: Call this from the main thread for MSDI apps
1465  BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc)
1466  {
1468  if(FAILED(lock.Lock()))
1469  {
1470  ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n"));
1471  ATLASSERT(FALSE);
1472  return FALSE;
1473  }
1474 
1475  if(m_pSettingChangeNotify == NULL)
1476  {
1477  typedef ATL::CSimpleArray<HWND> _notifyClass;
1478  ATLTRY(m_pSettingChangeNotify = new _notifyClass);
1479  ATLASSERT(m_pSettingChangeNotify != NULL);
1480  }
1481 
1482  BOOL bRet = (m_pSettingChangeNotify != NULL);
1483  if(bRet && m_pSettingChangeNotify->GetSize() == 0)
1484  {
1485  // init everything
1486  _ATL_EMPTY_DLGTEMPLATE templ;
1487  HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc);
1488  ATLASSERT(::IsWindow(hNtfWnd));
1489  if(::IsWindow(hNtfWnd))
1490  {
1491 // need conditional code because types don't match in winuser.h
1492 #ifdef _WIN64
1493  ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this);
1494 #else
1495  ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrToLong(this));
1496 #endif
1497  bRet = m_pSettingChangeNotify->Add(hNtfWnd);
1498  }
1499  else
1500  {
1501  bRet = FALSE;
1502  }
1503  }
1504 
1505  lock.Unlock();
1506 
1507  return bRet;
1508  }
1509 
1510  void TermSettingChangeNotify()
1511  {
1513  if(FAILED(lock.Lock()))
1514  {
1515  ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n"));
1516  ATLASSERT(FALSE);
1517  return;
1518  }
1519 
1520  if(m_pSettingChangeNotify != NULL && m_pSettingChangeNotify->GetSize() > 0)
1521  ::DestroyWindow((*m_pSettingChangeNotify)[0]);
1522  delete m_pSettingChangeNotify;
1523  m_pSettingChangeNotify = NULL;
1524 
1525  lock.Unlock();
1526  }
1527 
1528  BOOL AddSettingChangeNotify(HWND hWnd)
1529  {
1531  if(FAILED(lock.Lock()))
1532  {
1533  ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n"));
1534  ATLASSERT(FALSE);
1535  return FALSE;
1536  }
1537 
1538  ATLASSERT(::IsWindow(hWnd));
1539  BOOL bRet = FALSE;
1540  if(InitSettingChangeNotify() != FALSE)
1541  bRet = m_pSettingChangeNotify->Add(hWnd);
1542 
1543  lock.Unlock();
1544 
1545  return bRet;
1546  }
1547 
1548  BOOL RemoveSettingChangeNotify(HWND hWnd)
1549  {
1551  if(FAILED(lock.Lock()))
1552  {
1553  ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n"));
1554  ATLASSERT(FALSE);
1555  return FALSE;
1556  }
1557 
1558  BOOL bRet = FALSE;
1559  if(m_pSettingChangeNotify != NULL)
1560  bRet = m_pSettingChangeNotify->Remove(hWnd);
1561 
1562  lock.Unlock();
1563 
1564  return bRet;
1565  }
1566 
1567 // Implementation - setting change notify dialog template and dialog procedure
1568  struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE
1569  {
1571  {
1572  memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE));
1573  style = WS_POPUP;
1574  }
1575  WORD wMenu, wClass, wTitle;
1576  };
1577 
1578 #ifdef _WIN64
1579  static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1580 #else
1581  static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1582 #endif
1583  {
1584  if(uMsg == WM_SETTINGCHANGE)
1585  {
1586 // need conditional code because types don't match in winuser.h
1587 #ifdef _WIN64
1588  CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
1589 #else
1590  CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
1591 #endif
1592  ATLASSERT(pModule != NULL);
1593  ATLASSERT(pModule->m_pSettingChangeNotify != NULL);
1594  const UINT uTimeout = 1500; // ms
1595  for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++)
1596  {
1597 #if !defined(_WIN32_WCE)
1598  ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL);
1599 #elif(_WIN32_WCE >= 400) // CE specific
1600  ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL);
1601 #else // _WIN32_WCE < 400 specific
1602  uTimeout;
1603  ::SendMessage((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam);
1604 #endif
1605  }
1606  return TRUE;
1607  }
1608  return FALSE;
1609  }
1610 };
1611 
1612 
1614 // CServerAppModule - module class for a COM server application
1615 
1617 {
1618 public:
1619  HANDLE m_hEventShutdown;
1620  bool m_bActivity;
1621  DWORD m_dwTimeOut;
1622  DWORD m_dwPause;
1623 
1624 // Override of CAppModule::Init
1625  HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
1626  {
1627  m_dwTimeOut = 5000;
1628  m_dwPause = 1000;
1629  return CAppModule::Init(pObjMap, hInstance, pLibID);
1630  }
1631 
1632  void Term()
1633  {
1634  if(m_hEventShutdown != NULL && ::CloseHandle(m_hEventShutdown))
1635  m_hEventShutdown = NULL;
1636  CAppModule::Term();
1637  }
1638 
1639 // COM Server methods
1640  LONG Unlock()
1641  {
1642  LONG lRet = CComModule::Unlock();
1643  if(lRet == 0)
1644  {
1645  m_bActivity = true;
1646  ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero
1647  }
1648  return lRet;
1649  }
1650 
1651  void MonitorShutdown()
1652  {
1653  for(;;)
1654  {
1655  ::WaitForSingleObject(m_hEventShutdown, INFINITE);
1656  DWORD dwWait = 0;
1657  do
1658  {
1659  m_bActivity = false;
1660  dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
1661  }
1662  while(dwWait == WAIT_OBJECT_0);
1663  // timed out
1664  if(!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail
1665  {
1666 #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE)
1667  ::CoSuspendClassObjects();
1668  if(!m_bActivity && m_nLockCnt == 0)
1669 #endif
1670  break;
1671  }
1672  }
1673  // This handle should be valid now. If it isn't,
1674  // check if _Module.Term was called first (it shouldn't)
1675  if(::CloseHandle(m_hEventShutdown))
1676  m_hEventShutdown = NULL;
1677  ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
1678  }
1679 
1680  bool StartMonitor()
1681  {
1682  m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
1683  if(m_hEventShutdown == NULL)
1684  return false;
1685  DWORD dwThreadID = 0;
1686 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
1687  HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID);
1688 #else
1689  HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
1690 #endif
1691  bool bRet = (hThread != NULL);
1692  if(bRet)
1693  ::CloseHandle(hThread);
1694  return bRet;
1695  }
1696 
1697  static DWORD WINAPI MonitorProc(void* pv)
1698  {
1700  p->MonitorShutdown();
1701  return 0;
1702  }
1703 
1704 #if (_ATL_VER < 0x0700)
1705  // search for an occurence of string p2 in string p1
1706  static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
1707  {
1708  while(p1 != NULL && *p1 != NULL)
1709  {
1710  LPCTSTR p = p2;
1711  while(p != NULL && *p != NULL)
1712  {
1713  if(*p1 == *p)
1714  return ::CharNext(p1);
1715  p = ::CharNext(p);
1716  }
1717  p1 = ::CharNext(p1);
1718  }
1719  return NULL;
1720  }
1721 #endif // (_ATL_VER < 0x0700)
1722 };
1723 
1724 
1726 // CRegKeyEx - adds type-specific methods to ATL3 CRegKey
1727 
1728 #if (_ATL_VER < 0x0700)
1729 
1730 class CRegKeyEx : public ATL::CRegKey
1731 {
1732 public:
1733 // Constructors and operators
1734  CRegKeyEx(HKEY hKey = NULL)
1735  {
1736  m_hKey = hKey;
1737  }
1738 
1739  CRegKeyEx(CRegKeyEx& key)
1740  {
1741  Attach(key.Detach());
1742  }
1743 
1744  CRegKeyEx& operator =(CRegKeyEx& key)
1745  {
1746  Close();
1747  Attach(key.Detach());
1748  return *this;
1749  }
1750 
1751 // Methods
1752  LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes)
1753  {
1754  ATLASSERT(m_hKey != NULL);
1755  return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, static_cast<const BYTE*>(pValue), nBytes);
1756  }
1757 
1758  LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue)
1759  {
1760  ATLASSERT(m_hKey != NULL);
1761 
1762  OLECHAR szGUID[64] = { 0 };
1763  ::StringFromGUID2(guidValue, szGUID, 64);
1764 
1765  USES_CONVERSION;
1766  LPCTSTR lpstr = OLE2CT(szGUID);
1767 #ifndef _UNICODE
1768  if(lpstr == NULL)
1769  return E_OUTOFMEMORY;
1770 #endif
1771  return SetStringValue(pszValueName, lpstr);
1772  }
1773 
1774  LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes)
1775  {
1776  ATLASSERT(m_hKey != NULL);
1777  return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_BINARY, reinterpret_cast<const BYTE*>(pValue), nBytes);
1778  }
1779 
1780  LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue)
1781  {
1782  ATLASSERT(m_hKey != NULL);
1783  return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_DWORD, reinterpret_cast<const BYTE*>(&dwValue), sizeof(DWORD));
1784  }
1785 
1786 #ifndef _WIN32_WCE
1787  LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue)
1788  {
1789  ATLASSERT(m_hKey != NULL);
1790  return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_QWORD, reinterpret_cast<const BYTE*>(&qwValue), sizeof(ULONGLONG));
1791  }
1792 #endif
1793 
1794  LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ)
1795  {
1796  ATLASSERT(m_hKey != NULL);
1797  if(pszValue == NULL)
1798  {
1799  ATLASSERT(FALSE);
1800  return ERROR_INVALID_DATA;
1801  }
1802  ATLASSERT((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ));
1803 
1804  return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, reinterpret_cast<const BYTE*>(pszValue), (lstrlen(pszValue) + 1) * sizeof(TCHAR));
1805  }
1806 
1807  LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue)
1808  {
1809  ATLASSERT(m_hKey != NULL);
1810  if(pszValue == NULL)
1811  {
1812  ATLASSERT(FALSE);
1813  return ERROR_INVALID_DATA;
1814  }
1815 
1816  ULONG nBytes = 0;
1817  ULONG nLength = 0;
1818  LPCTSTR pszTemp = pszValue;
1819  do
1820  {
1821  nLength = lstrlen(pszTemp) + 1;
1822  pszTemp += nLength;
1823  nBytes += nLength * sizeof(TCHAR);
1824  } while (nLength != 1);
1825 
1826  return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_MULTI_SZ, reinterpret_cast<const BYTE*>(pszValue), nBytes);
1827  }
1828 
1829  LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes)
1830  {
1831  ATLASSERT(m_hKey != NULL);
1832  return ::RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, static_cast<LPBYTE>(pData), pnBytes);
1833  }
1834 
1835  LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue)
1836  {
1837  ATLASSERT(m_hKey != NULL);
1838 
1839  guidValue = GUID_NULL;
1840 
1841  TCHAR szGUID[64] = { 0 };
1842  ULONG nCount = 64;
1843  LONG lRes = QueryStringValue(pszValueName, szGUID, &nCount);
1844 
1845  if (lRes != ERROR_SUCCESS)
1846  return lRes;
1847 
1848  if(szGUID[0] != _T('{'))
1849  return ERROR_INVALID_DATA;
1850 
1851  USES_CONVERSION;
1852  LPOLESTR lpstr = T2OLE(szGUID);
1853 #ifndef _UNICODE
1854  if(lpstr == NULL)
1855  return E_OUTOFMEMORY;
1856 #endif
1857 
1858  HRESULT hr = ::CLSIDFromString(lpstr, &guidValue);
1859  if (FAILED(hr))
1860  return ERROR_INVALID_DATA;
1861 
1862  return ERROR_SUCCESS;
1863  }
1864 
1865  LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes)
1866  {
1867  ATLASSERT(pnBytes != NULL);
1868  ATLASSERT(m_hKey != NULL);
1869 
1870  DWORD dwType = 0;
1871  LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pValue), pnBytes);
1872  if (lRes != ERROR_SUCCESS)
1873  return lRes;
1874  if (dwType != REG_BINARY)
1875  return ERROR_INVALID_DATA;
1876 
1877  return ERROR_SUCCESS;
1878  }
1879 
1880  LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue)
1881  {
1882  ATLASSERT(m_hKey != NULL);
1883 
1884  ULONG nBytes = sizeof(DWORD);
1885  DWORD dwType = 0;
1886  LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&dwValue), &nBytes);
1887  if (lRes != ERROR_SUCCESS)
1888  return lRes;
1889  if (dwType != REG_DWORD)
1890  return ERROR_INVALID_DATA;
1891 
1892  return ERROR_SUCCESS;
1893  }
1894 
1895  LONG QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue)
1896  {
1897  ATLASSERT(m_hKey != NULL);
1898 
1899  ULONG nBytes = sizeof(ULONGLONG);
1900  DWORD dwType = 0;
1901  LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&qwValue), &nBytes);
1902  if (lRes != ERROR_SUCCESS)
1903  return lRes;
1904  if (dwType != REG_QWORD)
1905  return ERROR_INVALID_DATA;
1906 
1907  return ERROR_SUCCESS;
1908  }
1909 
1910  LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
1911  {
1912  ATLASSERT(m_hKey != NULL);
1913  ATLASSERT(pnChars != NULL);
1914 
1915  ULONG nBytes = (*pnChars) * sizeof(TCHAR);
1916  DWORD dwType = 0;
1917  *pnChars = 0;
1918  LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue), &nBytes);
1919 
1920  if (lRes != ERROR_SUCCESS)
1921  {
1922  return lRes;
1923  }
1924 
1925  if(dwType != REG_SZ && dwType != REG_EXPAND_SZ)
1926  {
1927  return ERROR_INVALID_DATA;
1928  }
1929 
1930  if (pszValue != NULL)
1931  {
1932  if(nBytes != 0)
1933  {
1934  if ((nBytes % sizeof(TCHAR) != 0) || (pszValue[nBytes / sizeof(TCHAR) -1] != 0))
1935  return ERROR_INVALID_DATA;
1936  }
1937  else
1938  {
1939  pszValue[0] = _T('\0');
1940  }
1941  }
1942 
1943  *pnChars = nBytes / sizeof(TCHAR);
1944 
1945  return ERROR_SUCCESS;
1946  }
1947 
1948  LONG QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
1949  {
1950  ATLASSERT(m_hKey != NULL);
1951  ATLASSERT(pnChars != NULL);
1952 
1953  if (pszValue != NULL && *pnChars < 2)
1954  return ERROR_INSUFFICIENT_BUFFER;
1955 
1956  ULONG nBytes = (*pnChars) * sizeof(TCHAR);
1957  DWORD dwType = 0;
1958  *pnChars = 0;
1959  LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue), &nBytes);
1960  if (lRes != ERROR_SUCCESS)
1961  return lRes;
1962  if (dwType != REG_MULTI_SZ)
1963  return ERROR_INVALID_DATA;
1964  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)))
1965  return ERROR_INVALID_DATA;
1966 
1967  *pnChars = nBytes / sizeof(TCHAR);
1968 
1969  return ERROR_SUCCESS;
1970  }
1971 };
1972 
1973 #else // !(_ATL_VER < 0x0700)
1974 
1975 typedef ATL::CRegKey CRegKeyEx;
1976 
1977 #endif // !(_ATL_VER < 0x0700)
1978 
1979 
1981 // CString forward reference (enables CString use in atluser.h and atlgdi.h)
1982 
1983 #if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
1984  #define _WTL_USE_CSTRING
1985 #endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
1986 
1987 #ifdef _WTL_USE_CSTRING
1988  class CString; // forward declaration (include atlmisc.h for the whole class)
1989 #endif // _WTL_USE_CSTRING
1990 
1991 // CString namespace
1992 #ifndef _CSTRING_NS
1993  #ifdef __ATLSTR_H__
1994  #define _CSTRING_NS ATL
1995  #else
1996  #define _CSTRING_NS WTL
1997  #endif
1998 #endif // _CSTRING_NS
1999 
2000 // Type classes namespace
2001 #ifndef _WTYPES_NS
2002  #ifdef __ATLTYPES_H__
2003  #define _WTYPES_NS
2004  #else
2005  #define _WTYPES_NS WTL
2006  #endif
2007 #endif // _WTYPES_NS
2008 
2009 }; // namespace WTL
2010 
2011 
2013 // General DLL version helpers
2014 // (ATL3: excluded from atlbase.h if _ATL_DLL is defined; ATL11: removed)
2015 
2016 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
2017 
2018 namespace ATL
2019 {
2020 
2021 inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
2022 {
2023  ATLASSERT(pDllVersionInfo != NULL);
2024  if(pDllVersionInfo == NULL)
2025  return E_INVALIDARG;
2026 
2027  // We must get this function explicitly because some DLLs don't implement it.
2028  DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
2029  if(pfnDllGetVersion == NULL)
2030  return E_NOTIMPL;
2031 
2032  return (*pfnDllGetVersion)(pDllVersionInfo);
2033 }
2034 
2035 inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
2036 {
2037  HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
2038  if(hInstDLL == NULL)
2039  return E_FAIL;
2040  HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
2041  ::FreeLibrary(hInstDLL);
2042  return hRet;
2043 }
2044 
2045 // Common Control Versions:
2046 // Win95/WinNT 4.0 maj=4 min=00
2047 // IE 3.x maj=4 min=70
2048 // IE 4.0 maj=4 min=71
2049 inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
2050 {
2051  ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
2052  if(pdwMajor == NULL || pdwMinor == NULL)
2053  return E_INVALIDARG;
2054 
2055  DLLVERSIONINFO dvi;
2056  ::ZeroMemory(&dvi, sizeof(dvi));
2057  dvi.cbSize = sizeof(dvi);
2058  HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
2059 
2060  if(SUCCEEDED(hRet))
2061  {
2062  *pdwMajor = dvi.dwMajorVersion;
2063  *pdwMinor = dvi.dwMinorVersion;
2064  }
2065  else if(hRet == E_NOTIMPL)
2066  {
2067  // If DllGetVersion is not there, then the DLL is a version
2068  // previous to the one shipped with IE 3.x
2069  *pdwMajor = 4;
2070  *pdwMinor = 0;
2071  hRet = S_OK;
2072  }
2073 
2074  return hRet;
2075 }
2076 
2077 // Shell Versions:
2078 // Win95/WinNT 4.0 maj=4 min=00
2079 // IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00
2080 // IE 4.0 with Web Integrated Desktop maj=4 min=71
2081 // IE 4.01 with Web Integrated Desktop maj=4 min=72
2082 inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
2083 {
2084  ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
2085  if(pdwMajor == NULL || pdwMinor == NULL)
2086  return E_INVALIDARG;
2087 
2088  DLLVERSIONINFO dvi;
2089  ::ZeroMemory(&dvi, sizeof(dvi));
2090  dvi.cbSize = sizeof(dvi);
2091  HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
2092 
2093  if(SUCCEEDED(hRet))
2094  {
2095  *pdwMajor = dvi.dwMajorVersion;
2096  *pdwMinor = dvi.dwMinorVersion;
2097  }
2098  else if(hRet == E_NOTIMPL)
2099  {
2100  // If DllGetVersion is not there, then the DLL is a version
2101  // previous to the one shipped with IE 4.x
2102  *pdwMajor = 4;
2103  *pdwMinor = 0;
2104  hRet = S_OK;
2105  }
2106 
2107  return hRet;
2108 }
2109 
2110 }; // namespace ATL
2111 
2112 #endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE)
2113 
2114 
2115 // These are always included
2116 #include "atlwinx.h"
2117 #include "atluser.h"
2118 #include "atlgdi.h"
2119 
2120 #ifndef _WTL_NO_AUTOMATIC_NAMESPACE
2121 using namespace WTL;
2122 #endif // !_WTL_NO_AUTOMATIC_NAMESPACE
2123 
2124 #endif // __ATLAPP_H__
Definition: atlapp.h:1068
Definition: atlapp.h:1730
Definition: atlapp.h:1094
Definition: atlapp.h:1262
Definition: atlapp.h:1376
Definition: atlapp.h:1078
Definition: atlmisc.h:760
Definition: stdafx.h:41
Definition: atlapp.h:484
Definition: atlapp.h:1317
Definition: atlapp.h:1616