Sync DrDump crash handler with TortoiseSVN codebase
[TortoiseGit.git] / ext / CrashServer / external / WTL / Include / atlapp.h
blob3d53756f0a543a3d2d22b5fdefd7ca273d23847d
1 // Windows Template Library - WTL version 9.0
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 // 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.
12 #ifndef __ATLAPP_H__
13 #define __ATLAPP_H__
15 #pragma once
17 #ifndef __cplusplus
18 #error WTL requires C++ compilation (use a .cpp suffix)
19 #endif
21 #ifndef __ATLBASE_H__
22 #error atlapp.h requires atlbase.h to be included first
23 #endif
25 #ifndef _WIN32_WCE
26 #if (WINVER < 0x0400)
27 #error WTL requires Windows version 4.0 or higher
28 #endif
30 #if (_WIN32_IE < 0x0300)
31 #error WTL requires IE version 3.0 or higher
32 #endif
33 #endif
35 #ifdef _ATL_NO_COMMODULE
36 #error WTL requires that _ATL_NO_COMMODULE is not defined
37 #endif
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
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
47 #include <limits.h>
48 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
49 #include <process.h> // for _beginthreadex
50 #endif
52 #if (_ATL_VER < 0x0800) && !defined(_DEBUG)
53 #include <stdio.h>
54 #endif
56 #include <commctrl.h>
57 #ifndef _WIN32_WCE
58 #pragma comment(lib, "comctl32.lib")
59 #endif
61 #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) && (_WIN32_WINNT >= 0x0501)
62 #include <VersionHelpers.h>
63 #endif
65 #ifndef _WIN32_WCE
66 #include "atlres.h"
67 #else // CE specific
68 #include "atlresce.h"
69 #endif // _WIN32_WCE
71 // We need to disable this warning because of template class arguments
72 #pragma warning(disable: 4127)
74 #if (_ATL_VER >= 0x0900) && !defined(_SECURE_ATL)
75 #define _SECURE_ATL 1
76 #endif
79 ///////////////////////////////////////////////////////////////////////////////
80 // WTL version number
82 #define _WTL_VER 0x0900
85 ///////////////////////////////////////////////////////////////////////////////
86 // Classes in this file:
88 // CMessageFilter
89 // CIdleHandler
90 // CMessageLoop
92 // CAppModule
93 // CServerAppModule
95 // CRegKeyEx
97 // Global functions:
98 // AtlGetDefaultGuiFont()
99 // AtlCreateControlFont()
100 // AtlCreateBoldFont()
101 // AtlInitCommonControls()
104 ///////////////////////////////////////////////////////////////////////////////
105 // Global support for Windows CE
107 #ifdef _WIN32_WCE
109 #ifndef SW_SHOWDEFAULT
110 #define SW_SHOWDEFAULT SW_SHOWNORMAL
111 #endif // !SW_SHOWDEFAULT
113 // These get's OR-ed in a constant and will have no effect.
114 // Defining them reduces the number of #ifdefs required for CE.
115 #define LR_DEFAULTSIZE 0
116 #define LR_LOADFROMFILE 0
118 #ifndef SM_CXCURSOR
119 #define SM_CXCURSOR 13
120 #endif
121 #ifndef SM_CYCURSOR
122 #define SM_CYCURSOR 14
123 #endif
125 inline BOOL IsMenu(HMENU hMenu)
127 MENUITEMINFO mii = { sizeof(MENUITEMINFO) };
128 ::SetLastError(0);
129 BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii);
130 if(!bRet)
131 bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE : FALSE;
132 return bRet;
135 #if (_WIN32_WCE >= 410)
136 extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight);
137 #endif // (_WIN32_WCE >= 410)
139 inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator)
141 __int64 multiple = nNumber * nNumerator;
142 return static_cast<int>(multiple / nDenominator);
145 #if (_ATL_VER >= 0x0800)
147 #ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW
148 #ifdef WS_OVERLAPPEDWINDOW
149 #undef WS_OVERLAPPEDWINDOW
150 #define WS_OVERLAPPEDWINDOW 0
151 #endif // WS_OVERLAPPEDWINDOW
152 #endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW
154 #ifndef RDW_FRAME
155 #define RDW_FRAME 0
156 #endif // !RDW_FRAME
158 #ifndef WM_WINDOWPOSCHANGING
159 #define WM_WINDOWPOSCHANGING 0
160 #endif // !WM_WINDOWPOSCHANGING
162 #define FreeResource(x)
163 #define UnlockResource(x)
165 namespace ATL
167 inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw()
168 { return E_NOTIMPL; }
169 inline HRESULT CComModule::RevokeClassObjects() throw()
170 { return E_NOTIMPL; }
171 }; // namespace ATL
173 #ifndef lstrlenW
174 #define lstrlenW (int)ATL::lstrlenW
175 #endif // lstrlenW
177 inline int WINAPI lstrlenA(LPCSTR lpszString)
178 { return ATL::lstrlenA(lpszString); }
180 #ifdef lstrcpyn
181 #undef lstrcpyn
182 #define lstrcpyn ATL::lstrcpynW
183 #endif // lstrcpyn
185 #ifndef SetWindowLongPtrW
186 inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLong )
188 return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) );
190 #define SetWindowLongPtrW tmp_SetWindowLongPtrW
191 #endif
193 #ifndef GetWindowLongPtrW
194 inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex )
196 return( ::GetWindowLongW( hWnd, nIndex ) );
198 #define GetWindowLongPtrW tmp_GetWindowLongPtrW
199 #endif
201 #ifndef LongToPtr
202 #define LongToPtr(x) ((void*)x)
203 #endif
205 #ifndef PtrToInt
206 #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
207 #endif
209 #else // !(_ATL_VER >= 0x0800)
211 #ifdef lstrlenW
212 #undef lstrlenW
213 #define lstrlenW (int)::wcslen
214 #endif // lstrlenW
216 #define lstrlenA (int)strlen
218 #ifndef lstrcpyn
219 inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength)
221 if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0)
222 return NULL;
223 int nLen = __min(lstrlen(lpstrSrc), nLength - 1);
224 LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHAR));
225 lpstrDest[nLen] = 0;
226 return lpstrRet;
228 #endif // !lstrcpyn
230 #ifndef lstrcpynW
231 inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength)
233 return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode only
235 #endif // !lstrcpynW
237 #ifndef lstrcpynA
238 inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength)
240 if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0)
241 return NULL;
242 int nLen = __min(lstrlenA(lpstrSrc), nLength - 1);
243 LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char));
244 lpstrDest[nLen] = 0;
245 return lpstrRet;
247 #endif // !lstrcpyn
249 #ifdef TrackPopupMenu
250 #undef TrackPopupMenu
251 #endif // TrackPopupMenu
253 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
254 static CWndClassInfo& GetWndClassInfo() \
256 static CWndClassInfo wc = \
258 { style, StartWindowProc, \
259 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName }, \
260 NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
261 }; \
262 return wc; \
265 #ifndef _MAX_FNAME
266 #define _MAX_FNAME _MAX_PATH
267 #endif // _MAX_FNAME
269 #if (_WIN32_WCE < 400)
270 #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i)))
271 #endif // (_WIN32_WCE < 400)
273 #if (_WIN32_WCE < 410)
274 #define WHEEL_PAGESCROLL (UINT_MAX)
275 #define WHEEL_DELTA 120
276 #endif // (_WIN32_WCE < 410)
278 #ifdef DrawIcon
279 #undef DrawIcon
280 #endif
282 #ifndef VARCMP_LT
283 #define VARCMP_LT 0
284 #endif
285 #ifndef VARCMP_EQ
286 #define VARCMP_EQ 1
287 #endif
288 #ifndef VARCMP_GT
289 #define VARCMP_GT 2
290 #endif
291 #ifndef VARCMP_NULL
292 #define VARCMP_NULL 3
293 #endif
295 #ifndef RDW_ALLCHILDREN
296 #define RDW_ALLCHILDREN 0
297 #endif
299 #endif // !(_ATL_VER >= 0x0800)
301 #endif // _WIN32_WCE
304 ///////////////////////////////////////////////////////////////////////////////
305 // Global support for using original VC++ 6.0 headers with WTL
307 #if (_MSC_VER < 1300) && !defined(_WIN32_WCE)
308 #ifndef REG_QWORD
309 #define REG_QWORD 11
310 #endif
312 #ifndef BS_PUSHBOX
313 #define BS_PUSHBOX 0x0000000AL
314 #endif
316 struct __declspec(uuid("000214e6-0000-0000-c000-000000000046")) IShellFolder;
317 struct __declspec(uuid("000214f9-0000-0000-c000-000000000046")) IShellLinkW;
318 struct __declspec(uuid("000214ee-0000-0000-c000-000000000046")) IShellLinkA;
319 #endif // (_MSC_VER < 1300) && !defined(_WIN32_WCE)
321 #ifndef _ATL_NO_OLD_HEADERS_WIN64
322 #if !defined(_WIN64) && (_ATL_VER < 0x0700)
324 #ifndef PSM_INSERTPAGE
325 #define PSM_INSERTPAGE (WM_USER + 119)
326 #endif // !PSM_INSERTPAGE
328 #ifndef GetClassLongPtr
329 #define GetClassLongPtrA GetClassLongA
330 #define GetClassLongPtrW GetClassLongW
331 #ifdef UNICODE
332 #define GetClassLongPtr GetClassLongPtrW
333 #else
334 #define GetClassLongPtr GetClassLongPtrA
335 #endif // !UNICODE
336 #endif // !GetClassLongPtr
338 #ifndef GCLP_HICONSM
339 #define GCLP_HICONSM (-34)
340 #endif // !GCLP_HICONSM
342 #ifndef GetWindowLongPtr
343 #define GetWindowLongPtrA GetWindowLongA
344 #define GetWindowLongPtrW GetWindowLongW
345 #ifdef UNICODE
346 #define GetWindowLongPtr GetWindowLongPtrW
347 #else
348 #define GetWindowLongPtr GetWindowLongPtrA
349 #endif // !UNICODE
350 #endif // !GetWindowLongPtr
352 #ifndef SetWindowLongPtr
353 #define SetWindowLongPtrA SetWindowLongA
354 #define SetWindowLongPtrW SetWindowLongW
355 #ifdef UNICODE
356 #define SetWindowLongPtr SetWindowLongPtrW
357 #else
358 #define SetWindowLongPtr SetWindowLongPtrA
359 #endif // !UNICODE
360 #endif // !SetWindowLongPtr
362 #ifndef GWLP_WNDPROC
363 #define GWLP_WNDPROC (-4)
364 #endif
365 #ifndef GWLP_HINSTANCE
366 #define GWLP_HINSTANCE (-6)
367 #endif
368 #ifndef GWLP_HWNDPARENT
369 #define GWLP_HWNDPARENT (-8)
370 #endif
371 #ifndef GWLP_USERDATA
372 #define GWLP_USERDATA (-21)
373 #endif
374 #ifndef GWLP_ID
375 #define GWLP_ID (-12)
376 #endif
378 #ifndef DWLP_MSGRESULT
379 #define DWLP_MSGRESULT 0
380 #endif
382 typedef long LONG_PTR;
383 typedef unsigned long ULONG_PTR;
384 typedef ULONG_PTR DWORD_PTR;
386 #ifndef HandleToUlong
387 #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) )
388 #endif
389 #ifndef HandleToLong
390 #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) )
391 #endif
392 #ifndef LongToHandle
393 #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h))
394 #endif
395 #ifndef PtrToUlong
396 #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) )
397 #endif
398 #ifndef PtrToLong
399 #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) )
400 #endif
401 #ifndef PtrToUint
402 #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) )
403 #endif
404 #ifndef PtrToInt
405 #define PtrToInt( p ) ((INT)(INT_PTR) (p) )
406 #endif
407 #ifndef PtrToUshort
408 #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) )
409 #endif
410 #ifndef PtrToShort
411 #define PtrToShort( p ) ((short)(LONG_PTR)(p) )
412 #endif
413 #ifndef IntToPtr
414 #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i))
415 #endif
416 #ifndef UIntToPtr
417 #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui))
418 #endif
419 #ifndef LongToPtr
420 #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l))
421 #endif
422 #ifndef ULongToPtr
423 #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul))
424 #endif
426 #endif // !defined(_WIN64) && (_ATL_VER < 0x0700)
427 #endif // !_ATL_NO_OLD_HEADERS_WIN64
430 ///////////////////////////////////////////////////////////////////////////////
431 // Global support for using original VC++ 7.x headers with WTL
433 #if (_MSC_VER >= 1300) && (_MSC_VER < 1400)
435 #ifndef BS_PUSHBOX
436 #define BS_PUSHBOX 0x0000000AL
437 #endif
439 #pragma warning(disable: 4244) // conversion from 'type1' to 'type2', possible loss of data
441 #endif // (_MSC_VER >= 1300) && (_MSC_VER < 1400)
444 ///////////////////////////////////////////////////////////////////////////////
445 // Global support for old SDK headers
447 #ifndef BTNS_BUTTON
448 #define BTNS_BUTTON TBSTYLE_BUTTON
449 #endif
451 #ifndef BTNS_SEP
452 #define BTNS_SEP TBSTYLE_SEP
453 #endif
455 #ifndef BTNS_CHECK
456 #define BTNS_CHECK TBSTYLE_CHECK
457 #endif
459 #ifndef BTNS_GROUP
460 #define BTNS_GROUP TBSTYLE_GROUP
461 #endif
463 #ifndef BTNS_CHECKGROUP
464 #define BTNS_CHECKGROUP TBSTYLE_CHECKGROUP
465 #endif
467 #if (_WIN32_IE >= 0x0300)
468 #ifndef BTNS_DROPDOWN
469 #define BTNS_DROPDOWN TBSTYLE_DROPDOWN
470 #endif
471 #endif
473 #if (_WIN32_IE >= 0x0400)
474 #ifndef BTNS_AUTOSIZE
475 #define BTNS_AUTOSIZE TBSTYLE_AUTOSIZE
476 #endif
478 #ifndef BTNS_NOPREFIX
479 #define BTNS_NOPREFIX TBSTYLE_NOPREFIX
480 #endif
481 #endif
484 ///////////////////////////////////////////////////////////////////////////////
485 // Global support for SecureHelper functions
487 #ifndef _TRUNCATE
488 #define _TRUNCATE ((size_t)-1)
489 #endif
491 #ifndef _ERRCODE_DEFINED
492 #define _ERRCODE_DEFINED
493 typedef int errno_t;
494 #endif
496 #ifndef _SECURECRT_ERRCODE_VALUES_DEFINED
497 #define _SECURECRT_ERRCODE_VALUES_DEFINED
498 #define EINVAL 22
499 #define STRUNCATE 80
500 #endif
502 #ifndef _countof
503 #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
504 #endif
507 ///////////////////////////////////////////////////////////////////////////////
508 // Miscellaneous global support
510 // define useful macros from winuser.h
511 #ifndef IS_INTRESOURCE
512 #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
513 #endif // IS_INTRESOURCE
515 // protect template members from windowsx.h macros
516 #ifdef _INC_WINDOWSX
517 #undef SubclassWindow
518 #endif // _INC_WINDOWSX
520 // define useful macros from windowsx.h
521 #ifndef GET_X_LPARAM
522 #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam))
523 #endif
524 #ifndef GET_Y_LPARAM
525 #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam))
526 #endif
528 // Dummy structs for compiling with /CLR
529 #if (_MSC_VER >= 1300) && defined(_MANAGED)
530 __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; }
531 __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; }
532 __if_not_exists(_PSP::_PSP) { struct _PSP { }; }
533 #endif
535 // Define ATLVERIFY macro for ATL3
536 #if (_ATL_VER < 0x0700)
537 #ifndef ATLVERIFY
538 #ifdef _DEBUG
539 #define ATLVERIFY(expr) ATLASSERT(expr)
540 #else
541 #define ATLVERIFY(expr) (expr)
542 #endif // DEBUG
543 #endif // ATLVERIFY
544 #endif // (_ATL_VER < 0x0700)
546 // Forward declaration for ATL3 and ATL11 fix
547 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
548 namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); };
549 #endif
551 #ifndef WM_MOUSEHWHEEL
552 #define WM_MOUSEHWHEEL 0x020E
553 #endif
556 namespace WTL
559 #if (_ATL_VER >= 0x0700)
560 DECLARE_TRACE_CATEGORY(atlTraceUI);
561 #ifdef _DEBUG
562 __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI"));
563 #endif // _DEBUG
564 #else // !(_ATL_VER >= 0x0700)
565 enum wtlTraceFlags
567 atlTraceUI = 0x10000000
569 #endif // !(_ATL_VER >= 0x0700)
571 // Windows version helper
572 inline bool AtlIsOldWindows()
574 #ifdef _versionhelpers_H_INCLUDED_
575 return !::IsWindowsVersionOrGreater(4, 90, 0);
576 #else // !_versionhelpers_H_INCLUDED_
577 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
578 BOOL bRet = ::GetVersionEx(&ovi);
579 return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4 && ovi.dwMinorVersion >= 90)));
580 #endif // _versionhelpers_H_INCLUDED_
583 // Default GUI font helper - "MS Shell Dlg" stock font
584 inline HFONT AtlGetDefaultGuiFont()
586 #ifndef _WIN32_WCE
587 return (HFONT)::GetStockObject(DEFAULT_GUI_FONT);
588 #else // CE specific
589 return (HFONT)::GetStockObject(SYSTEM_FONT);
590 #endif // _WIN32_WCE
593 // Control font helper - default font for controls not in a dialog
594 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
595 inline HFONT AtlCreateControlFont()
597 #ifndef _WIN32_WCE
598 LOGFONT lf = { 0 };
599 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
600 HFONT hFont = ::CreateFontIndirect(&lf);
601 ATLASSERT(hFont != NULL);
602 return hFont;
603 #else // CE specific
604 return (HFONT)::GetStockObject(SYSTEM_FONT);
605 #endif // _WIN32_WCE
608 // Bold font helper
609 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed)
610 inline HFONT AtlCreateBoldFont(HFONT hFont = NULL)
612 LOGFONT lf = { 0 };
613 #ifndef _WIN32_WCE
614 if(hFont == NULL)
615 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE);
616 else
617 ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
618 #else // CE specific
619 if(hFont == NULL)
620 hFont = (HFONT)::GetStockObject(SYSTEM_FONT);
621 ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT));
622 #endif // _WIN32_WCE
623 lf.lfWeight = FW_BOLD;
624 HFONT hFontBold = ::CreateFontIndirect(&lf);
625 ATLASSERT(hFontBold != NULL);
626 return hFontBold;
629 // Common Controls initialization helper
630 inline BOOL AtlInitCommonControls(DWORD dwFlags)
632 INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags };
633 BOOL bRet = ::InitCommonControlsEx(&iccx);
634 ATLASSERT(bRet);
635 return bRet;
639 ///////////////////////////////////////////////////////////////////////////////
640 // RunTimeHelper - helper functions for Windows version and structure sizes
642 // Not for Windows CE
643 #if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE)
644 #define _WTL_NO_RUNTIME_STRUCT_SIZE
645 #endif
647 #ifndef _WTL_NO_RUNTIME_STRUCT_SIZE
649 #ifndef _SIZEOF_STRUCT
650 #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
651 #endif
653 #if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
654 #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader)
655 #endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE)
657 #if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
658 #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign)
659 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE)
661 #if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
662 #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns)
663 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE)
665 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
666 #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st)
667 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE)
669 #if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
670 #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont)
671 #endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE)
673 #if !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0501) && !defined(TTTOOLINFO_V2_SIZE)
674 #define TTTOOLINFO_V2_SIZE _SIZEOF_STRUCT(TTTOOLINFO, lParam)
675 #endif // !defined(_WIN32_WCE) && (_WIN32_WINNT >= 0x0501) && !defined(TTTOOLINFO_V2_SIZE)
677 #endif // !_WTL_NO_RUNTIME_STRUCT_SIZE
679 namespace RunTimeHelper
681 #ifndef _WIN32_WCE
682 inline bool IsCommCtrl6()
684 DWORD dwMajor = 0, dwMinor = 0;
685 HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor);
686 return (SUCCEEDED(hRet) && (dwMajor >= 6));
689 inline bool IsVista()
691 #ifdef _versionhelpers_H_INCLUDED_
692 return ::IsWindowsVistaOrGreater();
693 #else // !_versionhelpers_H_INCLUDED_
694 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
695 BOOL bRet = ::GetVersionEx(&ovi);
696 return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6));
697 #endif // _versionhelpers_H_INCLUDED_
700 inline bool IsThemeAvailable()
702 bool bRet = false;
704 if(IsCommCtrl6())
706 HMODULE hThemeDLL = ::LoadLibrary(_T("uxtheme.dll"));
707 if(hThemeDLL != NULL)
709 typedef BOOL (STDAPICALLTYPE *PFN_IsThemeActive)();
710 PFN_IsThemeActive pfnIsThemeActive = (PFN_IsThemeActive)::GetProcAddress(hThemeDLL, "IsThemeActive");
711 ATLASSERT(pfnIsThemeActive != NULL);
712 bRet = (pfnIsThemeActive != NULL) && (pfnIsThemeActive() != FALSE);
713 if(bRet)
715 typedef BOOL (STDAPICALLTYPE *PFN_IsAppThemed)();
716 PFN_IsAppThemed pfnIsAppThemed = (PFN_IsAppThemed)::GetProcAddress(hThemeDLL, "IsAppThemed");
717 ATLASSERT(pfnIsAppThemed != NULL);
718 bRet = (pfnIsAppThemed != NULL) && (pfnIsAppThemed() != FALSE);
721 ::FreeLibrary(hThemeDLL);
725 return bRet;
728 inline bool IsWin7()
730 #ifdef _versionhelpers_H_INCLUDED_
731 return ::IsWindows7OrGreater();
732 #else // !_versionhelpers_H_INCLUDED_
733 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) };
734 BOOL bRet = ::GetVersionEx(&ovi);
735 return ((bRet != FALSE) && (ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1));
736 #endif // _versionhelpers_H_INCLUDED_
739 inline bool IsRibbonUIAvailable()
741 static INT iRibbonUI = -1;
743 #if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
744 if (iRibbonUI == -1)
746 HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll"));
747 if (hRibbonDLL != NULL)
749 const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } };
750 // block - create instance
752 ATL::CComPtr<IUnknown> pIUIFramework;
753 iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0;
755 ::FreeLibrary(hRibbonDLL);
757 else
759 iRibbonUI = 0;
762 #endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7)
764 return (iRibbonUI == 1);
767 #endif // !_WIN32_WCE
769 inline int SizeOf_REBARBANDINFO()
771 int nSize = sizeof(REBARBANDINFO);
772 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
773 if(!(IsVista() && IsCommCtrl6()))
774 nSize = REBARBANDINFO_V6_SIZE;
775 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
776 return nSize;
779 #if (_WIN32_WINNT >= 0x501)
780 inline int SizeOf_LVGROUP()
782 int nSize = sizeof(LVGROUP);
783 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
784 if(!IsVista())
785 nSize = LVGROUP_V5_SIZE;
786 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
787 return nSize;
790 inline int SizeOf_LVTILEINFO()
792 int nSize = sizeof(LVTILEINFO);
793 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
794 if(!IsVista())
795 nSize = LVTILEINFO_V5_SIZE;
796 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600)
797 return nSize;
799 #endif // (_WIN32_WINNT >= 0x501)
801 inline int SizeOf_MCHITTESTINFO()
803 int nSize = sizeof(MCHITTESTINFO);
804 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
805 if(!(IsVista() && IsCommCtrl6()))
806 nSize = MCHITTESTINFO_V1_SIZE;
807 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
808 return nSize;
811 #ifndef _WIN32_WCE
812 inline int SizeOf_NONCLIENTMETRICS()
814 int nSize = sizeof(NONCLIENTMETRICS);
815 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
816 if(!IsVista())
817 nSize = NONCLIENTMETRICS_V1_SIZE;
818 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600)
819 return nSize;
822 inline int SizeOf_TOOLINFO()
824 int nSize = sizeof(TOOLINFO);
825 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0501)
826 if(!IsVista())
827 nSize = TTTOOLINFO_V2_SIZE;
828 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0501)
829 return nSize;
831 #endif // !_WIN32_WCE
835 ///////////////////////////////////////////////////////////////////////////////
836 // ModuleHelper - helper functions for ATL3 and ATL7 module classes
838 namespace ModuleHelper
840 inline HINSTANCE GetModuleInstance()
842 #if (_ATL_VER >= 0x0700)
843 return ATL::_AtlBaseModule.GetModuleInstance();
844 #else // !(_ATL_VER >= 0x0700)
845 return ATL::_pModule->GetModuleInstance();
846 #endif // !(_ATL_VER >= 0x0700)
849 inline HINSTANCE GetResourceInstance()
851 #if (_ATL_VER >= 0x0700)
852 return ATL::_AtlBaseModule.GetResourceInstance();
853 #else // !(_ATL_VER >= 0x0700)
854 return ATL::_pModule->GetResourceInstance();
855 #endif // !(_ATL_VER >= 0x0700)
858 inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject)
860 #if (_ATL_VER >= 0x0700)
861 ATL::_AtlWinModule.AddCreateWndData(pData, pObject);
862 #else // !(_ATL_VER >= 0x0700)
863 ATL::_pModule->AddCreateWndData(pData, pObject);
864 #endif // !(_ATL_VER >= 0x0700)
867 inline void* ExtractCreateWndData()
869 #if (_ATL_VER >= 0x0700)
870 return ATL::_AtlWinModule.ExtractCreateWndData();
871 #else // !(_ATL_VER >= 0x0700)
872 return ATL::_pModule->ExtractCreateWndData();
873 #endif // !(_ATL_VER >= 0x0700)
878 ///////////////////////////////////////////////////////////////////////////////
879 // SecureHelper - helper functions for VS2005 secure CRT
881 namespace SecureHelper
883 inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
885 #if _SECURE_ATL
886 ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc);
887 #else
888 if(cchDest > (size_t)lstrlenA(lpstrSrc))
889 ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL);
890 else
891 ATLASSERT(FALSE);
892 #endif
895 inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
897 #if _SECURE_ATL
898 ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc);
899 #else
900 if(cchDest > (size_t)lstrlenW(lpstrSrc))
901 ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL);
902 else
903 ATLASSERT(FALSE);
904 #endif
907 inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
909 #ifdef _UNICODE
910 strcpyW_x(lpstrDest, cchDest, lpstrSrc);
911 #else
912 strcpyA_x(lpstrDest, cchDest, lpstrSrc);
913 #endif
916 inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount)
918 #if _SECURE_ATL
919 return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
920 #else
921 errno_t nRet = 0;
922 if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL)
924 nRet = EINVAL;
926 else if(cchCount == _TRUNCATE)
928 cchCount = __min(cchDest - 1, size_t(lstrlenA(lpstrSrc)));
929 nRet = STRUNCATE;
931 else if(cchDest <= cchCount)
933 lpstrDest[0] = 0;
934 nRet = EINVAL;
936 if(nRet == 0 || nRet == STRUNCATE)
937 nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL;
938 ATLASSERT(nRet == 0 || nRet == STRUNCATE);
939 return nRet;
940 #endif
943 inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount)
945 #if _SECURE_ATL
946 return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount);
947 #else
948 errno_t nRet = 0;
949 if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL)
951 nRet = EINVAL;
953 else if(cchCount == _TRUNCATE)
955 cchCount = __min(cchDest - 1, size_t(lstrlenW(lpstrSrc)));
956 nRet = STRUNCATE;
958 else if(cchDest <= cchCount)
960 lpstrDest[0] = 0;
961 nRet = EINVAL;
963 if(nRet == 0 || nRet == STRUNCATE)
964 nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1) != NULL) ? nRet : EINVAL;
965 ATLASSERT(nRet == 0 || nRet == STRUNCATE);
966 return nRet;
967 #endif
970 inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount)
972 #ifdef _UNICODE
973 return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount);
974 #else
975 return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount);
976 #endif
979 inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc)
981 #if _SECURE_ATL
982 ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc);
983 #else
984 if(cchDest > (size_t)lstrlenA(lpstrSrc))
985 ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL);
986 else
987 ATLASSERT(FALSE);
988 #endif
991 inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc)
993 #if _SECURE_ATL
994 ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc);
995 #else
996 if(cchDest > (size_t)lstrlenW(lpstrSrc))
997 ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL);
998 else
999 ATLASSERT(FALSE);
1000 #endif
1003 inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc)
1005 #ifdef _UNICODE
1006 strcatW_x(lpstrDest, cchDest, lpstrSrc);
1007 #else
1008 strcatA_x(lpstrDest, cchDest, lpstrSrc);
1009 #endif
1012 inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
1014 #if _SECURE_ATL
1015 ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc);
1016 #else
1017 if(cbDest >= cbSrc)
1018 memcpy(pDest, pSrc, cbSrc);
1019 else
1020 ATLASSERT(FALSE);
1021 #endif
1024 inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc)
1026 #if _SECURE_ATL
1027 ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc);
1028 #else
1029 if(cbDest >= cbSrc)
1030 memmove(pDest, pSrc, cbSrc);
1031 else
1032 ATLASSERT(FALSE);
1033 #endif
1036 inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
1038 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
1039 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
1040 #else
1041 cchBuff; // Avoid unused argument warning
1042 #pragma warning(push)
1043 #pragma warning(disable: 4996)
1044 return _vstprintf(lpstrBuff, lpstrFormat, args);
1045 #pragma warning(pop)
1046 #endif
1049 inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
1051 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
1052 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
1053 #else
1054 cchBuff; // Avoid unused argument warning
1055 return ::wvsprintf(lpstrBuff, lpstrFormat, args);
1056 #endif
1059 inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
1061 va_list args;
1062 va_start(args, lpstrFormat);
1063 int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
1064 va_end(args);
1065 return nRes;
1068 inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...)
1070 va_list args;
1071 va_start(args, lpstrFormat);
1072 int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args);
1073 va_end(args);
1074 return nRes;
1076 }; // namespace SecureHelper
1079 ///////////////////////////////////////////////////////////////////////////////
1080 // MinCrtHelper - helper functions for using _ATL_MIN_CRT
1082 namespace MinCrtHelper
1084 inline int _isspace(TCHAR ch)
1086 #ifndef _ATL_MIN_CRT
1087 return _istspace(ch);
1088 #else // _ATL_MIN_CRT
1089 WORD type = 0;
1090 ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
1091 return (type & C1_SPACE) == C1_SPACE;
1092 #endif // _ATL_MIN_CRT
1095 inline int _isdigit(TCHAR ch)
1097 #ifndef _ATL_MIN_CRT
1098 return _istdigit(ch);
1099 #else // _ATL_MIN_CRT
1100 WORD type = 0;
1101 ::GetStringTypeEx(::GetThreadLocale(), CT_CTYPE1, &ch, 1, &type);
1102 return (type & C1_DIGIT) == C1_DIGIT;
1103 #endif // _ATL_MIN_CRT
1106 inline int _atoi(LPCTSTR str)
1108 #ifndef _ATL_MIN_CRT
1109 return _ttoi(str);
1110 #else // _ATL_MIN_CRT
1111 while(_isspace(*str) != 0)
1112 ++str;
1114 TCHAR ch = *str++;
1115 TCHAR sign = ch; // save sign indication
1116 if(ch == _T('-') || ch == _T('+'))
1117 ch = *str++; // skip sign
1119 int total = 0;
1120 while(_isdigit(ch) != 0)
1122 total = 10 * total + (ch - '0'); // accumulate digit
1123 ch = *str++; // get next char
1126 return (sign == '-') ? -total : total; // return result, negated if necessary
1127 #endif // _ATL_MIN_CRT
1130 inline LPCTSTR _strrchr(LPCTSTR str, TCHAR ch)
1132 #ifndef _ATL_MIN_CRT
1133 return _tcsrchr(str, ch);
1134 #else // _ATL_MIN_CRT
1135 LPCTSTR lpsz = NULL;
1136 while(*str != 0)
1138 if(*str == ch)
1139 lpsz = str;
1140 str = ::CharNext(str);
1142 return lpsz;
1143 #endif // _ATL_MIN_CRT
1146 inline LPTSTR _strrchr(LPTSTR str, TCHAR ch)
1148 #ifndef _ATL_MIN_CRT
1149 return _tcsrchr(str, ch);
1150 #else // _ATL_MIN_CRT
1151 LPTSTR lpsz = NULL;
1152 while(*str != 0)
1154 if(*str == ch)
1155 lpsz = str;
1156 str = ::CharNext(str);
1158 return lpsz;
1159 #endif // _ATL_MIN_CRT
1161 }; // namespace MinCrtHelper
1164 ///////////////////////////////////////////////////////////////////////////////
1165 // GenericWndClass - generic window class usable for subclassing
1167 // Use in dialog templates to specify a placeholder to be subclassed
1168 // Specify as a custom control with class name WTL_GenericWindow
1169 // Call Rregister() before creating dialog (for example, in WinMain)
1170 namespace GenericWndClass
1172 inline LPCTSTR GetName()
1174 return _T("WTL_GenericWindow");
1177 inline ATOM Register()
1179 WNDCLASSEX wc = { sizeof(WNDCLASSEX) };
1180 wc.lpfnWndProc = ::DefWindowProc;
1181 wc.hInstance = ModuleHelper::GetModuleInstance();
1182 wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
1183 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1184 wc.lpszClassName = GetName();
1185 ATOM atom = ::RegisterClassEx(&wc);
1186 ATLASSERT(atom != 0);
1187 return atom;
1190 inline BOOL Unregister() // only needed for DLLs or tmp use
1192 return ::UnregisterClass(GetName(), ModuleHelper::GetModuleInstance());
1194 }; // namespace GenericWndClass
1197 ///////////////////////////////////////////////////////////////////////////////
1198 // CMessageFilter - Interface for message filter support
1200 class CMessageFilter
1202 public:
1203 virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
1207 ///////////////////////////////////////////////////////////////////////////////
1208 // CIdleHandler - Interface for idle processing
1210 class CIdleHandler
1212 public:
1213 virtual BOOL OnIdle() = 0;
1216 #ifndef _ATL_NO_OLD_NAMES
1217 // for compatilibility with old names only
1218 typedef CIdleHandler CUpdateUIObject;
1219 #define DoUpdate OnIdle
1220 #endif // !_ATL_NO_OLD_NAMES
1223 ///////////////////////////////////////////////////////////////////////////////
1224 // CMessageLoop - message loop implementation
1226 class CMessageLoop
1228 public:
1229 ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter;
1230 ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler;
1231 MSG m_msg;
1233 // Message filter operations
1234 BOOL AddMessageFilter(CMessageFilter* pMessageFilter)
1236 return m_aMsgFilter.Add(pMessageFilter);
1239 BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter)
1241 return m_aMsgFilter.Remove(pMessageFilter);
1244 // Idle handler operations
1245 BOOL AddIdleHandler(CIdleHandler* pIdleHandler)
1247 return m_aIdleHandler.Add(pIdleHandler);
1250 BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler)
1252 return m_aIdleHandler.Remove(pIdleHandler);
1255 #ifndef _ATL_NO_OLD_NAMES
1256 // for compatilibility with old names only
1257 BOOL AddUpdateUI(CIdleHandler* pIdleHandler)
1259 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1260 return AddIdleHandler(pIdleHandler);
1263 BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler)
1265 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI are deprecated. Please change your code to use CIdleHandler and OnIdle\n"));
1266 return RemoveIdleHandler(pIdleHandler);
1268 #endif // !_ATL_NO_OLD_NAMES
1270 // message loop
1271 int Run()
1273 BOOL bDoIdle = TRUE;
1274 int nIdleCount = 0;
1275 BOOL bRet;
1277 for(;;)
1279 while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
1281 if(!OnIdle(nIdleCount++))
1282 bDoIdle = FALSE;
1285 bRet = ::GetMessage(&m_msg, NULL, 0, 0);
1287 if(bRet == -1)
1289 ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
1290 continue; // error, don't process
1292 else if(!bRet)
1294 ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
1295 break; // WM_QUIT, exit message loop
1298 if(!PreTranslateMessage(&m_msg))
1300 ::TranslateMessage(&m_msg);
1301 ::DispatchMessage(&m_msg);
1304 if(IsIdleMessage(&m_msg))
1306 bDoIdle = TRUE;
1307 nIdleCount = 0;
1311 return (int)m_msg.wParam;
1314 static BOOL IsIdleMessage(MSG* pMsg)
1316 // These messages should NOT cause idle processing
1317 switch(pMsg->message)
1319 case WM_MOUSEMOVE:
1320 #ifndef _WIN32_WCE
1321 case WM_NCMOUSEMOVE:
1322 #endif // !_WIN32_WCE
1323 case WM_PAINT:
1324 case 0x0118: // WM_SYSTIMER (caret blink)
1325 return FALSE;
1328 return TRUE;
1331 // Overrideables
1332 // Override to change message filtering
1333 virtual BOOL PreTranslateMessage(MSG* pMsg)
1335 // loop backwards
1336 for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)
1338 CMessageFilter* pMessageFilter = m_aMsgFilter[i];
1339 if(pMessageFilter != NULL && pMessageFilter->PreTranslateMessage(pMsg))
1340 return TRUE;
1342 return FALSE; // not translated
1345 // override to change idle processing
1346 virtual BOOL OnIdle(int /*nIdleCount*/)
1348 for(int i = 0; i < m_aIdleHandler.GetSize(); i++)
1350 CIdleHandler* pIdleHandler = m_aIdleHandler[i];
1351 if(pIdleHandler != NULL)
1352 pIdleHandler->OnIdle();
1354 return FALSE; // don't continue
1359 ///////////////////////////////////////////////////////////////////////////////
1360 // CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock
1361 // internal classes to manage critical sections for both ATL3 and ATL7
1363 class CStaticDataInitCriticalSectionLock
1365 public:
1366 #if (_ATL_VER >= 0x0700)
1367 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1369 CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false)
1371 #endif // (_ATL_VER >= 0x0700)
1373 HRESULT Lock()
1375 #if (_ATL_VER >= 0x0700)
1376 return m_cslock.Lock();
1377 #else // !(_ATL_VER >= 0x0700)
1378 ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit);
1379 return S_OK;
1380 #endif // !(_ATL_VER >= 0x0700)
1383 void Unlock()
1385 #if (_ATL_VER >= 0x0700)
1386 m_cslock.Unlock();
1387 #else // !(_ATL_VER >= 0x0700)
1388 ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit);
1389 #endif // !(_ATL_VER >= 0x0700)
1394 class CWindowCreateCriticalSectionLock
1396 public:
1397 #if (_ATL_VER >= 0x0700)
1398 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1400 CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false)
1402 #endif // (_ATL_VER >= 0x0700)
1404 HRESULT Lock()
1406 #if (_ATL_VER >= 0x0700)
1407 return m_cslock.Lock();
1408 #else // !(_ATL_VER >= 0x0700)
1409 ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate);
1410 return S_OK;
1411 #endif // !(_ATL_VER >= 0x0700)
1414 void Unlock()
1416 #if (_ATL_VER >= 0x0700)
1417 m_cslock.Unlock();
1418 #else // !(_ATL_VER >= 0x0700)
1419 ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate);
1420 #endif // !(_ATL_VER >= 0x0700)
1425 ///////////////////////////////////////////////////////////////////////////////
1426 // CTempBuffer - helper class for stack allocations for ATL3
1428 #ifndef _WTL_STACK_ALLOC_THRESHOLD
1429 #define _WTL_STACK_ALLOC_THRESHOLD 512
1430 #endif
1432 #if (_ATL_VER >= 0x0700)
1434 using ATL::CTempBuffer;
1436 #else // !(_ATL_VER >= 0x0700)
1438 #ifndef SIZE_MAX
1439 #ifdef _WIN64
1440 #define SIZE_MAX _UI64_MAX
1441 #else
1442 #define SIZE_MAX UINT_MAX
1443 #endif
1444 #endif
1446 #pragma warning(push)
1447 #pragma warning(disable: 4284) // warning for operator ->
1449 template<typename T, int t_nFixedBytes = 128>
1450 class CTempBuffer
1452 public:
1453 CTempBuffer() : m_p(NULL)
1457 CTempBuffer(size_t nElements) : m_p(NULL)
1459 Allocate(nElements);
1462 ~CTempBuffer()
1464 if(m_p != reinterpret_cast<T*>(m_abFixedBuffer))
1465 free(m_p);
1468 operator T*() const
1470 return m_p;
1473 T* operator ->() const
1475 ATLASSERT(m_p != NULL);
1476 return m_p;
1479 T* Allocate(size_t nElements)
1481 ATLASSERT(nElements <= (SIZE_MAX / sizeof(T)));
1482 return AllocateBytes(nElements * sizeof(T));
1485 T* AllocateBytes(size_t nBytes)
1487 ATLASSERT(m_p == NULL);
1488 if(nBytes > t_nFixedBytes)
1489 m_p = static_cast<T*>(malloc(nBytes));
1490 else
1491 m_p = reinterpret_cast<T*>(m_abFixedBuffer);
1493 return m_p;
1496 private:
1497 T* m_p;
1498 BYTE m_abFixedBuffer[t_nFixedBytes];
1501 #pragma warning(pop)
1503 #endif // !(_ATL_VER >= 0x0700)
1506 ///////////////////////////////////////////////////////////////////////////////
1507 // CAppModule - module class for an application
1509 class CAppModule : public ATL::CComModule
1511 public:
1512 DWORD m_dwMainThreadID;
1513 ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap;
1514 ATL::CSimpleArray<HWND>* m_pSettingChangeNotify;
1516 // Overrides of CComModule::Init and Term
1517 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
1519 HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID);
1520 if(FAILED(hRet))
1521 return hRet;
1523 m_dwMainThreadID = ::GetCurrentThreadId();
1524 typedef ATL::CSimpleMap<DWORD, CMessageLoop*> _mapClass;
1525 m_pMsgLoopMap = NULL;
1526 ATLTRY(m_pMsgLoopMap = new _mapClass);
1527 if(m_pMsgLoopMap == NULL)
1528 return E_OUTOFMEMORY;
1529 m_pSettingChangeNotify = NULL;
1531 return hRet;
1534 void Term()
1536 TermSettingChangeNotify();
1537 delete m_pMsgLoopMap;
1538 CComModule::Term();
1541 // Message loop map methods
1542 BOOL AddMessageLoop(CMessageLoop* pMsgLoop)
1544 CStaticDataInitCriticalSectionLock lock;
1545 if(FAILED(lock.Lock()))
1547 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
1548 ATLASSERT(FALSE);
1549 return FALSE;
1552 ATLASSERT(pMsgLoop != NULL);
1553 ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL); // not in map yet
1555 BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop);
1557 lock.Unlock();
1559 return bRet;
1562 BOOL RemoveMessageLoop()
1564 CStaticDataInitCriticalSectionLock lock;
1565 if(FAILED(lock.Lock()))
1567 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
1568 ATLASSERT(FALSE);
1569 return FALSE;
1572 BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId());
1574 lock.Unlock();
1576 return bRet;
1579 CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const
1581 CStaticDataInitCriticalSectionLock lock;
1582 if(FAILED(lock.Lock()))
1584 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
1585 ATLASSERT(FALSE);
1586 return NULL;
1589 CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID);
1591 lock.Unlock();
1593 return pLoop;
1596 // Setting change notify methods
1597 // Note: Call this from the main thread for MSDI apps
1598 BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc)
1600 CStaticDataInitCriticalSectionLock lock;
1601 if(FAILED(lock.Lock()))
1603 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n"));
1604 ATLASSERT(FALSE);
1605 return FALSE;
1608 if(m_pSettingChangeNotify == NULL)
1610 typedef ATL::CSimpleArray<HWND> _notifyClass;
1611 ATLTRY(m_pSettingChangeNotify = new _notifyClass);
1612 ATLASSERT(m_pSettingChangeNotify != NULL);
1615 BOOL bRet = (m_pSettingChangeNotify != NULL);
1616 if(bRet && m_pSettingChangeNotify->GetSize() == 0)
1618 // init everything
1619 _ATL_EMPTY_DLGTEMPLATE templ;
1620 HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc);
1621 ATLASSERT(::IsWindow(hNtfWnd));
1622 if(::IsWindow(hNtfWnd))
1624 // need conditional code because types don't match in winuser.h
1625 #ifdef _WIN64
1626 ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this);
1627 #else
1628 ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrToLong(this));
1629 #endif
1630 bRet = m_pSettingChangeNotify->Add(hNtfWnd);
1632 else
1634 bRet = FALSE;
1638 lock.Unlock();
1640 return bRet;
1643 void TermSettingChangeNotify()
1645 CStaticDataInitCriticalSectionLock lock;
1646 if(FAILED(lock.Lock()))
1648 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n"));
1649 ATLASSERT(FALSE);
1650 return;
1653 if(m_pSettingChangeNotify != NULL && m_pSettingChangeNotify->GetSize() > 0)
1654 ::DestroyWindow((*m_pSettingChangeNotify)[0]);
1655 delete m_pSettingChangeNotify;
1656 m_pSettingChangeNotify = NULL;
1658 lock.Unlock();
1661 BOOL AddSettingChangeNotify(HWND hWnd)
1663 CStaticDataInitCriticalSectionLock lock;
1664 if(FAILED(lock.Lock()))
1666 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n"));
1667 ATLASSERT(FALSE);
1668 return FALSE;
1671 ATLASSERT(::IsWindow(hWnd));
1672 BOOL bRet = FALSE;
1673 if(InitSettingChangeNotify() != FALSE)
1674 bRet = m_pSettingChangeNotify->Add(hWnd);
1676 lock.Unlock();
1678 return bRet;
1681 BOOL RemoveSettingChangeNotify(HWND hWnd)
1683 CStaticDataInitCriticalSectionLock lock;
1684 if(FAILED(lock.Lock()))
1686 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n"));
1687 ATLASSERT(FALSE);
1688 return FALSE;
1691 BOOL bRet = FALSE;
1692 if(m_pSettingChangeNotify != NULL)
1693 bRet = m_pSettingChangeNotify->Remove(hWnd);
1695 lock.Unlock();
1697 return bRet;
1700 // Implementation - setting change notify dialog template and dialog procedure
1701 struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE
1703 _ATL_EMPTY_DLGTEMPLATE()
1705 memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE));
1706 style = WS_POPUP;
1708 WORD wMenu, wClass, wTitle;
1711 #ifdef _WIN64
1712 static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1713 #else
1714 static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1715 #endif
1717 if(uMsg == WM_SETTINGCHANGE)
1719 // need conditional code because types don't match in winuser.h
1720 #ifdef _WIN64
1721 CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
1722 #else
1723 CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
1724 #endif
1725 ATLASSERT(pModule != NULL);
1726 ATLASSERT(pModule->m_pSettingChangeNotify != NULL);
1727 const UINT uTimeout = 1500; // ms
1728 for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++)
1730 #if !defined(_WIN32_WCE)
1731 ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL);
1732 #elif(_WIN32_WCE >= 400) // CE specific
1733 ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL);
1734 #else // _WIN32_WCE < 400 specific
1735 uTimeout;
1736 ::SendMessage((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam);
1737 #endif
1739 return TRUE;
1741 return FALSE;
1746 ///////////////////////////////////////////////////////////////////////////////
1747 // CServerAppModule - module class for a COM server application
1749 class CServerAppModule : public CAppModule
1751 public:
1752 HANDLE m_hEventShutdown;
1753 bool m_bActivity;
1754 DWORD m_dwTimeOut;
1755 DWORD m_dwPause;
1757 // Override of CAppModule::Init
1758 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
1760 m_dwTimeOut = 5000;
1761 m_dwPause = 1000;
1762 return CAppModule::Init(pObjMap, hInstance, pLibID);
1765 void Term()
1767 if(m_hEventShutdown != NULL && ::CloseHandle(m_hEventShutdown))
1768 m_hEventShutdown = NULL;
1769 CAppModule::Term();
1772 // COM Server methods
1773 LONG Unlock()
1775 LONG lRet = CComModule::Unlock();
1776 if(lRet == 0)
1778 m_bActivity = true;
1779 ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero
1781 return lRet;
1784 void MonitorShutdown()
1786 for(;;)
1788 ::WaitForSingleObject(m_hEventShutdown, INFINITE);
1789 DWORD dwWait = 0;
1792 m_bActivity = false;
1793 dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
1795 while(dwWait == WAIT_OBJECT_0);
1796 // timed out
1797 if(!m_bActivity && m_nLockCnt == 0) // if no activity let's really bail
1799 #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THREADED) && !defined(_WIN32_WCE)
1800 ::CoSuspendClassObjects();
1801 if(!m_bActivity && m_nLockCnt == 0)
1802 #endif
1803 break;
1806 // This handle should be valid now. If it isn't,
1807 // check if _Module.Term was called first (it shouldn't)
1808 if(::CloseHandle(m_hEventShutdown))
1809 m_hEventShutdown = NULL;
1810 ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
1813 bool StartMonitor()
1815 m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
1816 if(m_hEventShutdown == NULL)
1817 return false;
1818 DWORD dwThreadID = 0;
1819 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE)
1820 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID);
1821 #else
1822 HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
1823 #endif
1824 bool bRet = (hThread != NULL);
1825 if(bRet)
1826 ::CloseHandle(hThread);
1827 return bRet;
1830 static DWORD WINAPI MonitorProc(void* pv)
1832 CServerAppModule* p = (CServerAppModule*)pv;
1833 p->MonitorShutdown();
1834 return 0;
1837 #if (_ATL_VER < 0x0700)
1838 // search for an occurence of string p2 in string p1
1839 static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
1841 while(p1 != NULL && *p1 != NULL)
1843 LPCTSTR p = p2;
1844 while(p != NULL && *p != NULL)
1846 if(*p1 == *p)
1847 return ::CharNext(p1);
1848 p = ::CharNext(p);
1850 p1 = ::CharNext(p1);
1852 return NULL;
1854 #endif // (_ATL_VER < 0x0700)
1858 ///////////////////////////////////////////////////////////////////////////////
1859 // CRegKeyEx - adds type-specific methods to ATL3 CRegKey
1861 #if (_ATL_VER < 0x0700)
1863 class CRegKeyEx : public ATL::CRegKey
1865 public:
1866 // Constructors and operators
1867 CRegKeyEx(HKEY hKey = NULL)
1869 m_hKey = hKey;
1872 CRegKeyEx(CRegKeyEx& key)
1874 Attach(key.Detach());
1877 CRegKeyEx& operator =(CRegKeyEx& key)
1879 Close();
1880 Attach(key.Detach());
1881 return *this;
1884 // Methods
1885 LONG SetValue(LPCTSTR pszValueName, DWORD dwType, const void* pValue, ULONG nBytes)
1887 ATLASSERT(m_hKey != NULL);
1888 return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, static_cast<const BYTE*>(pValue), nBytes);
1891 LONG SetGUIDValue(LPCTSTR pszValueName, REFGUID guidValue)
1893 ATLASSERT(m_hKey != NULL);
1895 OLECHAR szGUID[64] = { 0 };
1896 ::StringFromGUID2(guidValue, szGUID, 64);
1898 USES_CONVERSION;
1899 LPCTSTR lpstr = OLE2CT(szGUID);
1900 #ifndef _UNICODE
1901 if(lpstr == NULL)
1902 return E_OUTOFMEMORY;
1903 #endif
1904 return SetStringValue(pszValueName, lpstr);
1907 LONG SetBinaryValue(LPCTSTR pszValueName, const void* pValue, ULONG nBytes)
1909 ATLASSERT(m_hKey != NULL);
1910 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_BINARY, reinterpret_cast<const BYTE*>(pValue), nBytes);
1913 LONG SetDWORDValue(LPCTSTR pszValueName, DWORD dwValue)
1915 ATLASSERT(m_hKey != NULL);
1916 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_DWORD, reinterpret_cast<const BYTE*>(&dwValue), sizeof(DWORD));
1919 #ifndef _WIN32_WCE
1920 LONG SetQWORDValue(LPCTSTR pszValueName, ULONGLONG qwValue)
1922 ATLASSERT(m_hKey != NULL);
1923 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_QWORD, reinterpret_cast<const BYTE*>(&qwValue), sizeof(ULONGLONG));
1925 #endif
1927 LONG SetStringValue(LPCTSTR pszValueName, LPCTSTR pszValue, DWORD dwType = REG_SZ)
1929 ATLASSERT(m_hKey != NULL);
1930 if(pszValue == NULL)
1932 ATLASSERT(FALSE);
1933 return ERROR_INVALID_DATA;
1935 ATLASSERT((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ));
1937 return ::RegSetValueEx(m_hKey, pszValueName, NULL, dwType, reinterpret_cast<const BYTE*>(pszValue), (lstrlen(pszValue) + 1) * sizeof(TCHAR));
1940 LONG SetMultiStringValue(LPCTSTR pszValueName, LPCTSTR pszValue)
1942 ATLASSERT(m_hKey != NULL);
1943 if(pszValue == NULL)
1945 ATLASSERT(FALSE);
1946 return ERROR_INVALID_DATA;
1949 ULONG nBytes = 0;
1950 ULONG nLength = 0;
1951 LPCTSTR pszTemp = pszValue;
1954 nLength = lstrlen(pszTemp) + 1;
1955 pszTemp += nLength;
1956 nBytes += nLength * sizeof(TCHAR);
1957 } while (nLength != 1);
1959 return ::RegSetValueEx(m_hKey, pszValueName, NULL, REG_MULTI_SZ, reinterpret_cast<const BYTE*>(pszValue), nBytes);
1962 LONG QueryValue(LPCTSTR pszValueName, DWORD* pdwType, void* pData, ULONG* pnBytes)
1964 ATLASSERT(m_hKey != NULL);
1965 return ::RegQueryValueEx(m_hKey, pszValueName, NULL, pdwType, static_cast<LPBYTE>(pData), pnBytes);
1968 LONG QueryGUIDValue(LPCTSTR pszValueName, GUID& guidValue)
1970 ATLASSERT(m_hKey != NULL);
1972 guidValue = GUID_NULL;
1974 TCHAR szGUID[64] = { 0 };
1975 ULONG nCount = 64;
1976 LONG lRes = QueryStringValue(pszValueName, szGUID, &nCount);
1978 if (lRes != ERROR_SUCCESS)
1979 return lRes;
1981 if(szGUID[0] != _T('{'))
1982 return ERROR_INVALID_DATA;
1984 USES_CONVERSION;
1985 LPOLESTR lpstr = T2OLE(szGUID);
1986 #ifndef _UNICODE
1987 if(lpstr == NULL)
1988 return E_OUTOFMEMORY;
1989 #endif
1991 HRESULT hr = ::CLSIDFromString(lpstr, &guidValue);
1992 if (FAILED(hr))
1993 return ERROR_INVALID_DATA;
1995 return ERROR_SUCCESS;
1998 LONG QueryBinaryValue(LPCTSTR pszValueName, void* pValue, ULONG* pnBytes)
2000 ATLASSERT(pnBytes != NULL);
2001 ATLASSERT(m_hKey != NULL);
2003 DWORD dwType = 0;
2004 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pValue), pnBytes);
2005 if (lRes != ERROR_SUCCESS)
2006 return lRes;
2007 if (dwType != REG_BINARY)
2008 return ERROR_INVALID_DATA;
2010 return ERROR_SUCCESS;
2013 LONG QueryDWORDValue(LPCTSTR pszValueName, DWORD& dwValue)
2015 ATLASSERT(m_hKey != NULL);
2017 ULONG nBytes = sizeof(DWORD);
2018 DWORD dwType = 0;
2019 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&dwValue), &nBytes);
2020 if (lRes != ERROR_SUCCESS)
2021 return lRes;
2022 if (dwType != REG_DWORD)
2023 return ERROR_INVALID_DATA;
2025 return ERROR_SUCCESS;
2028 #ifndef _WIN32_WCE
2029 LONG QueryQWORDValue(LPCTSTR pszValueName, ULONGLONG& qwValue)
2031 ATLASSERT(m_hKey != NULL);
2033 ULONG nBytes = sizeof(ULONGLONG);
2034 DWORD dwType = 0;
2035 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(&qwValue), &nBytes);
2036 if (lRes != ERROR_SUCCESS)
2037 return lRes;
2038 if (dwType != REG_QWORD)
2039 return ERROR_INVALID_DATA;
2041 return ERROR_SUCCESS;
2043 #endif
2045 LONG QueryStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
2047 ATLASSERT(m_hKey != NULL);
2048 ATLASSERT(pnChars != NULL);
2050 ULONG nBytes = (*pnChars) * sizeof(TCHAR);
2051 DWORD dwType = 0;
2052 *pnChars = 0;
2053 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue), &nBytes);
2055 if (lRes != ERROR_SUCCESS)
2057 return lRes;
2060 if(dwType != REG_SZ && dwType != REG_EXPAND_SZ)
2062 return ERROR_INVALID_DATA;
2065 if (pszValue != NULL)
2067 if(nBytes != 0)
2069 if ((nBytes % sizeof(TCHAR) != 0) || (pszValue[nBytes / sizeof(TCHAR) -1] != 0))
2070 return ERROR_INVALID_DATA;
2072 else
2074 pszValue[0] = _T('\0');
2078 *pnChars = nBytes / sizeof(TCHAR);
2080 return ERROR_SUCCESS;
2083 LONG QueryMultiStringValue(LPCTSTR pszValueName, LPTSTR pszValue, ULONG* pnChars)
2085 ATLASSERT(m_hKey != NULL);
2086 ATLASSERT(pnChars != NULL);
2088 if (pszValue != NULL && *pnChars < 2)
2089 return ERROR_INSUFFICIENT_BUFFER;
2091 ULONG nBytes = (*pnChars) * sizeof(TCHAR);
2092 DWORD dwType = 0;
2093 *pnChars = 0;
2094 LONG lRes = ::RegQueryValueEx(m_hKey, pszValueName, NULL, &dwType, reinterpret_cast<LPBYTE>(pszValue), &nBytes);
2095 if (lRes != ERROR_SUCCESS)
2096 return lRes;
2097 if (dwType != REG_MULTI_SZ)
2098 return ERROR_INVALID_DATA;
2099 if (pszValue != NULL && (nBytes % sizeof(TCHAR) != 0 || nBytes / sizeof(TCHAR) < 1 || pszValue[nBytes / sizeof(TCHAR) - 1] != 0 || ((nBytes / sizeof(TCHAR)) > 1 && pszValue[nBytes / sizeof(TCHAR) - 2] != 0)))
2100 return ERROR_INVALID_DATA;
2102 *pnChars = nBytes / sizeof(TCHAR);
2104 return ERROR_SUCCESS;
2108 #else // !(_ATL_VER < 0x0700)
2110 typedef ATL::CRegKey CRegKeyEx;
2112 #endif // !(_ATL_VER < 0x0700)
2115 ///////////////////////////////////////////////////////////////////////////////
2116 // CString forward reference (enables CString use in atluser.h and atlgdi.h)
2118 #if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
2119 #define _WTL_USE_CSTRING
2120 #endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING)
2122 #ifdef _WTL_USE_CSTRING
2123 class CString; // forward declaration (include atlmisc.h for the whole class)
2124 #endif // _WTL_USE_CSTRING
2126 // CString namespace
2127 #ifndef _CSTRING_NS
2128 #ifdef __ATLSTR_H__
2129 #define _CSTRING_NS ATL
2130 #else
2131 #define _CSTRING_NS WTL
2132 #endif
2133 #endif // _CSTRING_NS
2135 // Type classes namespace
2136 #ifndef _WTYPES_NS
2137 #ifdef __ATLTYPES_H__
2138 #define _WTYPES_NS
2139 #else
2140 #define _WTYPES_NS WTL
2141 #endif
2142 #endif // _WTYPES_NS
2144 }; // namespace WTL
2147 ///////////////////////////////////////////////////////////////////////////////
2148 // General DLL version helpers
2149 // (ATL3: excluded from atlbase.h if _ATL_DLL is defined; ATL11: removed)
2151 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !defined(_WIN32_WCE)
2153 namespace ATL
2156 inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
2158 ATLASSERT(pDllVersionInfo != NULL);
2159 if(pDllVersionInfo == NULL)
2160 return E_INVALIDARG;
2162 // We must get this function explicitly because some DLLs don't implement it.
2163 DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
2164 if(pfnDllGetVersion == NULL)
2165 return E_NOTIMPL;
2167 return (*pfnDllGetVersion)(pDllVersionInfo);
2170 inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
2172 HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
2173 if(hInstDLL == NULL)
2174 return E_FAIL;
2175 HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
2176 ::FreeLibrary(hInstDLL);
2177 return hRet;
2180 // Common Control Versions:
2181 // Win95/WinNT 4.0 maj=4 min=00
2182 // IE 3.x maj=4 min=70
2183 // IE 4.0 maj=4 min=71
2184 inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
2186 ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
2187 if(pdwMajor == NULL || pdwMinor == NULL)
2188 return E_INVALIDARG;
2190 DLLVERSIONINFO dvi;
2191 ::ZeroMemory(&dvi, sizeof(dvi));
2192 dvi.cbSize = sizeof(dvi);
2193 HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
2195 if(SUCCEEDED(hRet))
2197 *pdwMajor = dvi.dwMajorVersion;
2198 *pdwMinor = dvi.dwMinorVersion;
2200 else if(hRet == E_NOTIMPL)
2202 // If DllGetVersion is not there, then the DLL is a version
2203 // previous to the one shipped with IE 3.x
2204 *pdwMajor = 4;
2205 *pdwMinor = 0;
2206 hRet = S_OK;
2209 return hRet;
2212 // Shell Versions:
2213 // Win95/WinNT 4.0 maj=4 min=00
2214 // IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00
2215 // IE 4.0 with Web Integrated Desktop maj=4 min=71
2216 // IE 4.01 with Web Integrated Desktop maj=4 min=72
2217 inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
2219 ATLASSERT(pdwMajor != NULL && pdwMinor != NULL);
2220 if(pdwMajor == NULL || pdwMinor == NULL)
2221 return E_INVALIDARG;
2223 DLLVERSIONINFO dvi;
2224 ::ZeroMemory(&dvi, sizeof(dvi));
2225 dvi.cbSize = sizeof(dvi);
2226 HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
2228 if(SUCCEEDED(hRet))
2230 *pdwMajor = dvi.dwMajorVersion;
2231 *pdwMinor = dvi.dwMinorVersion;
2233 else if(hRet == E_NOTIMPL)
2235 // If DllGetVersion is not there, then the DLL is a version
2236 // previous to the one shipped with IE 4.x
2237 *pdwMajor = 4;
2238 *pdwMinor = 0;
2239 hRet = S_OK;
2242 return hRet;
2245 }; // namespace ATL
2247 #endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE)
2250 // These are always included
2251 #include "atlwinx.h"
2252 #include "atluser.h"
2253 #include "atlgdi.h"
2255 #ifndef _WTL_NO_AUTOMATIC_NAMESPACE
2256 using namespace WTL;
2257 #endif // !_WTL_NO_AUTOMATIC_NAMESPACE
2259 #endif // __ATLAPP_H__