OLD | NEW |
| (Empty) |
1 // Windows Template Library - WTL version 8.0 | |
2 // Copyright (C) Microsoft Corporation. All rights reserved. | |
3 // | |
4 // This file is a part of the Windows Template Library. | |
5 // The use and distribution terms for this software are covered by the | |
6 // Microsoft Permissive License (Ms-PL) which can be found in the file | |
7 // Ms-PL.txt at the root of this distribution. | |
8 | |
9 #ifndef __ATLAPP_H__ | |
10 #define __ATLAPP_H__ | |
11 | |
12 #pragma once | |
13 | |
14 #ifndef __cplusplus | |
15 #error ATL 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 // _ATL_NO_COMMODULE | |
35 | |
36 #if defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) | |
37 #pragma message("Warning: WTL for Windows CE doesn't use _ATL_MIN_CRT") | |
38 #endif // defined(_WIN32_WCE) && defined(_ATL_MIN_CRT) | |
39 | |
40 #include <limits.h> | |
41 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) | |
42 #include <process.h> // for _beginthreadex | |
43 #endif | |
44 | |
45 #if (_ATL_VER < 0x0800) && !defined(_DEBUG) | |
46 #include <stdio.h> | |
47 #endif | |
48 | |
49 #include <commctrl.h> | |
50 #ifndef _WIN32_WCE | |
51 #pragma comment(lib, "comctl32.lib") | |
52 #endif // !_WIN32_WCE | |
53 | |
54 #ifndef _WIN32_WCE | |
55 #include "atlres.h" | |
56 #else // CE specific | |
57 #include "atlresce.h" | |
58 #endif // _WIN32_WCE | |
59 | |
60 // We need to disable this warning because of template class arguments | |
61 #pragma warning(disable: 4127) | |
62 | |
63 | |
64 /////////////////////////////////////////////////////////////////////////////// | |
65 // WTL version number | |
66 | |
67 #define _WTL_VER 0x0800 | |
68 | |
69 | |
70 /////////////////////////////////////////////////////////////////////////////// | |
71 // Classes in this file: | |
72 // | |
73 // CMessageFilter | |
74 // CIdleHandler | |
75 // CMessageLoop | |
76 // | |
77 // CAppModule | |
78 // CServerAppModule | |
79 // | |
80 // Global functions: | |
81 // AtlGetDefaultGuiFont() | |
82 // AtlCreateBoldFont() | |
83 // AtlInitCommonControls() | |
84 | |
85 | |
86 /////////////////////////////////////////////////////////////////////////////// | |
87 // Global support for Windows CE | |
88 | |
89 #ifdef _WIN32_WCE | |
90 | |
91 #ifndef SW_SHOWDEFAULT | |
92 #define SW_SHOWDEFAULT SW_SHOWNORMAL | |
93 #endif // !SW_SHOWDEFAULT | |
94 | |
95 // These get's OR-ed in a constant and will have no effect. | |
96 // Defining them reduces the number of #ifdefs required for CE. | |
97 #define LR_DEFAULTSIZE 0 | |
98 #define LR_LOADFROMFILE 0 | |
99 | |
100 #ifndef SM_CXCURSOR | |
101 #define SM_CXCURSOR 13 | |
102 #endif | |
103 #ifndef SM_CYCURSOR | |
104 #define SM_CYCURSOR 14 | |
105 #endif | |
106 | |
107 inline BOOL IsMenu(HMENU hMenu) | |
108 { | |
109 MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; | |
110 ::SetLastError(0); | |
111 BOOL bRet = ::GetMenuItemInfo(hMenu, 0, TRUE, &mii); | |
112 if(!bRet) | |
113 bRet = (::GetLastError() != ERROR_INVALID_MENU_HANDLE) ? TRUE :
FALSE; | |
114 return bRet; | |
115 } | |
116 | |
117 #if (_WIN32_WCE >= 410) | |
118 extern "C" void WINAPI ListView_SetItemSpacing(HWND hwndLV, int iHeight); | |
119 #endif // (_WIN32_WCE >= 410) | |
120 | |
121 inline int MulDiv(IN int nNumber, IN int nNumerator, IN int nDenominator) | |
122 { | |
123 __int64 multiple = nNumber * nNumerator; | |
124 return static_cast<int>(multiple / nDenominator); | |
125 } | |
126 | |
127 #if (_ATL_VER >= 0x0800) | |
128 | |
129 #ifndef _WTL_KEEP_WS_OVERLAPPEDWINDOW | |
130 #ifdef WS_OVERLAPPEDWINDOW | |
131 #undef WS_OVERLAPPEDWINDOW | |
132 #define WS_OVERLAPPEDWINDOW 0 | |
133 #endif // WS_OVERLAPPEDWINDOW | |
134 #endif // !_WTL_KEEP_WS_OVERLAPPEDWINDOW | |
135 | |
136 #ifndef RDW_FRAME | |
137 #define RDW_FRAME 0 | |
138 #endif // !RDW_FRAME | |
139 | |
140 #ifndef WM_WINDOWPOSCHANGING | |
141 #define WM_WINDOWPOSCHANGING 0 | |
142 #endif // !WM_WINDOWPOSCHANGING | |
143 | |
144 #define FreeResource(x) | |
145 #define UnlockResource(x) | |
146 | |
147 namespace ATL | |
148 { | |
149 inline HRESULT CComModule::RegisterClassObjects(DWORD /*dwClsContext*/, DWORD
/*dwFlags*/) throw() | |
150 { return E_NOTIMPL; } | |
151 inline HRESULT CComModule::RevokeClassObjects() throw() | |
152 { return E_NOTIMPL; } | |
153 }; // namespace ATL | |
154 | |
155 #ifndef lstrlenW | |
156 #define lstrlenW (int)ATL::lstrlenW | |
157 #endif // lstrlenW | |
158 | |
159 inline int WINAPI lstrlenA(LPCSTR lpszString) | |
160 { return ATL::lstrlenA(lpszString); } | |
161 | |
162 #ifdef lstrcpyn | |
163 #undef lstrcpyn | |
164 #define lstrcpyn ATL::lstrcpynW | |
165 #endif // lstrcpyn | |
166 | |
167 #ifndef SetWindowLongPtrW | |
168 inline LONG_PTR tmp_SetWindowLongPtrW( HWND hWnd, int nIndex, LONG_PTR dwNewLo
ng ) | |
169 { | |
170 return( ::SetWindowLongW( hWnd, nIndex, LONG( dwNewLong ) ) ); | |
171 } | |
172 #define SetWindowLongPtrW tmp_SetWindowLongPtrW | |
173 #endif | |
174 | |
175 #ifndef GetWindowLongPtrW | |
176 inline LONG_PTR tmp_GetWindowLongPtrW( HWND hWnd, int nIndex ) | |
177 { | |
178 return( ::GetWindowLongW( hWnd, nIndex ) ); | |
179 } | |
180 #define GetWindowLongPtrW tmp_GetWindowLongPtrW | |
181 #endif | |
182 | |
183 #ifndef LongToPtr | |
184 #define LongToPtr(x) ((void*)x) | |
185 #endif | |
186 | |
187 #ifndef PtrToInt | |
188 #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) | |
189 #endif | |
190 | |
191 #else // !(_ATL_VER >= 0x0800) | |
192 | |
193 #ifdef lstrlenW | |
194 #undef lstrlenW | |
195 #define lstrlenW (int)::wcslen | |
196 #endif // lstrlenW | |
197 | |
198 #define lstrlenA (int)strlen | |
199 | |
200 #ifndef lstrcpyn | |
201 inline LPTSTR lstrcpyn(LPTSTR lpstrDest, LPCTSTR lpstrSrc, int nLength) | |
202 { | |
203 if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) | |
204 return NULL; | |
205 int nLen = __min(lstrlen(lpstrSrc), nLength - 1); | |
206 LPTSTR lpstrRet = (LPTSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(TCHA
R)); | |
207 lpstrDest[nLen] = 0; | |
208 return lpstrRet; | |
209 } | |
210 #endif // !lstrcpyn | |
211 | |
212 #ifndef lstrcpynW | |
213 inline LPWSTR lstrcpynW(LPWSTR lpstrDest, LPCWSTR lpstrSrc, int nLength) | |
214 { | |
215 return lstrcpyn(lpstrDest, lpstrSrc, nLength); // WinCE is Unicode onl
y | |
216 } | |
217 #endif // !lstrcpynW | |
218 | |
219 #ifndef lstrcpynA | |
220 inline LPSTR lstrcpynA(LPSTR lpstrDest, LPCSTR lpstrSrc, int nLength) | |
221 { | |
222 if(lpstrDest == NULL || lpstrSrc == NULL || nLength <= 0) | |
223 return NULL; | |
224 int nLen = __min(lstrlenA(lpstrSrc), nLength - 1); | |
225 LPSTR lpstrRet = (LPSTR)memcpy(lpstrDest, lpstrSrc, nLen * sizeof(char))
; | |
226 lpstrDest[nLen] = 0; | |
227 return lpstrRet; | |
228 } | |
229 #endif // !lstrcpyn | |
230 | |
231 #ifdef TrackPopupMenu | |
232 #undef TrackPopupMenu | |
233 #endif // TrackPopupMenu | |
234 | |
235 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \ | |
236 static CWndClassInfo& GetWndClassInfo() \ | |
237 { \ | |
238 static CWndClassInfo wc = \ | |
239 { \ | |
240 { style, StartWindowProc, \ | |
241 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassNam
e }, \ | |
242 NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \ | |
243 }; \ | |
244 return wc; \ | |
245 } | |
246 | |
247 #ifndef _MAX_FNAME | |
248 #define _MAX_FNAME _MAX_PATH | |
249 #endif // _MAX_FNAME | |
250 | |
251 #if (_WIN32_WCE < 400) | |
252 #define MAKEINTATOM(i) (LPTSTR)((ULONG_PTR)((WORD)(i))) | |
253 #endif // (_WIN32_WCE < 400) | |
254 | |
255 #if (_WIN32_WCE < 410) | |
256 #define WHEEL_PAGESCROLL (UINT_MAX) | |
257 #define WHEEL_DELTA 120 | |
258 #endif // (_WIN32_WCE < 410) | |
259 | |
260 #ifdef DrawIcon | |
261 #undef DrawIcon | |
262 #endif | |
263 | |
264 #ifndef VARCMP_LT | |
265 #define VARCMP_LT 0 | |
266 #endif | |
267 #ifndef VARCMP_EQ | |
268 #define VARCMP_EQ 1 | |
269 #endif | |
270 #ifndef VARCMP_GT | |
271 #define VARCMP_GT 2 | |
272 #endif | |
273 #ifndef VARCMP_NULL | |
274 #define VARCMP_NULL 3 | |
275 #endif | |
276 | |
277 #ifndef RDW_ALLCHILDREN | |
278 #define RDW_ALLCHILDREN 0 | |
279 #endif | |
280 | |
281 #endif // !(_ATL_VER >= 0x0800) | |
282 | |
283 #endif // _WIN32_WCE | |
284 | |
285 | |
286 /////////////////////////////////////////////////////////////////////////////// | |
287 // Global support for using original VC++ 6.0 headers with WTL | |
288 | |
289 #ifndef _ATL_NO_OLD_HEADERS_WIN64 | |
290 #if !defined(_WIN64) && (_ATL_VER < 0x0700) | |
291 | |
292 #ifndef PSM_INSERTPAGE | |
293 #define PSM_INSERTPAGE (WM_USER + 119) | |
294 #endif // !PSM_INSERTPAGE | |
295 | |
296 #ifndef GetClassLongPtr | |
297 #define GetClassLongPtrA GetClassLongA | |
298 #define GetClassLongPtrW GetClassLongW | |
299 #ifdef UNICODE | |
300 #define GetClassLongPtr GetClassLongPtrW | |
301 #else | |
302 #define GetClassLongPtr GetClassLongPtrA | |
303 #endif // !UNICODE | |
304 #endif // !GetClassLongPtr | |
305 | |
306 #ifndef GCLP_HICONSM | |
307 #define GCLP_HICONSM (-34) | |
308 #endif // !GCLP_HICONSM | |
309 | |
310 #ifndef GetWindowLongPtr | |
311 #define GetWindowLongPtrA GetWindowLongA | |
312 #define GetWindowLongPtrW GetWindowLongW | |
313 #ifdef UNICODE | |
314 #define GetWindowLongPtr GetWindowLongPtrW | |
315 #else | |
316 #define GetWindowLongPtr GetWindowLongPtrA | |
317 #endif // !UNICODE | |
318 #endif // !GetWindowLongPtr | |
319 | |
320 #ifndef SetWindowLongPtr | |
321 #define SetWindowLongPtrA SetWindowLongA | |
322 #define SetWindowLongPtrW SetWindowLongW | |
323 #ifdef UNICODE | |
324 #define SetWindowLongPtr SetWindowLongPtrW | |
325 #else | |
326 #define SetWindowLongPtr SetWindowLongPtrA | |
327 #endif // !UNICODE | |
328 #endif // !SetWindowLongPtr | |
329 | |
330 #ifndef GWLP_WNDPROC | |
331 #define GWLP_WNDPROC (-4) | |
332 #endif | |
333 #ifndef GWLP_HINSTANCE | |
334 #define GWLP_HINSTANCE (-6) | |
335 #endif | |
336 #ifndef GWLP_HWNDPARENT | |
337 #define GWLP_HWNDPARENT (-8) | |
338 #endif | |
339 #ifndef GWLP_USERDATA | |
340 #define GWLP_USERDATA (-21) | |
341 #endif | |
342 #ifndef GWLP_ID | |
343 #define GWLP_ID (-12) | |
344 #endif | |
345 | |
346 #ifndef DWLP_MSGRESULT | |
347 #define DWLP_MSGRESULT 0 | |
348 #endif | |
349 | |
350 typedef long LONG_PTR; | |
351 typedef unsigned long ULONG_PTR; | |
352 typedef ULONG_PTR DWORD_PTR; | |
353 | |
354 #ifndef HandleToUlong | |
355 #define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) ) | |
356 #endif | |
357 #ifndef HandleToLong | |
358 #define HandleToLong( h ) ((LONG)(LONG_PTR) (h) ) | |
359 #endif | |
360 #ifndef LongToHandle | |
361 #define LongToHandle( h) ((HANDLE)(LONG_PTR) (h)) | |
362 #endif | |
363 #ifndef PtrToUlong | |
364 #define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) ) | |
365 #endif | |
366 #ifndef PtrToLong | |
367 #define PtrToLong( p ) ((LONG)(LONG_PTR) (p) ) | |
368 #endif | |
369 #ifndef PtrToUint | |
370 #define PtrToUint( p ) ((UINT)(UINT_PTR) (p) ) | |
371 #endif | |
372 #ifndef PtrToInt | |
373 #define PtrToInt( p ) ((INT)(INT_PTR) (p) ) | |
374 #endif | |
375 #ifndef PtrToUshort | |
376 #define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) ) | |
377 #endif | |
378 #ifndef PtrToShort | |
379 #define PtrToShort( p ) ((short)(LONG_PTR)(p) ) | |
380 #endif | |
381 #ifndef IntToPtr | |
382 #define IntToPtr( i ) ((VOID *)(INT_PTR)((int)i)) | |
383 #endif | |
384 #ifndef UIntToPtr | |
385 #define UIntToPtr( ui ) ((VOID *)(UINT_PTR)((unsigned int)ui)) | |
386 #endif | |
387 #ifndef LongToPtr | |
388 #define LongToPtr( l ) ((VOID *)(LONG_PTR)((long)l)) | |
389 #endif | |
390 #ifndef ULongToPtr | |
391 #define ULongToPtr( ul ) ((VOID *)(ULONG_PTR)((unsigned long)ul)) | |
392 #endif | |
393 | |
394 #endif // !defined(_WIN64) && (_ATL_VER < 0x0700) | |
395 #endif // !_ATL_NO_OLD_HEADERS_WIN64 | |
396 | |
397 | |
398 /////////////////////////////////////////////////////////////////////////////// | |
399 // Global support for SecureHelper functions | |
400 | |
401 #ifndef _TRUNCATE | |
402 #define _TRUNCATE ((size_t)-1) | |
403 #endif | |
404 | |
405 #ifndef _ERRCODE_DEFINED | |
406 #define _ERRCODE_DEFINED | |
407 typedef int errno_t; | |
408 #endif | |
409 | |
410 #ifndef _SECURECRT_ERRCODE_VALUES_DEFINED | |
411 #define _SECURECRT_ERRCODE_VALUES_DEFINED | |
412 #define EINVAL 22 | |
413 #define STRUNCATE 80 | |
414 #endif | |
415 | |
416 #ifndef _countof | |
417 #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) | |
418 #endif | |
419 | |
420 | |
421 /////////////////////////////////////////////////////////////////////////////// | |
422 // Miscellaneous global support | |
423 | |
424 // define useful macros from winuser.h | |
425 #ifndef IS_INTRESOURCE | |
426 #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0) | |
427 #endif // IS_INTRESOURCE | |
428 | |
429 // protect template members from windowsx.h macros | |
430 #ifdef _INC_WINDOWSX | |
431 #undef SubclassWindow | |
432 #endif // _INC_WINDOWSX | |
433 | |
434 // define useful macros from windowsx.h | |
435 #ifndef GET_X_LPARAM | |
436 #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam)) | |
437 #endif | |
438 #ifndef GET_Y_LPARAM | |
439 #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam)) | |
440 #endif | |
441 | |
442 // Dummy structs for compiling with /CLR | |
443 #if (_MSC_VER >= 1300) && defined(_MANAGED) | |
444 __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; } | |
445 __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; } | |
446 __if_not_exists(_PSP::_PSP) { struct _PSP { }; } | |
447 #endif | |
448 | |
449 // Define ATLVERIFY macro for ATL3 | |
450 #if (_ATL_VER < 0x0700) | |
451 #ifndef ATLVERIFY | |
452 #ifdef _DEBUG | |
453 #define ATLVERIFY(expr) ATLASSERT(expr) | |
454 #else | |
455 #define ATLVERIFY(expr) (expr) | |
456 #endif // DEBUG | |
457 #endif // ATLVERIFY | |
458 #endif // (_ATL_VER < 0x0700) | |
459 | |
460 // Forward declaration for ATL3 and ATL11 fix | |
461 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !def
ined(_WIN32_WCE) | |
462 namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMin
or); }; | |
463 #endif | |
464 | |
465 | |
466 namespace WTL | |
467 { | |
468 | |
469 #if (_ATL_VER >= 0x0700) | |
470 DECLARE_TRACE_CATEGORY(atlTraceUI); | |
471 #ifdef _DEBUG | |
472 __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI")); | |
473 #endif // _DEBUG | |
474 #else // !(_ATL_VER >= 0x0700) | |
475 enum wtlTraceFlags | |
476 { | |
477 atlTraceUI = 0x10000000 | |
478 }; | |
479 #endif // !(_ATL_VER >= 0x0700) | |
480 | |
481 // Windows version helper | |
482 inline bool AtlIsOldWindows() | |
483 { | |
484 OSVERSIONINFO ovi = { 0 }; | |
485 ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | |
486 BOOL bRet = ::GetVersionEx(&ovi); | |
487 return (!bRet || !((ovi.dwMajorVersion >= 5) || (ovi.dwMajorVersion == 4
&& ovi.dwMinorVersion >= 90))); | |
488 } | |
489 | |
490 // default GUI font helper | |
491 inline HFONT AtlGetDefaultGuiFont() | |
492 { | |
493 #ifndef _WIN32_WCE | |
494 return (HFONT)::GetStockObject(DEFAULT_GUI_FONT); | |
495 #else // CE specific | |
496 return (HFONT)::GetStockObject(SYSTEM_FONT); | |
497 #endif // _WIN32_WCE | |
498 } | |
499 | |
500 // bold font helper (NOTE: Caller owns the font, and should destroy it when done
using it) | |
501 inline HFONT AtlCreateBoldFont(HFONT hFont = NULL) | |
502 { | |
503 if(hFont == NULL) | |
504 hFont = AtlGetDefaultGuiFont(); | |
505 ATLASSERT(hFont != NULL); | |
506 HFONT hFontBold = NULL; | |
507 LOGFONT lf = { 0 }; | |
508 if(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)) | |
509 { | |
510 lf.lfWeight = FW_BOLD; | |
511 hFontBold = ::CreateFontIndirect(&lf); | |
512 ATLASSERT(hFontBold != NULL); | |
513 } | |
514 else | |
515 { | |
516 ATLASSERT(FALSE); | |
517 } | |
518 return hFontBold; | |
519 } | |
520 | |
521 // Common Controls initialization helper | |
522 inline BOOL AtlInitCommonControls(DWORD dwFlags) | |
523 { | |
524 INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags }; | |
525 BOOL bRet = ::InitCommonControlsEx(&iccx); | |
526 ATLASSERT(bRet); | |
527 return bRet; | |
528 } | |
529 | |
530 | |
531 /////////////////////////////////////////////////////////////////////////////// | |
532 // RunTimeHelper - helper functions for Windows version and structure sizes | |
533 | |
534 // Not for Windows CE | |
535 #if defined(_WIN32_WCE) && !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) | |
536 #define _WTL_NO_RUNTIME_STRUCT_SIZE | |
537 #endif | |
538 | |
539 #ifndef _WTL_NO_RUNTIME_STRUCT_SIZE | |
540 | |
541 #ifndef _SIZEOF_STRUCT | |
542 #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)
->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) | |
543 #endif | |
544 | |
545 #if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) | |
546 #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader) | |
547 #endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) | |
548 | |
549 #if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) | |
550 #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign) | |
551 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) | |
552 | |
553 #if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) | |
554 #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns) | |
555 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) | |
556 | |
557 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHI
TTESTINFO_V1_SIZE) | |
558 #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st) | |
559 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !define
d(MCHITTESTINFO_V1_SIZE) | |
560 | |
561 #if !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_S
IZE) | |
562 #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageF
ont) | |
563 #endif // !defined(_WIN32_WCE) && (WINVER >= 0x0600) && !defined(NONCLIENTMETRIC
S_V1_SIZE) | |
564 | |
565 #endif // !_WTL_NO_RUNTIME_STRUCT_SIZE | |
566 | |
567 namespace RunTimeHelper | |
568 { | |
569 #ifndef _WIN32_WCE | |
570 inline bool IsCommCtrl6() | |
571 { | |
572 DWORD dwMajor = 0, dwMinor = 0; | |
573 HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); | |
574 return (SUCCEEDED(hRet) && (dwMajor >= 6)); | |
575 } | |
576 | |
577 inline bool IsVista() | |
578 { | |
579 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; | |
580 BOOL bRet = ::GetVersionEx(&ovi); | |
581 return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6)); | |
582 } | |
583 #endif // !_WIN32_WCE | |
584 | |
585 inline int SizeOf_REBARBANDINFO() | |
586 { | |
587 int nSize = sizeof(REBARBANDINFO); | |
588 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
589 if(!(IsVista() && IsCommCtrl6())) | |
590 nSize = REBARBANDINFO_V6_SIZE; | |
591 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
592 return nSize; | |
593 } | |
594 | |
595 #if (_WIN32_WINNT >= 0x501) | |
596 inline int SizeOf_LVGROUP() | |
597 { | |
598 int nSize = sizeof(LVGROUP); | |
599 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
600 if(!IsVista()) | |
601 nSize = LVGROUP_V5_SIZE; | |
602 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
603 return nSize; | |
604 } | |
605 | |
606 inline int SizeOf_LVTILEINFO() | |
607 { | |
608 int nSize = sizeof(LVTILEINFO); | |
609 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
610 if(!IsVista()) | |
611 nSize = LVTILEINFO_V5_SIZE; | |
612 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
613 return nSize; | |
614 } | |
615 #endif // (_WIN32_WINNT >= 0x501) | |
616 | |
617 inline int SizeOf_MCHITTESTINFO() | |
618 { | |
619 int nSize = sizeof(MCHITTESTINFO); | |
620 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VE
RSION >= NTDDI_LONGHORN) | |
621 if(!(IsVista() && IsCommCtrl6())) | |
622 nSize = MCHITTESTINFO_V1_SIZE; | |
623 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NT
DDI_VERSION >= NTDDI_LONGHORN) | |
624 return nSize; | |
625 } | |
626 | |
627 #ifndef _WIN32_WCE | |
628 inline int SizeOf_NONCLIENTMETRICS() | |
629 { | |
630 int nSize = sizeof(NONCLIENTMETRICS); | |
631 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) | |
632 if(!IsVista()) | |
633 nSize = NONCLIENTMETRICS_V1_SIZE; | |
634 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) | |
635 return nSize; | |
636 } | |
637 #endif // !_WIN32_WCE | |
638 }; | |
639 | |
640 | |
641 /////////////////////////////////////////////////////////////////////////////// | |
642 // ModuleHelper - helper functions for ATL3 and ATL7 module classes | |
643 | |
644 namespace ModuleHelper | |
645 { | |
646 inline HINSTANCE GetModuleInstance() | |
647 { | |
648 #if (_ATL_VER >= 0x0700) | |
649 return ATL::_AtlBaseModule.GetModuleInstance(); | |
650 #else // !(_ATL_VER >= 0x0700) | |
651 return ATL::_pModule->GetModuleInstance(); | |
652 #endif // !(_ATL_VER >= 0x0700) | |
653 } | |
654 | |
655 inline HINSTANCE GetResourceInstance() | |
656 { | |
657 #if (_ATL_VER >= 0x0700) | |
658 return ATL::_AtlBaseModule.GetResourceInstance(); | |
659 #else // !(_ATL_VER >= 0x0700) | |
660 return ATL::_pModule->GetResourceInstance(); | |
661 #endif // !(_ATL_VER >= 0x0700) | |
662 } | |
663 | |
664 inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObjec
t) | |
665 { | |
666 #if (_ATL_VER >= 0x0700) | |
667 ATL::_AtlWinModule.AddCreateWndData(pData, pObject); | |
668 #else // !(_ATL_VER >= 0x0700) | |
669 ATL::_pModule->AddCreateWndData(pData, pObject); | |
670 #endif // !(_ATL_VER >= 0x0700) | |
671 } | |
672 | |
673 inline void* ExtractCreateWndData() | |
674 { | |
675 #if (_ATL_VER >= 0x0700) | |
676 return ATL::_AtlWinModule.ExtractCreateWndData(); | |
677 #else // !(_ATL_VER >= 0x0700) | |
678 return ATL::_pModule->ExtractCreateWndData(); | |
679 #endif // !(_ATL_VER >= 0x0700) | |
680 } | |
681 }; | |
682 | |
683 | |
684 /////////////////////////////////////////////////////////////////////////////// | |
685 // SecureHelper - helper functions for VS2005 secure CRT | |
686 | |
687 namespace SecureHelper | |
688 { | |
689 inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstr
Src) | |
690 { | |
691 #if _SECURE_ATL | |
692 ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc); | |
693 #else | |
694 if(cchDest > (size_t)lstrlenA(lpstrSrc)) | |
695 ATLVERIFY(lstrcpyA(lpstrDest, lpstrSrc) != NULL); | |
696 else | |
697 ATLASSERT(FALSE); | |
698 #endif | |
699 } | |
700 | |
701 inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t*
lpstrSrc) | |
702 { | |
703 #if _SECURE_ATL | |
704 ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc); | |
705 #else | |
706 if(cchDest > (size_t)lstrlenW(lpstrSrc)) | |
707 ATLVERIFY(lstrcpyW(lpstrDest, lpstrSrc) != NULL); | |
708 else | |
709 ATLASSERT(FALSE); | |
710 #endif | |
711 } | |
712 | |
713 inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) | |
714 { | |
715 #ifdef _UNICODE | |
716 strcpyW_x(lpstrDest, cchDest, lpstrSrc); | |
717 #else | |
718 strcpyA_x(lpstrDest, cchDest, lpstrSrc); | |
719 #endif | |
720 } | |
721 | |
722 inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* l
pstrSrc, size_t cchCount) | |
723 { | |
724 #if _SECURE_ATL | |
725 return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cch
Count); | |
726 #else | |
727 errno_t nRet = 0; | |
728 if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) | |
729 { | |
730 nRet = EINVAL; | |
731 } | |
732 else if(cchCount == _TRUNCATE) | |
733 { | |
734 cchCount = __min(cchDest - 1, size_t(lstrlenA(lpstrSrc))
); | |
735 nRet = STRUNCATE; | |
736 } | |
737 else if(cchDest <= cchCount) | |
738 { | |
739 lpstrDest[0] = 0; | |
740 nRet = EINVAL; | |
741 } | |
742 if(nRet == 0 || nRet == STRUNCATE) | |
743 nRet = (lstrcpynA(lpstrDest, lpstrSrc, (int)cchCount + 1
) != NULL) ? nRet : EINVAL; | |
744 ATLASSERT(nRet == 0 || nRet == STRUNCATE); | |
745 return nRet; | |
746 #endif | |
747 } | |
748 | |
749 inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wcha
r_t* lpstrSrc, size_t cchCount) | |
750 { | |
751 #if _SECURE_ATL | |
752 return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cch
Count); | |
753 #else | |
754 errno_t nRet = 0; | |
755 if(lpstrDest == NULL || cchDest == 0 || lpstrSrc == NULL) | |
756 { | |
757 nRet = EINVAL; | |
758 } | |
759 else if(cchCount == _TRUNCATE) | |
760 { | |
761 cchCount = __min(cchDest - 1, size_t(lstrlenW(lpstrSrc))
); | |
762 nRet = STRUNCATE; | |
763 } | |
764 else if(cchDest <= cchCount) | |
765 { | |
766 lpstrDest[0] = 0; | |
767 nRet = EINVAL; | |
768 } | |
769 if(nRet == 0 || nRet == STRUNCATE) | |
770 nRet = (lstrcpynW(lpstrDest, lpstrSrc, (int)cchCount + 1
) != NULL) ? nRet : EINVAL; | |
771 ATLASSERT(nRet == 0 || nRet == STRUNCATE); | |
772 return nRet; | |
773 #endif | |
774 } | |
775 | |
776 inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstr
Src, size_t cchCount) | |
777 { | |
778 #ifdef _UNICODE | |
779 return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount); | |
780 #else | |
781 return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount); | |
782 #endif | |
783 } | |
784 | |
785 inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstr
Src) | |
786 { | |
787 #if _SECURE_ATL | |
788 ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc); | |
789 #else | |
790 if(cchDest > (size_t)lstrlenA(lpstrSrc)) | |
791 ATLVERIFY(lstrcatA(lpstrDest, lpstrSrc) != NULL); | |
792 else | |
793 ATLASSERT(FALSE); | |
794 #endif | |
795 } | |
796 | |
797 inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t*
lpstrSrc) | |
798 { | |
799 #if _SECURE_ATL | |
800 ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc); | |
801 #else | |
802 if(cchDest > (size_t)lstrlenW(lpstrSrc)) | |
803 ATLVERIFY(lstrcatW(lpstrDest, lpstrSrc) != NULL); | |
804 else | |
805 ATLASSERT(FALSE); | |
806 #endif | |
807 } | |
808 | |
809 inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) | |
810 { | |
811 #ifdef _UNICODE | |
812 strcatW_x(lpstrDest, cchDest, lpstrSrc); | |
813 #else | |
814 strcatA_x(lpstrDest, cchDest, lpstrSrc); | |
815 #endif | |
816 } | |
817 | |
818 inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_
t cbSrc) | |
819 { | |
820 #if _SECURE_ATL | |
821 ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc); | |
822 #else | |
823 if(cbDest >= cbSrc) | |
824 memcpy(pDest, pSrc, cbSrc); | |
825 else | |
826 ATLASSERT(FALSE); | |
827 #endif | |
828 } | |
829 | |
830 inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size
_t cbSrc) | |
831 { | |
832 #if _SECURE_ATL | |
833 ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc); | |
834 #else | |
835 if(cbDest >= cbSrc) | |
836 memmove(pDest, pSrc, cbSrc); | |
837 else | |
838 ATLASSERT(FALSE); | |
839 #endif | |
840 } | |
841 | |
842 inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFor
mat, va_list args) | |
843 { | |
844 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) | |
845 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); | |
846 #else | |
847 cchBuff; // Avoid unused argument warning | |
848 return _vstprintf(lpstrBuff, lpstrFormat, args); | |
849 #endif | |
850 } | |
851 | |
852 inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFo
rmat, va_list args) | |
853 { | |
854 #if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE) | |
855 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); | |
856 #else | |
857 cchBuff; // Avoid unused argument warning | |
858 return ::wvsprintf(lpstrBuff, lpstrFormat, args); | |
859 #endif | |
860 } | |
861 | |
862 inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrForm
at, ...) | |
863 { | |
864 va_list args; | |
865 va_start(args, lpstrFormat); | |
866 int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); | |
867 va_end(args); | |
868 return nRes; | |
869 } | |
870 | |
871 inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFor
mat, ...) | |
872 { | |
873 va_list args; | |
874 va_start(args, lpstrFormat); | |
875 int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); | |
876 va_end(args); | |
877 return nRes; | |
878 } | |
879 }; // namespace SecureHelper | |
880 | |
881 | |
882 /////////////////////////////////////////////////////////////////////////////// | |
883 // CMessageFilter - Interface for message filter support | |
884 | |
885 class CMessageFilter | |
886 { | |
887 public: | |
888 virtual BOOL PreTranslateMessage(MSG* pMsg) = 0; | |
889 }; | |
890 | |
891 | |
892 /////////////////////////////////////////////////////////////////////////////// | |
893 // CIdleHandler - Interface for idle processing | |
894 | |
895 class CIdleHandler | |
896 { | |
897 public: | |
898 virtual BOOL OnIdle() = 0; | |
899 }; | |
900 | |
901 #ifndef _ATL_NO_OLD_NAMES | |
902 // for compatilibility with old names only | |
903 typedef CIdleHandler CUpdateUIObject; | |
904 #define DoUpdate OnIdle | |
905 #endif // !_ATL_NO_OLD_NAMES | |
906 | |
907 | |
908 /////////////////////////////////////////////////////////////////////////////// | |
909 // CMessageLoop - message loop implementation | |
910 | |
911 class CMessageLoop | |
912 { | |
913 public: | |
914 ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter; | |
915 ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler; | |
916 MSG m_msg; | |
917 | |
918 // Message filter operations | |
919 BOOL AddMessageFilter(CMessageFilter* pMessageFilter) | |
920 { | |
921 return m_aMsgFilter.Add(pMessageFilter); | |
922 } | |
923 | |
924 BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter) | |
925 { | |
926 return m_aMsgFilter.Remove(pMessageFilter); | |
927 } | |
928 | |
929 // Idle handler operations | |
930 BOOL AddIdleHandler(CIdleHandler* pIdleHandler) | |
931 { | |
932 return m_aIdleHandler.Add(pIdleHandler); | |
933 } | |
934 | |
935 BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler) | |
936 { | |
937 return m_aIdleHandler.Remove(pIdleHandler); | |
938 } | |
939 | |
940 #ifndef _ATL_NO_OLD_NAMES | |
941 // for compatilibility with old names only | |
942 BOOL AddUpdateUI(CIdleHandler* pIdleHandler) | |
943 { | |
944 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and AddUpdateUI are
deprecated. Please change your code to use CIdleHandler and OnIdle\n")); | |
945 return AddIdleHandler(pIdleHandler); | |
946 } | |
947 | |
948 BOOL RemoveUpdateUI(CIdleHandler* pIdleHandler) | |
949 { | |
950 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIObject and RemoveUpdateUI
are deprecated. Please change your code to use CIdleHandler and OnIdle\n")); | |
951 return RemoveIdleHandler(pIdleHandler); | |
952 } | |
953 #endif // !_ATL_NO_OLD_NAMES | |
954 | |
955 // message loop | |
956 int Run() | |
957 { | |
958 BOOL bDoIdle = TRUE; | |
959 int nIdleCount = 0; | |
960 BOOL bRet; | |
961 | |
962 for(;;) | |
963 { | |
964 while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_N
OREMOVE)) | |
965 { | |
966 if(!OnIdle(nIdleCount++)) | |
967 bDoIdle = FALSE; | |
968 } | |
969 | |
970 bRet = ::GetMessage(&m_msg, NULL, 0, 0); | |
971 | |
972 if(bRet == -1) | |
973 { | |
974 ATLTRACE2(atlTraceUI, 0, _T("::GetMessage return
ed -1 (error)\n")); | |
975 continue; // error, don't process | |
976 } | |
977 else if(!bRet) | |
978 { | |
979 ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run -
exiting\n")); | |
980 break; // WM_QUIT, exit message loop | |
981 } | |
982 | |
983 if(!PreTranslateMessage(&m_msg)) | |
984 { | |
985 ::TranslateMessage(&m_msg); | |
986 ::DispatchMessage(&m_msg); | |
987 } | |
988 | |
989 if(IsIdleMessage(&m_msg)) | |
990 { | |
991 bDoIdle = TRUE; | |
992 nIdleCount = 0; | |
993 } | |
994 } | |
995 | |
996 return (int)m_msg.wParam; | |
997 } | |
998 | |
999 static BOOL IsIdleMessage(MSG* pMsg) | |
1000 { | |
1001 // These messages should NOT cause idle processing | |
1002 switch(pMsg->message) | |
1003 { | |
1004 case WM_MOUSEMOVE: | |
1005 #ifndef _WIN32_WCE | |
1006 case WM_NCMOUSEMOVE: | |
1007 #endif // !_WIN32_WCE | |
1008 case WM_PAINT: | |
1009 case 0x0118: // WM_SYSTIMER (caret blink) | |
1010 return FALSE; | |
1011 } | |
1012 | |
1013 return TRUE; | |
1014 } | |
1015 | |
1016 // Overrideables | |
1017 // Override to change message filtering | |
1018 virtual BOOL PreTranslateMessage(MSG* pMsg) | |
1019 { | |
1020 // loop backwards | |
1021 for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--) | |
1022 { | |
1023 CMessageFilter* pMessageFilter = m_aMsgFilter[i]; | |
1024 if(pMessageFilter != NULL && pMessageFilter->PreTranslat
eMessage(pMsg)) | |
1025 return TRUE; | |
1026 } | |
1027 return FALSE; // not translated | |
1028 } | |
1029 | |
1030 // override to change idle processing | |
1031 virtual BOOL OnIdle(int /*nIdleCount*/) | |
1032 { | |
1033 for(int i = 0; i < m_aIdleHandler.GetSize(); i++) | |
1034 { | |
1035 CIdleHandler* pIdleHandler = m_aIdleHandler[i]; | |
1036 if(pIdleHandler != NULL) | |
1037 pIdleHandler->OnIdle(); | |
1038 } | |
1039 return FALSE; // don't continue | |
1040 } | |
1041 }; | |
1042 | |
1043 | |
1044 /////////////////////////////////////////////////////////////////////////////// | |
1045 // CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock | |
1046 // internal classes to manage critical sections for both ATL3 and ATL7 | |
1047 | |
1048 class CStaticDataInitCriticalSectionLock | |
1049 { | |
1050 public: | |
1051 #if (_ATL_VER >= 0x0700) | |
1052 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock; | |
1053 | |
1054 CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csSt
aticDataInitAndTypeInfo, false) | |
1055 { } | |
1056 #endif // (_ATL_VER >= 0x0700) | |
1057 | |
1058 HRESULT Lock() | |
1059 { | |
1060 #if (_ATL_VER >= 0x0700) | |
1061 return m_cslock.Lock(); | |
1062 #else // !(_ATL_VER >= 0x0700) | |
1063 ::EnterCriticalSection(&ATL::_pModule->m_csStaticDataInit); | |
1064 return S_OK; | |
1065 #endif // !(_ATL_VER >= 0x0700) | |
1066 } | |
1067 | |
1068 void Unlock() | |
1069 { | |
1070 #if (_ATL_VER >= 0x0700) | |
1071 m_cslock.Unlock(); | |
1072 #else // !(_ATL_VER >= 0x0700) | |
1073 ::LeaveCriticalSection(&ATL::_pModule->m_csStaticDataInit); | |
1074 #endif // !(_ATL_VER >= 0x0700) | |
1075 } | |
1076 }; | |
1077 | |
1078 | |
1079 class CWindowCreateCriticalSectionLock | |
1080 { | |
1081 public: | |
1082 #if (_ATL_VER >= 0x0700) | |
1083 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock; | |
1084 | |
1085 CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWin
dowCreate, false) | |
1086 { } | |
1087 #endif // (_ATL_VER >= 0x0700) | |
1088 | |
1089 HRESULT Lock() | |
1090 { | |
1091 #if (_ATL_VER >= 0x0700) | |
1092 return m_cslock.Lock(); | |
1093 #else // !(_ATL_VER >= 0x0700) | |
1094 ::EnterCriticalSection(&ATL::_pModule->m_csWindowCreate); | |
1095 return S_OK; | |
1096 #endif // !(_ATL_VER >= 0x0700) | |
1097 } | |
1098 | |
1099 void Unlock() | |
1100 { | |
1101 #if (_ATL_VER >= 0x0700) | |
1102 m_cslock.Unlock(); | |
1103 #else // !(_ATL_VER >= 0x0700) | |
1104 ::LeaveCriticalSection(&ATL::_pModule->m_csWindowCreate); | |
1105 #endif // !(_ATL_VER >= 0x0700) | |
1106 } | |
1107 }; | |
1108 | |
1109 | |
1110 /////////////////////////////////////////////////////////////////////////////// | |
1111 // CTempBuffer - helper class for stack allocations for ATL3 | |
1112 | |
1113 #ifndef _WTL_STACK_ALLOC_THRESHOLD | |
1114 #define _WTL_STACK_ALLOC_THRESHOLD 512 | |
1115 #endif | |
1116 | |
1117 #if (_ATL_VER >= 0x0700) | |
1118 | |
1119 using ATL::CTempBuffer; | |
1120 | |
1121 #else // !(_ATL_VER >= 0x0700) | |
1122 | |
1123 #ifndef SIZE_MAX | |
1124 #ifdef _WIN64 | |
1125 #define SIZE_MAX _UI64_MAX | |
1126 #else | |
1127 #define SIZE_MAX UINT_MAX | |
1128 #endif | |
1129 #endif | |
1130 | |
1131 #pragma warning(disable: 4284) // warning for operator -> | |
1132 | |
1133 template<typename T, int t_nFixedBytes = 128> | |
1134 class CTempBuffer | |
1135 { | |
1136 public: | |
1137 CTempBuffer() : m_p(NULL) | |
1138 { | |
1139 } | |
1140 | |
1141 CTempBuffer(size_t nElements) : m_p(NULL) | |
1142 { | |
1143 Allocate(nElements); | |
1144 } | |
1145 | |
1146 ~CTempBuffer() | |
1147 { | |
1148 if(m_p != reinterpret_cast<T*>(m_abFixedBuffer)) | |
1149 free(m_p); | |
1150 } | |
1151 | |
1152 operator T*() const | |
1153 { | |
1154 return m_p; | |
1155 } | |
1156 | |
1157 T* operator ->() const | |
1158 { | |
1159 ATLASSERT(m_p != NULL); | |
1160 return m_p; | |
1161 } | |
1162 | |
1163 T* Allocate(size_t nElements) | |
1164 { | |
1165 ATLASSERT(nElements <= (SIZE_MAX / sizeof(T))); | |
1166 return AllocateBytes(nElements * sizeof(T)); | |
1167 } | |
1168 | |
1169 T* AllocateBytes(size_t nBytes) | |
1170 { | |
1171 ATLASSERT(m_p == NULL); | |
1172 if(nBytes > t_nFixedBytes) | |
1173 m_p = static_cast<T*>(malloc(nBytes)); | |
1174 else | |
1175 m_p = reinterpret_cast<T*>(m_abFixedBuffer); | |
1176 | |
1177 return m_p; | |
1178 } | |
1179 | |
1180 private: | |
1181 T* m_p; | |
1182 BYTE m_abFixedBuffer[t_nFixedBytes]; | |
1183 }; | |
1184 | |
1185 #pragma warning(default: 4284) | |
1186 | |
1187 #endif // !(_ATL_VER >= 0x0700) | |
1188 | |
1189 | |
1190 /////////////////////////////////////////////////////////////////////////////// | |
1191 // CAppModule - module class for an application | |
1192 | |
1193 class CAppModule : public ATL::CComModule | |
1194 { | |
1195 public: | |
1196 DWORD m_dwMainThreadID; | |
1197 ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap; | |
1198 ATL::CSimpleArray<HWND>* m_pSettingChangeNotify; | |
1199 | |
1200 // Overrides of CComModule::Init and Term | |
1201 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const
GUID* pLibID = NULL) | |
1202 { | |
1203 HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID); | |
1204 if(FAILED(hRet)) | |
1205 return hRet; | |
1206 | |
1207 m_dwMainThreadID = ::GetCurrentThreadId(); | |
1208 typedef ATL::CSimpleMap<DWORD, CMessageLoop*> _mapClass; | |
1209 m_pMsgLoopMap = NULL; | |
1210 ATLTRY(m_pMsgLoopMap = new _mapClass); | |
1211 if(m_pMsgLoopMap == NULL) | |
1212 return E_OUTOFMEMORY; | |
1213 m_pSettingChangeNotify = NULL; | |
1214 | |
1215 return hRet; | |
1216 } | |
1217 | |
1218 void Term() | |
1219 { | |
1220 TermSettingChangeNotify(); | |
1221 delete m_pMsgLoopMap; | |
1222 CComModule::Term(); | |
1223 } | |
1224 | |
1225 // Message loop map methods | |
1226 BOOL AddMessageLoop(CMessageLoop* pMsgLoop) | |
1227 { | |
1228 CStaticDataInitCriticalSectionLock lock; | |
1229 if(FAILED(lock.Lock())) | |
1230 { | |
1231 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock crit
ical section in CAppModule::AddMessageLoop.\n")); | |
1232 ATLASSERT(FALSE); | |
1233 return FALSE; | |
1234 } | |
1235 | |
1236 ATLASSERT(pMsgLoop != NULL); | |
1237 ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL)
; // not in map yet | |
1238 | |
1239 BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop)
; | |
1240 | |
1241 lock.Unlock(); | |
1242 | |
1243 return bRet; | |
1244 } | |
1245 | |
1246 BOOL RemoveMessageLoop() | |
1247 { | |
1248 CStaticDataInitCriticalSectionLock lock; | |
1249 if(FAILED(lock.Lock())) | |
1250 { | |
1251 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock crit
ical section in CAppModule::RemoveMessageLoop.\n")); | |
1252 ATLASSERT(FALSE); | |
1253 return FALSE; | |
1254 } | |
1255 | |
1256 BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId()); | |
1257 | |
1258 lock.Unlock(); | |
1259 | |
1260 return bRet; | |
1261 } | |
1262 | |
1263 CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId())
const | |
1264 { | |
1265 CStaticDataInitCriticalSectionLock lock; | |
1266 if(FAILED(lock.Lock())) | |
1267 { | |
1268 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock crit
ical section in CAppModule::GetMessageLoop.\n")); | |
1269 ATLASSERT(FALSE); | |
1270 return NULL; | |
1271 } | |
1272 | |
1273 CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID); | |
1274 | |
1275 lock.Unlock(); | |
1276 | |
1277 return pLoop; | |
1278 } | |
1279 | |
1280 // Setting change notify methods | |
1281 // Note: Call this from the main thread for MSDI apps | |
1282 BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc) | |
1283 { | |
1284 CStaticDataInitCriticalSectionLock lock; | |
1285 if(FAILED(lock.Lock())) | |
1286 { | |
1287 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock crit
ical section in CAppModule::InitSettingChangeNotify.\n")); | |
1288 ATLASSERT(FALSE); | |
1289 return FALSE; | |
1290 } | |
1291 | |
1292 if(m_pSettingChangeNotify == NULL) | |
1293 { | |
1294 typedef ATL::CSimpleArray<HWND> _notifyClass; | |
1295 ATLTRY(m_pSettingChangeNotify = new _notifyClass); | |
1296 ATLASSERT(m_pSettingChangeNotify != NULL); | |
1297 } | |
1298 | |
1299 BOOL bRet = (m_pSettingChangeNotify != NULL); | |
1300 if(bRet && m_pSettingChangeNotify->GetSize() == 0) | |
1301 { | |
1302 // init everything | |
1303 _ATL_EMPTY_DLGTEMPLATE templ; | |
1304 HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(
), &templ, NULL, pfnDlgProc); | |
1305 ATLASSERT(::IsWindow(hNtfWnd)); | |
1306 if(::IsWindow(hNtfWnd)) | |
1307 { | |
1308 // need conditional code because types don't match in winuser.h | |
1309 #ifdef _WIN64 | |
1310 ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG
_PTR)this); | |
1311 #else | |
1312 ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, PtrTo
Long(this)); | |
1313 #endif | |
1314 bRet = m_pSettingChangeNotify->Add(hNtfWnd); | |
1315 } | |
1316 else | |
1317 { | |
1318 bRet = FALSE; | |
1319 } | |
1320 } | |
1321 | |
1322 lock.Unlock(); | |
1323 | |
1324 return bRet; | |
1325 } | |
1326 | |
1327 void TermSettingChangeNotify() | |
1328 { | |
1329 CStaticDataInitCriticalSectionLock lock; | |
1330 if(FAILED(lock.Lock())) | |
1331 { | |
1332 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock crit
ical section in CAppModule::TermSettingChangeNotify.\n")); | |
1333 ATLASSERT(FALSE); | |
1334 return; | |
1335 } | |
1336 | |
1337 if(m_pSettingChangeNotify != NULL && m_pSettingChangeNotify->Get
Size() > 0) | |
1338 ::DestroyWindow((*m_pSettingChangeNotify)[0]); | |
1339 delete m_pSettingChangeNotify; | |
1340 m_pSettingChangeNotify = NULL; | |
1341 | |
1342 lock.Unlock(); | |
1343 } | |
1344 | |
1345 BOOL AddSettingChangeNotify(HWND hWnd) | |
1346 { | |
1347 CStaticDataInitCriticalSectionLock lock; | |
1348 if(FAILED(lock.Lock())) | |
1349 { | |
1350 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock crit
ical section in CAppModule::AddSettingChangeNotify.\n")); | |
1351 ATLASSERT(FALSE); | |
1352 return FALSE; | |
1353 } | |
1354 | |
1355 ATLASSERT(::IsWindow(hWnd)); | |
1356 BOOL bRet = FALSE; | |
1357 if(InitSettingChangeNotify() != FALSE) | |
1358 bRet = m_pSettingChangeNotify->Add(hWnd); | |
1359 | |
1360 lock.Unlock(); | |
1361 | |
1362 return bRet; | |
1363 } | |
1364 | |
1365 BOOL RemoveSettingChangeNotify(HWND hWnd) | |
1366 { | |
1367 CStaticDataInitCriticalSectionLock lock; | |
1368 if(FAILED(lock.Lock())) | |
1369 { | |
1370 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock crit
ical section in CAppModule::RemoveSettingChangeNotify.\n")); | |
1371 ATLASSERT(FALSE); | |
1372 return FALSE; | |
1373 } | |
1374 | |
1375 BOOL bRet = FALSE; | |
1376 if(m_pSettingChangeNotify != NULL) | |
1377 bRet = m_pSettingChangeNotify->Remove(hWnd); | |
1378 | |
1379 lock.Unlock(); | |
1380 | |
1381 return bRet; | |
1382 } | |
1383 | |
1384 // Implementation - setting change notify dialog template and dialog procedure | |
1385 struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE | |
1386 { | |
1387 _ATL_EMPTY_DLGTEMPLATE() | |
1388 { | |
1389 memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE)); | |
1390 style = WS_POPUP; | |
1391 } | |
1392 WORD wMenu, wClass, wTitle; | |
1393 }; | |
1394 | |
1395 #ifdef _WIN64 | |
1396 static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPAR
AM wParam, LPARAM lParam) | |
1397 #else | |
1398 static BOOL CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM
wParam, LPARAM lParam) | |
1399 #endif | |
1400 { | |
1401 if(uMsg == WM_SETTINGCHANGE) | |
1402 { | |
1403 // need conditional code because types don't match in winuser.h | |
1404 #ifdef _WIN64 | |
1405 CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hW
nd, GWLP_USERDATA); | |
1406 #else | |
1407 CAppModule* pModule = (CAppModule*)LongToPtr(::GetWindow
LongPtr(hWnd, GWLP_USERDATA)); | |
1408 #endif | |
1409 ATLASSERT(pModule != NULL); | |
1410 ATLASSERT(pModule->m_pSettingChangeNotify != NULL); | |
1411 const UINT uTimeout = 1500; // ms | |
1412 for(int i = 1; i < pModule->m_pSettingChangeNotify->GetS
ize(); i++) | |
1413 { | |
1414 #if !defined(_WIN32_WCE) | |
1415 ::SendMessageTimeout((*pModule->m_pSettingChange
Notify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL); | |
1416 #elif(_WIN32_WCE >= 400) // CE specific | |
1417 ::SendMessageTimeout((*pModule->m_pSettingChange
Notify)[i], uMsg, wParam, lParam, SMTO_NORMAL, uTimeout, NULL); | |
1418 #else // _WIN32_WCE < 400 specific | |
1419 uTimeout; | |
1420 ::SendMessage((*pModule->m_pSettingChangeNotify)
[i], uMsg, wParam, lParam); | |
1421 #endif | |
1422 } | |
1423 return TRUE; | |
1424 } | |
1425 return FALSE; | |
1426 } | |
1427 }; | |
1428 | |
1429 | |
1430 /////////////////////////////////////////////////////////////////////////////// | |
1431 // CServerAppModule - module class for a COM server application | |
1432 | |
1433 class CServerAppModule : public CAppModule | |
1434 { | |
1435 public: | |
1436 HANDLE m_hEventShutdown; | |
1437 bool m_bActivity; | |
1438 DWORD m_dwTimeOut; | |
1439 DWORD m_dwPause; | |
1440 | |
1441 // Override of CAppModule::Init | |
1442 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const
GUID* pLibID = NULL) | |
1443 { | |
1444 m_dwTimeOut = 5000; | |
1445 m_dwPause = 1000; | |
1446 return CAppModule::Init(pObjMap, hInstance, pLibID); | |
1447 } | |
1448 | |
1449 void Term() | |
1450 { | |
1451 if(m_hEventShutdown != NULL && ::CloseHandle(m_hEventShutdown)) | |
1452 m_hEventShutdown = NULL; | |
1453 CAppModule::Term(); | |
1454 } | |
1455 | |
1456 // COM Server methods | |
1457 LONG Unlock() | |
1458 { | |
1459 LONG lRet = CComModule::Unlock(); | |
1460 if(lRet == 0) | |
1461 { | |
1462 m_bActivity = true; | |
1463 ::SetEvent(m_hEventShutdown); // tell monitor that we tr
ansitioned to zero | |
1464 } | |
1465 return lRet; | |
1466 } | |
1467 | |
1468 void MonitorShutdown() | |
1469 { | |
1470 for(;;) | |
1471 { | |
1472 ::WaitForSingleObject(m_hEventShutdown, INFINITE); | |
1473 DWORD dwWait = 0; | |
1474 do | |
1475 { | |
1476 m_bActivity = false; | |
1477 dwWait = ::WaitForSingleObject(m_hEventShutdown,
m_dwTimeOut); | |
1478 } | |
1479 while(dwWait == WAIT_OBJECT_0); | |
1480 // timed out | |
1481 if(!m_bActivity && m_nLockCnt == 0) // if no activity le
t's really bail | |
1482 { | |
1483 #if ((_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM)) && defined(_ATL_FREE_THR
EADED) && !defined(_WIN32_WCE) | |
1484 ::CoSuspendClassObjects(); | |
1485 if(!m_bActivity && m_nLockCnt == 0) | |
1486 #endif | |
1487 break; | |
1488 } | |
1489 } | |
1490 // This handle should be valid now. If it isn't, | |
1491 // check if _Module.Term was called first (it shouldn't) | |
1492 if(::CloseHandle(m_hEventShutdown)) | |
1493 m_hEventShutdown = NULL; | |
1494 ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0); | |
1495 } | |
1496 | |
1497 bool StartMonitor() | |
1498 { | |
1499 m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL); | |
1500 if(m_hEventShutdown == NULL) | |
1501 return false; | |
1502 DWORD dwThreadID = 0; | |
1503 #if !defined(_ATL_MIN_CRT) && defined(_MT) && !defined(_WIN32_WCE) | |
1504 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)
(void*))MonitorProc, this, 0, (UINT*)&dwThreadID); | |
1505 #else | |
1506 HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &
dwThreadID); | |
1507 #endif | |
1508 bool bRet = (hThread != NULL); | |
1509 if(bRet) | |
1510 ::CloseHandle(hThread); | |
1511 return bRet; | |
1512 } | |
1513 | |
1514 static DWORD WINAPI MonitorProc(void* pv) | |
1515 { | |
1516 CServerAppModule* p = (CServerAppModule*)pv; | |
1517 p->MonitorShutdown(); | |
1518 return 0; | |
1519 } | |
1520 | |
1521 #if (_ATL_VER < 0x0700) | |
1522 // search for an occurence of string p2 in string p1 | |
1523 static LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2) | |
1524 { | |
1525 while(p1 != NULL && *p1 != NULL) | |
1526 { | |
1527 LPCTSTR p = p2; | |
1528 while(p != NULL && *p != NULL) | |
1529 { | |
1530 if(*p1 == *p) | |
1531 return ::CharNext(p1); | |
1532 p = ::CharNext(p); | |
1533 } | |
1534 p1 = ::CharNext(p1); | |
1535 } | |
1536 return NULL; | |
1537 } | |
1538 #endif // (_ATL_VER < 0x0700) | |
1539 }; | |
1540 | |
1541 | |
1542 /////////////////////////////////////////////////////////////////////////////// | |
1543 // CString forward reference (enables CString use in atluser.h and atlgdi.h) | |
1544 | |
1545 #if defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) | |
1546 #define _WTL_USE_CSTRING | |
1547 #endif // defined(_WTL_FORWARD_DECLARE_CSTRING) && !defined(_WTL_USE_CSTRING) | |
1548 | |
1549 #ifdef _WTL_USE_CSTRING | |
1550 class CString; // forward declaration (include atlmisc.h for the whole class
) | |
1551 #endif // _WTL_USE_CSTRING | |
1552 | |
1553 // CString namespace | |
1554 #ifndef _CSTRING_NS | |
1555 #ifdef __ATLSTR_H__ | |
1556 #define _CSTRING_NS ATL | |
1557 #else | |
1558 #define _CSTRING_NS WTL | |
1559 #endif | |
1560 #endif // _CSTRING_NS | |
1561 | |
1562 // Type classes namespace | |
1563 #ifndef _WTYPES_NS | |
1564 #ifdef __ATLTYPES_H__ | |
1565 #define _WTYPES_NS | |
1566 #else | |
1567 #define _WTYPES_NS WTL | |
1568 #endif | |
1569 #endif // _WTYPES_NS | |
1570 | |
1571 }; // namespace WTL | |
1572 | |
1573 | |
1574 /////////////////////////////////////////////////////////////////////////////// | |
1575 // General DLL version helpers | |
1576 // (ATL3: excluded from atlbase.h if _ATL_DLL is defined; ATL11: removed) | |
1577 | |
1578 #if (((_ATL_VER < 0x0700) && defined(_ATL_DLL)) || (_ATL_VER >= 0x0B00)) && !def
ined(_WIN32_WCE) | |
1579 | |
1580 namespace ATL | |
1581 { | |
1582 | |
1583 inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionI
nfo) | |
1584 { | |
1585 ATLASSERT(pDllVersionInfo != NULL); | |
1586 if(pDllVersionInfo == NULL) | |
1587 return E_INVALIDARG; | |
1588 | |
1589 // We must get this function explicitly because some DLLs don't implemen
t it. | |
1590 DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress
(hInstDLL, "DllGetVersion"); | |
1591 if(pfnDllGetVersion == NULL) | |
1592 return E_NOTIMPL; | |
1593 | |
1594 return (*pfnDllGetVersion)(pDllVersionInfo); | |
1595 } | |
1596 | |
1597 inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersio
nInfo) | |
1598 { | |
1599 HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName); | |
1600 if(hInstDLL == NULL) | |
1601 return E_FAIL; | |
1602 HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo); | |
1603 ::FreeLibrary(hInstDLL); | |
1604 return hRet; | |
1605 } | |
1606 | |
1607 // Common Control Versions: | |
1608 // Win95/WinNT 4.0 maj=4 min=00 | |
1609 // IE 3.x maj=4 min=70 | |
1610 // IE 4.0 maj=4 min=71 | |
1611 inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) | |
1612 { | |
1613 ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); | |
1614 if(pdwMajor == NULL || pdwMinor == NULL) | |
1615 return E_INVALIDARG; | |
1616 | |
1617 DLLVERSIONINFO dvi; | |
1618 ::ZeroMemory(&dvi, sizeof(dvi)); | |
1619 dvi.cbSize = sizeof(dvi); | |
1620 HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi); | |
1621 | |
1622 if(SUCCEEDED(hRet)) | |
1623 { | |
1624 *pdwMajor = dvi.dwMajorVersion; | |
1625 *pdwMinor = dvi.dwMinorVersion; | |
1626 } | |
1627 else if(hRet == E_NOTIMPL) | |
1628 { | |
1629 // If DllGetVersion is not there, then the DLL is a version | |
1630 // previous to the one shipped with IE 3.x | |
1631 *pdwMajor = 4; | |
1632 *pdwMinor = 0; | |
1633 hRet = S_OK; | |
1634 } | |
1635 | |
1636 return hRet; | |
1637 } | |
1638 | |
1639 // Shell Versions: | |
1640 // Win95/WinNT 4.0 maj=4 min=00 | |
1641 // IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00 | |
1642 // IE 4.0 with Web Integrated Desktop maj=4 min=71 | |
1643 // IE 4.01 with Web Integrated Desktop maj=4 min=72 | |
1644 inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) | |
1645 { | |
1646 ATLASSERT(pdwMajor != NULL && pdwMinor != NULL); | |
1647 if(pdwMajor == NULL || pdwMinor == NULL) | |
1648 return E_INVALIDARG; | |
1649 | |
1650 DLLVERSIONINFO dvi; | |
1651 ::ZeroMemory(&dvi, sizeof(dvi)); | |
1652 dvi.cbSize = sizeof(dvi); | |
1653 HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi); | |
1654 | |
1655 if(SUCCEEDED(hRet)) | |
1656 { | |
1657 *pdwMajor = dvi.dwMajorVersion; | |
1658 *pdwMinor = dvi.dwMinorVersion; | |
1659 } | |
1660 else if(hRet == E_NOTIMPL) | |
1661 { | |
1662 // If DllGetVersion is not there, then the DLL is a version | |
1663 // previous to the one shipped with IE 4.x | |
1664 *pdwMajor = 4; | |
1665 *pdwMinor = 0; | |
1666 hRet = S_OK; | |
1667 } | |
1668 | |
1669 return hRet; | |
1670 } | |
1671 | |
1672 }; // namespace ATL | |
1673 | |
1674 #endif // (_ATL_VER < 0x0700) && defined(_ATL_DLL) && !defined(_WIN32_WCE) | |
1675 | |
1676 | |
1677 // These are always included | |
1678 #include "atlwinx.h" | |
1679 #include "atluser.h" | |
1680 #include "atlgdi.h" | |
1681 | |
1682 #ifndef _WTL_NO_AUTOMATIC_NAMESPACE | |
1683 using namespace WTL; | |
1684 #endif // !_WTL_NO_AUTOMATIC_NAMESPACE | |
1685 | |
1686 #endif // __ATLAPP_H__ | |
OLD | NEW |