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