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
76 ///////////////////////////////////////////////////////////////////////////////
77 // WTL version number
78
79 #define _WTL_VER 0x0910
80
81
82 ///////////////////////////////////////////////////////////////////////////////
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
101 ///////////////////////////////////////////////////////////////////////////////
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
IsMenu(HMENU hMenu)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
MulDiv(IN int nNumber,IN int nNumerator,IN int nDenominator)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 {
RegisterClassObjects(DWORD,DWORD)164 inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD /*dwFlags*/) throw()
165 { return E_NOTIMPL; }
RevokeClassObjects()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
lstrlenA(LPCSTR lpszString)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
tmp_SetWindowLongPtrW(HWND hWnd,int nIndex,LONG_PTR dwNewLong)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
tmp_GetWindowLongPtrW(HWND hWnd,int nIndex)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
lstrcpyn(LPTSTR lpstrDest,LPCTSTR lpstrSrc,int nLength)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
lstrcpynW(LPWSTR lpstrDest,LPCWSTR lpstrSrc,int nLength)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
lstrcpynA(LPSTR lpstrDest,LPCSTR lpstrSrc,int nLength)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
301 ///////////////////////////////////////////////////////////////////////////////
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
427 ///////////////////////////////////////////////////////////////////////////////
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
441 ///////////////////////////////////////////////////////////////////////////////
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
481 ///////////////////////////////////////////////////////////////////////////////
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
504 ///////////////////////////////////////////////////////////////////////////////
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)
__if_not_exists(_IMAGELIST::_IMAGELIST)527 __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; }
__if_not_exists(_TREEITEM::_TREEITEM)528 __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; }
__if_not_exists(_PSP::_PSP)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
AtlIsOldWindows()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
AtlGetDefaultGuiFont()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)
AtlCreateControlFont()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
AtlInitCommonControls(DWORD dwFlags)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
636 ///////////////////////////////////////////////////////////////////////////////
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
IsCommCtrl6()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
IsVista()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
IsThemeAvailable()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
IsWin7()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
IsRibbonUIAvailable()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
SizeOf_REBARBANDINFO()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)
SizeOf_LVGROUP()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
SizeOf_LVTILEINFO()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
SizeOf_MCHITTESTINFO()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
SizeOf_NONCLIENTMETRICS()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
SizeOf_TOOLINFO()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
832 ///////////////////////////////////////////////////////////////////////////////
833 // ModuleHelper - helper functions for ATL3 and ATL7 module classes
834
835 namespace ModuleHelper
836 {
GetModuleInstance()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
GetResourceInstance()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
AddCreateWndData(ATL::_AtlCreateWndData * pData,void * pObject)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
ExtractCreateWndData()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
875 ///////////////////////////////////////////////////////////////////////////////
876 // SecureHelper - helper functions for VS2005 secure CRT
877
878 namespace SecureHelper
879 {
strcpyA_x(char * lpstrDest,size_t cchDest,const char * lpstrSrc)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
strcpyW_x(wchar_t * lpstrDest,size_t cchDest,const wchar_t * lpstrSrc)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
strcpy_x(LPTSTR lpstrDest,size_t cchDest,LPCTSTR lpstrSrc)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
strncpyA_x(char * lpstrDest,size_t cchDest,const char * lpstrSrc,size_t cchCount)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
strncpyW_x(wchar_t * lpstrDest,size_t cchDest,const wchar_t * lpstrSrc,size_t cchCount)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
strncpy_x(LPTSTR lpstrDest,size_t cchDest,LPCTSTR lpstrSrc,size_t cchCount)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
strcatA_x(char * lpstrDest,size_t cchDest,const char * lpstrSrc)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
strcatW_x(wchar_t * lpstrDest,size_t cchDest,const wchar_t * lpstrSrc)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
strcat_x(LPTSTR lpstrDest,size_t cchDest,LPCTSTR lpstrSrc)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
memcpy_x(void * pDest,size_t cbDest,const void * pSrc,size_t cbSrc)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
memmove_x(void * pDest,size_t cbDest,const void * pSrc,size_t cbSrc)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
vsprintf_x(LPTSTR lpstrBuff,size_t cchBuff,LPCTSTR lpstrFormat,va_list args)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
wvsprintf_x(LPTSTR lpstrBuff,size_t cchBuff,LPCTSTR lpstrFormat,va_list args)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
sprintf_x(LPTSTR lpstrBuff,size_t cchBuff,LPCTSTR lpstrFormat,...)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
wsprintf_x(LPTSTR lpstrBuff,size_t cchBuff,LPCTSTR lpstrFormat,...)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
1076 ///////////////////////////////////////////////////////////////////////////////
1077 // MinCrtHelper - helper functions for using _ATL_MIN_CRT
1078
1079 namespace MinCrtHelper
1080 {
_isspace(TCHAR ch)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
_isdigit(TCHAR ch)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
_atoi(LPCTSTR str)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
_strrchr(LPCTSTR str,TCHAR ch)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
_strrchr(LPTSTR str,TCHAR ch)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
1161 ///////////////////////////////////////////////////////////////////////////////
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 {
GetName()1169 inline LPCTSTR GetName()
1170 {
1171 return _T("WTL_GenericWindow");
1172 }
1173
Register()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
Unregister()1195 inline BOOL Unregister() // only needed for DLLs or tmp use
1196 {
1197 return ::UnregisterClass(GetName(), ModuleHelper::GetModuleInstance());
1198 }
1199 }; // namespace GenericWndClass
1200
1201
1202 ///////////////////////////////////////////////////////////////////////////////
1203 // CMessageFilter - Interface for message filter support
1204
1205 class CMessageFilter
1206 {
1207 public:
1208 virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
1209 };
1210
1211
1212 ///////////////////////////////////////////////////////////////////////////////
1213 // CIdleHandler - Interface for idle processing
1214
1215 class CIdleHandler
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
1228 ///////////////////////////////////////////////////////////////////////////////
1229 // CMessageLoop - message loop implementation
1230
1231 class CMessageLoop
1232 {
1233 public:
1234 ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter;
1235 ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler;
1236 MSG m_msg;
1237
1238 // Message filter operations
AddMessageFilter(CMessageFilter * pMessageFilter)1239 BOOL AddMessageFilter(CMessageFilter* pMessageFilter)
1240 {
1241 return m_aMsgFilter.Add(pMessageFilter);
1242 }
1243
RemoveMessageFilter(CMessageFilter * pMessageFilter)1244 BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter)
1245 {
1246 return m_aMsgFilter.Remove(pMessageFilter);
1247 }
1248
1249 // Idle handler operations
AddIdleHandler(CIdleHandler * pIdleHandler)1250 BOOL AddIdleHandler(CIdleHandler* pIdleHandler)
1251 {
1252 return m_aIdleHandler.Add(pIdleHandler);
1253 }
1254
RemoveIdleHandler(CIdleHandler * pIdleHandler)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
AddUpdateUI(CIdleHandler * pIdleHandler)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
RemoveUpdateUI(CIdleHandler * pIdleHandler)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
Run()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
IsIdleMessage(MSG * pMsg)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
PreTranslateMessage(MSG * pMsg)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
OnIdle(int)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
1364 ///////////////////////////////////////////////////////////////////////////////
1365 // CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock
1366 // internal classes to manage critical sections for both ATL3 and ATL7
1367
1368 class CStaticDataInitCriticalSectionLock
1369 {
1370 public:
1371 #if (_ATL_VER >= 0x0700)
1372 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1373
CStaticDataInitCriticalSectionLock()1374 CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false)
1375 { }
1376 #endif // (_ATL_VER >= 0x0700)
1377
Lock()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
Unlock()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
1399 class CWindowCreateCriticalSectionLock
1400 {
1401 public:
1402 #if (_ATL_VER >= 0x0700)
1403 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
1404
CWindowCreateCriticalSectionLock()1405 CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false)
1406 { }
1407 #endif // (_ATL_VER >= 0x0700)
1408
Lock()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
Unlock()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
1430 ///////////////////////////////////////////////////////////////////////////////
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>
1455 class CTempBuffer
1456 {
1457 public:
CTempBuffer()1458 CTempBuffer() : m_p(NULL)
1459 {
1460 }
1461
CTempBuffer(size_t nElements)1462 CTempBuffer(size_t nElements) : m_p(NULL)
1463 {
1464 Allocate(nElements);
1465 }
1466
~CTempBuffer()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
Allocate(size_t nElements)1484 T* Allocate(size_t nElements)
1485 {
1486 ATLASSERT(nElements <= (SIZE_MAX / sizeof(T)));
1487 return AllocateBytes(nElements * sizeof(T));
1488 }
1489
AllocateBytes(size_t nBytes)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
1511 ///////////////////////////////////////////////////////////////////////////////
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
Term()1539 void Term()
1540 {
1541 TermSettingChangeNotify();
1542 delete m_pMsgLoopMap;
1543 CComModule::Term();
1544 }
1545
1546 // Message loop map methods
AddMessageLoop(CMessageLoop * pMsgLoop)1547 BOOL AddMessageLoop(CMessageLoop* pMsgLoop)
1548 {
1549 CStaticDataInitCriticalSectionLock lock;
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
RemoveMessageLoop()1567 BOOL RemoveMessageLoop()
1568 {
1569 CStaticDataInitCriticalSectionLock lock;
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 {
1586 CStaticDataInitCriticalSectionLock lock;
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 {
1605 CStaticDataInitCriticalSectionLock lock;
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
TermSettingChangeNotify()1648 void TermSettingChangeNotify()
1649 {
1650 CStaticDataInitCriticalSectionLock lock;
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
AddSettingChangeNotify(HWND hWnd)1666 BOOL AddSettingChangeNotify(HWND hWnd)
1667 {
1668 CStaticDataInitCriticalSectionLock lock;
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
RemoveSettingChangeNotify(HWND hWnd)1686 BOOL RemoveSettingChangeNotify(HWND hWnd)
1687 {
1688 CStaticDataInitCriticalSectionLock lock;
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 {
_ATL_EMPTY_DLGTEMPLATE_ATL_EMPTY_DLGTEMPLATE1708 _ATL_EMPTY_DLGTEMPLATE()
1709 {
1710 memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE));
1711 style = WS_POPUP;
1712 }
1713 WORD wMenu, wClass, wTitle;
1714 };
1715
1716 #ifdef _WIN64
_SettingChangeDlgProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)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
1751 ///////////////////////////////////////////////////////////////////////////////
1752 // CServerAppModule - module class for a COM server application
1753
1754 class CServerAppModule : public CAppModule
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
Term()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)
Unlock()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
MonitorShutdown()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
StartMonitor()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
MonitorProc(void * pv)1839 static DWORD WINAPI MonitorProc(void* pv)
1840 {
1841 CServerAppModule* p = (CServerAppModule*)pv;
1842 p->MonitorShutdown();
1843 return 0;
1844 }
1845
1846 #if (_ATL_VER < 0x0700)
1847 // search for an occurence of string p2 in string p1
FindOneOf(LPCTSTR p1,LPCTSTR p2)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
1867 ///////////////////////////////////////////////////////////////////////////////
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
CRegKeyEx(CRegKeyEx & key)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
SetValue(LPCTSTR pszValueName,DWORD dwType,const void * pValue,ULONG nBytes)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
SetGUIDValue(LPCTSTR pszValueName,REFGUID guidValue)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
SetBinaryValue(LPCTSTR pszValueName,const void * pValue,ULONG nBytes)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
SetDWORDValue(LPCTSTR pszValueName,DWORD dwValue)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
SetQWORDValue(LPCTSTR pszValueName,ULONGLONG qwValue)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
SetMultiStringValue(LPCTSTR pszValueName,LPCTSTR pszValue)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
QueryValue(LPCTSTR pszValueName,DWORD * pdwType,void * pData,ULONG * pnBytes)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
QueryGUIDValue(LPCTSTR pszValueName,GUID & guidValue)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
QueryBinaryValue(LPCTSTR pszValueName,void * pValue,ULONG * pnBytes)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
QueryDWORDValue(LPCTSTR pszValueName,DWORD & dwValue)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
QueryQWORDValue(LPCTSTR pszValueName,ULONGLONG & qwValue)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
QueryStringValue(LPCTSTR pszValueName,LPTSTR pszValue,ULONG * pnChars)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
QueryMultiStringValue(LPCTSTR pszValueName,LPTSTR pszValue,ULONG * pnChars)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
2124 ///////////////////////////////////////////////////////////////////////////////
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
2156 ///////////////////////////////////////////////////////////////////////////////
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
AtlGetDllVersion(HINSTANCE hInstDLL,DLLVERSIONINFO * pDllVersionInfo)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
AtlGetDllVersion(LPCTSTR lpstrDllName,DLLVERSIONINFO * pDllVersionInfo)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
AtlGetCommCtrlVersion(LPDWORD pdwMajor,LPDWORD pdwMinor)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
AtlGetShellVersion(LPDWORD pdwMajor,LPDWORD pdwMinor)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__
2269