Mercurial > foo_out_sdl
comparison foosdk/wtl/Include/atlapp.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 // Windows Template Library - WTL version 10.0 | |
| 2 // Copyright (C) Microsoft Corporation, WTL Team. All rights reserved. | |
| 3 // | |
| 4 // This file is a part of the Windows Template Library. | |
| 5 // The use and distribution terms for this software are covered by the | |
| 6 // 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 #ifdef _WIN32_WCE | |
| 23 #error WTL10 doesn't support Windows CE | |
| 24 #endif | |
| 25 | |
| 26 #ifdef _ATL_NO_COMMODULE | |
| 27 #error WTL requires that _ATL_NO_COMMODULE is not defined | |
| 28 #endif | |
| 29 | |
| 30 #ifdef _ATL_NO_WIN_SUPPORT | |
| 31 #error WTL requires that _ATL_NO_WIN_SUPPORT is not defined | |
| 32 #endif | |
| 33 | |
| 34 #if (_MSC_VER < 1400) | |
| 35 #error WTL10 requires C++ compiler version 14 (Visual C++ 2005) or higher | |
| 36 #endif | |
| 37 | |
| 38 #if (WINVER < 0x0501) | |
| 39 #error WTL requires WINVER >= 0x0501 | |
| 40 #endif | |
| 41 | |
| 42 #if (_WIN32_WINNT < 0x0501) | |
| 43 #error WTL requires _WIN32_WINNT >= 0x0501 | |
| 44 #endif | |
| 45 | |
| 46 #if (_WIN32_IE < 0x0600) | |
| 47 #error WTL requires _WIN32_IE >= 0x0600 | |
| 48 #endif | |
| 49 | |
| 50 #if (_ATL_VER < 0x0800) | |
| 51 #error WTL10 requires ATL version 8 or higher | |
| 52 #endif | |
| 53 | |
| 54 #ifdef _ATL_MIN_CRT | |
| 55 #error WTL10 doesn't support _ATL_MIN_CRT | |
| 56 #endif | |
| 57 | |
| 58 #ifdef _ATL_NO_MSIMG | |
| 59 #error WTL10 doesn't support _ATL_NO_MSIMG | |
| 60 #endif | |
| 61 | |
| 62 #include <limits.h> | |
| 63 #ifdef _MT | |
| 64 #include <process.h> // for _beginthreadex | |
| 65 #endif | |
| 66 | |
| 67 #include <commctrl.h> | |
| 68 #pragma comment(lib, "comctl32.lib") | |
| 69 | |
| 70 #include <commdlg.h> | |
| 71 #include <shellapi.h> | |
| 72 | |
| 73 // Check for VS2005 without newer WinSDK | |
| 74 #if (_MSC_VER == 1400) && !defined(RB_GETEXTENDEDSTYLE) | |
| 75 #error WTL10 requires WinSDK 6.0 ot higher | |
| 76 #endif | |
| 77 | |
| 78 #include <uxtheme.h> | |
| 79 #pragma comment(lib, "uxtheme.lib") | |
| 80 | |
| 81 #if defined(_SYSINFOAPI_H_) && defined(NOT_BUILD_WINDOWS_DEPRECATE) | |
| 82 #include <VersionHelpers.h> | |
| 83 #endif | |
| 84 | |
| 85 #include "atlres.h" | |
| 86 | |
| 87 | |
| 88 /////////////////////////////////////////////////////////////////////////////// | |
| 89 // WTL version number | |
| 90 | |
| 91 #define _WTL_VER 0x1000 // version 10.0 | |
| 92 | |
| 93 | |
| 94 /////////////////////////////////////////////////////////////////////////////// | |
| 95 // Classes in this file: | |
| 96 // | |
| 97 // CMessageFilter | |
| 98 // CIdleHandler | |
| 99 // CMessageLoop | |
| 100 // | |
| 101 // CAppModule | |
| 102 // CServerAppModule | |
| 103 // | |
| 104 // Global functions: | |
| 105 // AtlInitCommonControls() | |
| 106 // AtlGetDefaultGuiFont() | |
| 107 // AtlCreateControlFont() | |
| 108 // AtlCreateBoldFont() | |
| 109 // AtlGetStringPtr() | |
| 110 | |
| 111 | |
| 112 /////////////////////////////////////////////////////////////////////////////// | |
| 113 // Miscellaneous global support | |
| 114 | |
| 115 // define useful macros from winuser.h | |
| 116 #ifndef IS_INTRESOURCE | |
| 117 #define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0) | |
| 118 #endif // IS_INTRESOURCE | |
| 119 | |
| 120 // protect template members from windowsx.h macros | |
| 121 #ifdef _INC_WINDOWSX | |
| 122 #undef SubclassWindow | |
| 123 #endif // _INC_WINDOWSX | |
| 124 | |
| 125 // define useful macros from windowsx.h | |
| 126 #ifndef GET_X_LPARAM | |
| 127 #define GET_X_LPARAM(lParam) ((int)(short)LOWORD(lParam)) | |
| 128 #endif | |
| 129 #ifndef GET_Y_LPARAM | |
| 130 #define GET_Y_LPARAM(lParam) ((int)(short)HIWORD(lParam)) | |
| 131 #endif | |
| 132 | |
| 133 // Dummy structs for compiling with /CLR | |
| 134 #ifdef _MANAGED | |
| 135 __if_not_exists(_IMAGELIST::_IMAGELIST) { struct _IMAGELIST { }; } | |
| 136 __if_not_exists(_TREEITEM::_TREEITEM) { struct _TREEITEM { }; } | |
| 137 __if_not_exists(_PSP::_PSP) { struct _PSP { }; } | |
| 138 #endif | |
| 139 | |
| 140 // Forward declaration for ATL11 fix | |
| 141 #if (_ATL_VER >= 0x0B00) | |
| 142 namespace ATL { HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor); } | |
| 143 #endif | |
| 144 | |
| 145 #ifndef WM_MOUSEHWHEEL | |
| 146 #define WM_MOUSEHWHEEL 0x020E | |
| 147 #endif | |
| 148 | |
| 149 // Used for stack allocations with ATL::CTempBuffer | |
| 150 #ifndef _WTL_STACK_ALLOC_THRESHOLD | |
| 151 #define _WTL_STACK_ALLOC_THRESHOLD 512 | |
| 152 #endif | |
| 153 | |
| 154 | |
| 155 namespace WTL | |
| 156 { | |
| 157 | |
| 158 DECLARE_TRACE_CATEGORY(atlTraceUI) | |
| 159 #ifdef _DEBUG | |
| 160 __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI")); | |
| 161 #endif // _DEBUG | |
| 162 | |
| 163 // Common Controls initialization helper | |
| 164 inline BOOL AtlInitCommonControls(DWORD dwFlags) | |
| 165 { | |
| 166 INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags }; | |
| 167 BOOL bRet = ::InitCommonControlsEx(&iccx); | |
| 168 ATLASSERT(bRet); | |
| 169 return bRet; | |
| 170 } | |
| 171 | |
| 172 // Default GUI font helper - "MS Shell Dlg" stock font | |
| 173 inline HFONT AtlGetDefaultGuiFont() | |
| 174 { | |
| 175 return (HFONT)::GetStockObject(DEFAULT_GUI_FONT); | |
| 176 } | |
| 177 | |
| 178 // Control font helper - default font for controls not in a dialog | |
| 179 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed) | |
| 180 inline HFONT AtlCreateControlFont() | |
| 181 { | |
| 182 LOGFONT lf = {}; | |
| 183 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); | |
| 184 HFONT hFont = ::CreateFontIndirect(&lf); | |
| 185 ATLASSERT(hFont != NULL); | |
| 186 return hFont; | |
| 187 } | |
| 188 | |
| 189 // Bold font helper | |
| 190 // (NOTE: Caller owns the font, and should destroy it when it's no longer needed) | |
| 191 inline HFONT AtlCreateBoldFont(HFONT hFont = NULL) | |
| 192 { | |
| 193 LOGFONT lf = {}; | |
| 194 if(hFont == NULL) | |
| 195 ATLVERIFY(::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0) != FALSE); | |
| 196 else | |
| 197 ATLVERIFY(::GetObject(hFont, sizeof(LOGFONT), &lf) == sizeof(LOGFONT)); | |
| 198 lf.lfWeight = FW_BOLD; | |
| 199 HFONT hFontBold = ::CreateFontIndirect(&lf); | |
| 200 ATLASSERT(hFontBold != NULL); | |
| 201 return hFontBold; | |
| 202 } | |
| 203 | |
| 204 // Resource string pointer | |
| 205 inline LPCWSTR AtlGetStringPtr(UINT uID, int* pch = NULL) | |
| 206 { | |
| 207 LPCWSTR lpstr = NULL; | |
| 208 int nRet = ::LoadStringW(ATL::_AtlBaseModule.GetResourceInstance(), uID, (LPWSTR)&lpstr, 0); | |
| 209 if(pch != NULL) | |
| 210 *pch = nRet; | |
| 211 return lpstr; | |
| 212 } | |
| 213 | |
| 214 | |
| 215 /////////////////////////////////////////////////////////////////////////////// | |
| 216 // RunTimeHelper - helper functions for Windows version and structure sizes | |
| 217 | |
| 218 #ifndef _WTL_NO_RUNTIME_STRUCT_SIZE | |
| 219 | |
| 220 #ifndef _SIZEOF_STRUCT | |
| 221 #define _SIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) | |
| 222 #endif | |
| 223 | |
| 224 #if (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) | |
| 225 #define REBARBANDINFO_V6_SIZE _SIZEOF_STRUCT(REBARBANDINFO, cxHeader) | |
| 226 #endif // (_WIN32_WINNT >= 0x0600) && !defined(REBARBANDINFO_V6_SIZE) | |
| 227 | |
| 228 #if (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) | |
| 229 #define LVGROUP_V5_SIZE _SIZEOF_STRUCT(LVGROUP, uAlign) | |
| 230 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVGROUP_V5_SIZE) | |
| 231 | |
| 232 #if (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) | |
| 233 #define LVTILEINFO_V5_SIZE _SIZEOF_STRUCT(LVTILEINFO, puColumns) | |
| 234 #endif // (_WIN32_WINNT >= 0x0600) && !defined(LVTILEINFO_V5_SIZE) | |
| 235 | |
| 236 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) | |
| 237 #define MCHITTESTINFO_V1_SIZE _SIZEOF_STRUCT(MCHITTESTINFO, st) | |
| 238 #endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) && !defined(MCHITTESTINFO_V1_SIZE) | |
| 239 | |
| 240 #if (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) | |
| 241 #define NONCLIENTMETRICS_V1_SIZE _SIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont) | |
| 242 #endif // (WINVER >= 0x0600) && !defined(NONCLIENTMETRICS_V1_SIZE) | |
| 243 | |
| 244 #ifndef TTTOOLINFO_V2_SIZE | |
| 245 #define TTTOOLINFO_V2_SIZE _SIZEOF_STRUCT(TTTOOLINFO, lParam) | |
| 246 #endif | |
| 247 | |
| 248 #endif // !_WTL_NO_RUNTIME_STRUCT_SIZE | |
| 249 | |
| 250 namespace RunTimeHelper | |
| 251 { | |
| 252 inline bool IsCommCtrl6() | |
| 253 { | |
| 254 DWORD dwMajor = 0, dwMinor = 0; | |
| 255 HRESULT hRet = ATL::AtlGetCommCtrlVersion(&dwMajor, &dwMinor); | |
| 256 return (SUCCEEDED(hRet) && (dwMajor >= 6)); | |
| 257 } | |
| 258 | |
| 259 inline bool IsVista() | |
| 260 { | |
| 261 #ifdef _versionhelpers_H_INCLUDED_ | |
| 262 return ::IsWindowsVistaOrGreater(); | |
| 263 #else // !_versionhelpers_H_INCLUDED_ | |
| 264 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; | |
| 265 BOOL bRet = ::GetVersionEx(&ovi); | |
| 266 return ((bRet != FALSE) && (ovi.dwMajorVersion >= 6)); | |
| 267 #endif // _versionhelpers_H_INCLUDED_ | |
| 268 } | |
| 269 | |
| 270 inline bool IsThemeAvailable() | |
| 271 { | |
| 272 return IsCommCtrl6() && (::IsThemeActive() != FALSE) && (::IsAppThemed() != FALSE); | |
| 273 } | |
| 274 | |
| 275 inline bool IsWin7() | |
| 276 { | |
| 277 #ifdef _versionhelpers_H_INCLUDED_ | |
| 278 return ::IsWindows7OrGreater(); | |
| 279 #else // !_versionhelpers_H_INCLUDED_ | |
| 280 OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; | |
| 281 BOOL bRet = ::GetVersionEx(&ovi); | |
| 282 return ((bRet != FALSE) && ((ovi.dwMajorVersion > 6) || ((ovi.dwMajorVersion == 6) && (ovi.dwMinorVersion >= 1)))); | |
| 283 #endif // _versionhelpers_H_INCLUDED_ | |
| 284 } | |
| 285 | |
| 286 inline bool IsRibbonUIAvailable() | |
| 287 { | |
| 288 static INT iRibbonUI = -1; | |
| 289 | |
| 290 #if defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) | |
| 291 if (iRibbonUI == -1) | |
| 292 { | |
| 293 HMODULE hRibbonDLL = ::LoadLibrary(_T("propsys.dll")); | |
| 294 if (hRibbonDLL != NULL) | |
| 295 { | |
| 296 const GUID CLSID_UIRibbonFramework = { 0x926749fa, 0x2615, 0x4987, { 0x88, 0x45, 0xc3, 0x3e, 0x65, 0xf2, 0xb9, 0x57 } }; | |
| 297 // block - create instance | |
| 298 { | |
| 299 ATL::CComPtr<IUnknown> pIUIFramework; | |
| 300 iRibbonUI = SUCCEEDED(pIUIFramework.CoCreateInstance(CLSID_UIRibbonFramework)) ? 1 : 0; | |
| 301 } | |
| 302 ::FreeLibrary(hRibbonDLL); | |
| 303 } | |
| 304 else | |
| 305 { | |
| 306 iRibbonUI = 0; | |
| 307 } | |
| 308 } | |
| 309 #endif // defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) | |
| 310 | |
| 311 return (iRibbonUI == 1); | |
| 312 } | |
| 313 | |
| 314 inline UINT SizeOf_REBARBANDINFO() | |
| 315 { | |
| 316 UINT uSize = sizeof(REBARBANDINFO); | |
| 317 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
| 318 if(!(IsVista() && IsCommCtrl6())) | |
| 319 uSize = REBARBANDINFO_V6_SIZE; | |
| 320 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
| 321 return uSize; | |
| 322 } | |
| 323 | |
| 324 inline UINT SizeOf_LVGROUP() | |
| 325 { | |
| 326 UINT uSize = sizeof(LVGROUP); | |
| 327 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
| 328 if(!IsVista()) | |
| 329 uSize = LVGROUP_V5_SIZE; | |
| 330 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
| 331 return uSize; | |
| 332 } | |
| 333 | |
| 334 inline UINT SizeOf_LVTILEINFO() | |
| 335 { | |
| 336 UINT uSize = sizeof(LVTILEINFO); | |
| 337 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
| 338 if(!IsVista()) | |
| 339 uSize = LVTILEINFO_V5_SIZE; | |
| 340 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (_WIN32_WINNT >= 0x0600) | |
| 341 return uSize; | |
| 342 } | |
| 343 | |
| 344 inline UINT SizeOf_MCHITTESTINFO() | |
| 345 { | |
| 346 UINT uSize = sizeof(MCHITTESTINFO); | |
| 347 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) | |
| 348 if(!(IsVista() && IsCommCtrl6())) | |
| 349 uSize = MCHITTESTINFO_V1_SIZE; | |
| 350 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN) | |
| 351 return uSize; | |
| 352 } | |
| 353 | |
| 354 inline UINT SizeOf_NONCLIENTMETRICS() | |
| 355 { | |
| 356 UINT uSize = sizeof(NONCLIENTMETRICS); | |
| 357 #if !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) | |
| 358 if(!IsVista()) | |
| 359 uSize = NONCLIENTMETRICS_V1_SIZE; | |
| 360 #endif // !defined(_WTL_NO_RUNTIME_STRUCT_SIZE) && (WINVER >= 0x0600) | |
| 361 return uSize; | |
| 362 } | |
| 363 | |
| 364 inline UINT SizeOf_TOOLINFO() | |
| 365 { | |
| 366 UINT uSize = sizeof(TOOLINFO); | |
| 367 #ifndef _WTL_NO_RUNTIME_STRUCT_SIZE | |
| 368 if(!IsVista()) | |
| 369 uSize = TTTOOLINFO_V2_SIZE; | |
| 370 #endif | |
| 371 return uSize; | |
| 372 } | |
| 373 } // namespace RunTimeHelper | |
| 374 | |
| 375 | |
| 376 /////////////////////////////////////////////////////////////////////////////// | |
| 377 // ModuleHelper - helper functions for ATL (deprecated) | |
| 378 | |
| 379 namespace ModuleHelper | |
| 380 { | |
| 381 inline HINSTANCE GetModuleInstance() | |
| 382 { | |
| 383 return ATL::_AtlBaseModule.GetModuleInstance(); | |
| 384 } | |
| 385 | |
| 386 inline HINSTANCE GetResourceInstance() | |
| 387 { | |
| 388 return ATL::_AtlBaseModule.GetResourceInstance(); | |
| 389 } | |
| 390 | |
| 391 inline void AddCreateWndData(ATL::_AtlCreateWndData* pData, void* pObject) | |
| 392 { | |
| 393 ATL::_AtlWinModule.AddCreateWndData(pData, pObject); | |
| 394 } | |
| 395 | |
| 396 inline void* ExtractCreateWndData() | |
| 397 { | |
| 398 return ATL::_AtlWinModule.ExtractCreateWndData(); | |
| 399 } | |
| 400 } // namespace ModuleHelper | |
| 401 | |
| 402 | |
| 403 /////////////////////////////////////////////////////////////////////////////// | |
| 404 // SecureHelper - WTL10 requires use of secure functions | |
| 405 // these are here only for compatibility with existing projects | |
| 406 | |
| 407 namespace SecureHelper | |
| 408 { | |
| 409 inline void strcpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) | |
| 410 { | |
| 411 ATL::Checked::strcpy_s(lpstrDest, cchDest, lpstrSrc); | |
| 412 } | |
| 413 | |
| 414 inline void strcpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) | |
| 415 { | |
| 416 ATL::Checked::wcscpy_s(lpstrDest, cchDest, lpstrSrc); | |
| 417 } | |
| 418 | |
| 419 inline void strcpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) | |
| 420 { | |
| 421 #ifdef _UNICODE | |
| 422 strcpyW_x(lpstrDest, cchDest, lpstrSrc); | |
| 423 #else | |
| 424 strcpyA_x(lpstrDest, cchDest, lpstrSrc); | |
| 425 #endif | |
| 426 } | |
| 427 | |
| 428 inline errno_t strncpyA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc, size_t cchCount) | |
| 429 { | |
| 430 return ATL::Checked::strncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); | |
| 431 } | |
| 432 | |
| 433 inline errno_t strncpyW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc, size_t cchCount) | |
| 434 { | |
| 435 return ATL::Checked::wcsncpy_s(lpstrDest, cchDest, lpstrSrc, cchCount); | |
| 436 } | |
| 437 | |
| 438 inline errno_t strncpy_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc, size_t cchCount) | |
| 439 { | |
| 440 #ifdef _UNICODE | |
| 441 return strncpyW_x(lpstrDest, cchDest, lpstrSrc, cchCount); | |
| 442 #else | |
| 443 return strncpyA_x(lpstrDest, cchDest, lpstrSrc, cchCount); | |
| 444 #endif | |
| 445 } | |
| 446 | |
| 447 inline void strcatA_x(char* lpstrDest, size_t cchDest, const char* lpstrSrc) | |
| 448 { | |
| 449 ATL::Checked::strcat_s(lpstrDest, cchDest, lpstrSrc); | |
| 450 } | |
| 451 | |
| 452 inline void strcatW_x(wchar_t* lpstrDest, size_t cchDest, const wchar_t* lpstrSrc) | |
| 453 { | |
| 454 ATL::Checked::wcscat_s(lpstrDest, cchDest, lpstrSrc); | |
| 455 } | |
| 456 | |
| 457 inline void strcat_x(LPTSTR lpstrDest, size_t cchDest, LPCTSTR lpstrSrc) | |
| 458 { | |
| 459 #ifdef _UNICODE | |
| 460 strcatW_x(lpstrDest, cchDest, lpstrSrc); | |
| 461 #else | |
| 462 strcatA_x(lpstrDest, cchDest, lpstrSrc); | |
| 463 #endif | |
| 464 } | |
| 465 | |
| 466 inline void memcpy_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) | |
| 467 { | |
| 468 ATL::Checked::memcpy_s(pDest, cbDest, pSrc, cbSrc); | |
| 469 } | |
| 470 | |
| 471 inline void memmove_x(void* pDest, size_t cbDest, const void* pSrc, size_t cbSrc) | |
| 472 { | |
| 473 ATL::Checked::memmove_s(pDest, cbDest, pSrc, cbSrc); | |
| 474 } | |
| 475 | |
| 476 inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) | |
| 477 { | |
| 478 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); | |
| 479 } | |
| 480 | |
| 481 inline int wvsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args) | |
| 482 { | |
| 483 return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args); | |
| 484 } | |
| 485 | |
| 486 inline int sprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) | |
| 487 { | |
| 488 va_list args; | |
| 489 va_start(args, lpstrFormat); | |
| 490 int nRes = vsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); | |
| 491 va_end(args); | |
| 492 return nRes; | |
| 493 } | |
| 494 | |
| 495 inline int wsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, ...) | |
| 496 { | |
| 497 va_list args; | |
| 498 va_start(args, lpstrFormat); | |
| 499 int nRes = wvsprintf_x(lpstrBuff, cchBuff, lpstrFormat, args); | |
| 500 va_end(args); | |
| 501 return nRes; | |
| 502 } | |
| 503 } // namespace SecureHelper | |
| 504 | |
| 505 | |
| 506 /////////////////////////////////////////////////////////////////////////////// | |
| 507 // MinCrtHelper - WTL10 doesn't support _ATL_MIN_CRT, | |
| 508 // these are here only for compatibility with existing projects | |
| 509 | |
| 510 namespace MinCrtHelper | |
| 511 { | |
| 512 inline int _isspace(TCHAR ch) | |
| 513 { | |
| 514 return _istspace(ch); | |
| 515 } | |
| 516 | |
| 517 inline int _isdigit(TCHAR ch) | |
| 518 { | |
| 519 return _istdigit(ch); | |
| 520 } | |
| 521 | |
| 522 inline int _atoi(LPCTSTR str) | |
| 523 { | |
| 524 return _ttoi(str); | |
| 525 } | |
| 526 | |
| 527 inline LPCTSTR _strrchr(LPCTSTR str, TCHAR ch) | |
| 528 { | |
| 529 return _tcsrchr(str, ch); | |
| 530 } | |
| 531 | |
| 532 inline LPTSTR _strrchr(LPTSTR str, TCHAR ch) | |
| 533 { | |
| 534 return _tcsrchr(str, ch); | |
| 535 } | |
| 536 } // namespace MinCrtHelper | |
| 537 | |
| 538 | |
| 539 /////////////////////////////////////////////////////////////////////////////// | |
| 540 // GenericWndClass - generic window class usable for subclassing | |
| 541 | |
| 542 // Use in dialog templates to specify a placeholder to be subclassed | |
| 543 // Specify as a custom control with class name WTL_GenericWindow | |
| 544 // Call Rregister() before creating dialog (for example, in WinMain) | |
| 545 namespace GenericWndClass | |
| 546 { | |
| 547 inline LPCTSTR GetName() | |
| 548 { | |
| 549 return _T("WTL_GenericWindow"); | |
| 550 } | |
| 551 | |
| 552 inline ATOM Register() | |
| 553 { | |
| 554 WNDCLASSEX wc = { sizeof(WNDCLASSEX) }; | |
| 555 wc.lpfnWndProc = ::DefWindowProc; | |
| 556 wc.hInstance = ModuleHelper::GetModuleInstance(); | |
| 557 wc.hCursor = ::LoadCursor(NULL, IDC_ARROW); | |
| 558 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); | |
| 559 wc.lpszClassName = GetName(); | |
| 560 ATOM atom = ::RegisterClassEx(&wc); | |
| 561 ATLASSERT(atom != 0); | |
| 562 return atom; | |
| 563 } | |
| 564 | |
| 565 inline BOOL Unregister() // only needed for DLLs or tmp use | |
| 566 { | |
| 567 return ::UnregisterClass(GetName(), ModuleHelper::GetModuleInstance()); | |
| 568 } | |
| 569 } // namespace GenericWndClass | |
| 570 | |
| 571 | |
| 572 /////////////////////////////////////////////////////////////////////////////// | |
| 573 // CMessageFilter - Interface for message filter support | |
| 574 | |
| 575 class CMessageFilter | |
| 576 { | |
| 577 public: | |
| 578 virtual BOOL PreTranslateMessage(MSG* pMsg) = 0; | |
| 579 }; | |
| 580 | |
| 581 | |
| 582 /////////////////////////////////////////////////////////////////////////////// | |
| 583 // CIdleHandler - Interface for idle processing | |
| 584 | |
| 585 class CIdleHandler | |
| 586 { | |
| 587 public: | |
| 588 virtual BOOL OnIdle() = 0; | |
| 589 }; | |
| 590 | |
| 591 | |
| 592 /////////////////////////////////////////////////////////////////////////////// | |
| 593 // CMessageLoop - message loop implementation | |
| 594 | |
| 595 class CMessageLoop | |
| 596 { | |
| 597 public: | |
| 598 ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter; | |
| 599 ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler; | |
| 600 MSG m_msg; | |
| 601 | |
| 602 CMessageLoop() | |
| 603 { } | |
| 604 | |
| 605 virtual ~CMessageLoop() | |
| 606 { } | |
| 607 | |
| 608 // Message filter operations | |
| 609 BOOL AddMessageFilter(CMessageFilter* pMessageFilter) | |
| 610 { | |
| 611 return m_aMsgFilter.Add(pMessageFilter); | |
| 612 } | |
| 613 | |
| 614 BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter) | |
| 615 { | |
| 616 return m_aMsgFilter.Remove(pMessageFilter); | |
| 617 } | |
| 618 | |
| 619 // Idle handler operations | |
| 620 BOOL AddIdleHandler(CIdleHandler* pIdleHandler) | |
| 621 { | |
| 622 return m_aIdleHandler.Add(pIdleHandler); | |
| 623 } | |
| 624 | |
| 625 BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler) | |
| 626 { | |
| 627 return m_aIdleHandler.Remove(pIdleHandler); | |
| 628 } | |
| 629 | |
| 630 // message loop | |
| 631 int Run() | |
| 632 { | |
| 633 BOOL bDoIdle = TRUE; | |
| 634 int nIdleCount = 0; | |
| 635 BOOL bRet; | |
| 636 | |
| 637 for(;;) | |
| 638 { | |
| 639 while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE)) | |
| 640 { | |
| 641 if(!OnIdle(nIdleCount++)) | |
| 642 bDoIdle = FALSE; | |
| 643 } | |
| 644 | |
| 645 bRet = ::GetMessage(&m_msg, NULL, 0, 0); | |
| 646 | |
| 647 if(bRet == -1) | |
| 648 { | |
| 649 ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n")); | |
| 650 continue; // error, don't process | |
| 651 } | |
| 652 else if(!bRet) | |
| 653 { | |
| 654 ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n")); | |
| 655 break; // WM_QUIT, exit message loop | |
| 656 } | |
| 657 | |
| 658 if(!PreTranslateMessage(&m_msg)) | |
| 659 { | |
| 660 ::TranslateMessage(&m_msg); | |
| 661 ::DispatchMessage(&m_msg); | |
| 662 } | |
| 663 | |
| 664 if(IsIdleMessage(&m_msg)) | |
| 665 { | |
| 666 bDoIdle = TRUE; | |
| 667 nIdleCount = 0; | |
| 668 } | |
| 669 } | |
| 670 | |
| 671 return (int)m_msg.wParam; | |
| 672 } | |
| 673 | |
| 674 static BOOL IsIdleMessage(MSG* pMsg) | |
| 675 { | |
| 676 // These messages should NOT cause idle processing | |
| 677 switch(pMsg->message) | |
| 678 { | |
| 679 case WM_MOUSEMOVE: | |
| 680 case WM_NCMOUSEMOVE: | |
| 681 case WM_PAINT: | |
| 682 case 0x0118: // WM_SYSTIMER (caret blink) | |
| 683 return FALSE; | |
| 684 } | |
| 685 | |
| 686 return TRUE; | |
| 687 } | |
| 688 | |
| 689 // Overrideables | |
| 690 // Override to change message filtering | |
| 691 virtual BOOL PreTranslateMessage(MSG* pMsg) | |
| 692 { | |
| 693 // loop backwards | |
| 694 for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--) | |
| 695 { | |
| 696 CMessageFilter* pMessageFilter = m_aMsgFilter[i]; | |
| 697 if((pMessageFilter != NULL) && pMessageFilter->PreTranslateMessage(pMsg)) | |
| 698 return TRUE; | |
| 699 } | |
| 700 return FALSE; // not translated | |
| 701 } | |
| 702 | |
| 703 // override to change idle processing | |
| 704 virtual BOOL OnIdle(int /*nIdleCount*/) | |
| 705 { | |
| 706 for(int i = 0; i < m_aIdleHandler.GetSize(); i++) | |
| 707 { | |
| 708 CIdleHandler* pIdleHandler = m_aIdleHandler[i]; | |
| 709 if(pIdleHandler != NULL) | |
| 710 pIdleHandler->OnIdle(); | |
| 711 } | |
| 712 return FALSE; // don't continue | |
| 713 } | |
| 714 }; | |
| 715 | |
| 716 | |
| 717 /////////////////////////////////////////////////////////////////////////////// | |
| 718 // CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock | |
| 719 // internal classes to manage critical sections for ATL (deprecated) | |
| 720 | |
| 721 class CStaticDataInitCriticalSectionLock | |
| 722 { | |
| 723 public: | |
| 724 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock; | |
| 725 | |
| 726 CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false) | |
| 727 { } | |
| 728 | |
| 729 HRESULT Lock() | |
| 730 { | |
| 731 return m_cslock.Lock(); | |
| 732 } | |
| 733 | |
| 734 void Unlock() | |
| 735 { | |
| 736 m_cslock.Unlock(); | |
| 737 } | |
| 738 }; | |
| 739 | |
| 740 | |
| 741 class CWindowCreateCriticalSectionLock | |
| 742 { | |
| 743 public: | |
| 744 ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock; | |
| 745 | |
| 746 CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false) | |
| 747 { } | |
| 748 | |
| 749 HRESULT Lock() | |
| 750 { | |
| 751 return m_cslock.Lock(); | |
| 752 } | |
| 753 | |
| 754 void Unlock() | |
| 755 { | |
| 756 m_cslock.Unlock(); | |
| 757 } | |
| 758 }; | |
| 759 | |
| 760 | |
| 761 /////////////////////////////////////////////////////////////////////////////// | |
| 762 // CAppModule - module class for an application | |
| 763 | |
| 764 #if (_MSC_VER == 1400) // VS2005 | |
| 765 #pragma warning(push) | |
| 766 #pragma warning(disable : 4244) | |
| 767 #pragma warning(disable : 4312) | |
| 768 #endif | |
| 769 | |
| 770 class CAppModule : public ATL::CComModule | |
| 771 { | |
| 772 public: | |
| 773 DWORD m_dwMainThreadID; | |
| 774 ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap; | |
| 775 ATL::CSimpleArray<HWND>* m_pSettingChangeNotify; | |
| 776 | |
| 777 // Overrides of CComModule::Init and Term | |
| 778 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) | |
| 779 { | |
| 780 HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID); | |
| 781 if(FAILED(hRet)) | |
| 782 return hRet; | |
| 783 | |
| 784 m_dwMainThreadID = ::GetCurrentThreadId(); | |
| 785 typedef ATL::CSimpleMap<DWORD, CMessageLoop*> _mapClass; | |
| 786 m_pMsgLoopMap = NULL; | |
| 787 ATLTRY(m_pMsgLoopMap = new _mapClass); | |
| 788 if(m_pMsgLoopMap == NULL) | |
| 789 return E_OUTOFMEMORY; | |
| 790 m_pSettingChangeNotify = NULL; | |
| 791 | |
| 792 return hRet; | |
| 793 } | |
| 794 | |
| 795 void Term() | |
| 796 { | |
| 797 TermSettingChangeNotify(); | |
| 798 delete m_pMsgLoopMap; | |
| 799 CComModule::Term(); | |
| 800 } | |
| 801 | |
| 802 // Message loop map methods | |
| 803 BOOL AddMessageLoop(CMessageLoop* pMsgLoop) | |
| 804 { | |
| 805 CStaticDataInitCriticalSectionLock lock; | |
| 806 if(FAILED(lock.Lock())) | |
| 807 { | |
| 808 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n")); | |
| 809 ATLASSERT(FALSE); | |
| 810 return FALSE; | |
| 811 } | |
| 812 | |
| 813 ATLASSERT(pMsgLoop != NULL); | |
| 814 ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL); // not in map yet | |
| 815 | |
| 816 BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop); | |
| 817 | |
| 818 lock.Unlock(); | |
| 819 | |
| 820 return bRet; | |
| 821 } | |
| 822 | |
| 823 BOOL RemoveMessageLoop() | |
| 824 { | |
| 825 CStaticDataInitCriticalSectionLock lock; | |
| 826 if(FAILED(lock.Lock())) | |
| 827 { | |
| 828 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n")); | |
| 829 ATLASSERT(FALSE); | |
| 830 return FALSE; | |
| 831 } | |
| 832 | |
| 833 BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId()); | |
| 834 | |
| 835 lock.Unlock(); | |
| 836 | |
| 837 return bRet; | |
| 838 } | |
| 839 | |
| 840 CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const | |
| 841 { | |
| 842 CStaticDataInitCriticalSectionLock lock; | |
| 843 if(FAILED(lock.Lock())) | |
| 844 { | |
| 845 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n")); | |
| 846 ATLASSERT(FALSE); | |
| 847 return NULL; | |
| 848 } | |
| 849 | |
| 850 CMessageLoop* pLoop = m_pMsgLoopMap->Lookup(dwThreadID); | |
| 851 | |
| 852 lock.Unlock(); | |
| 853 | |
| 854 return pLoop; | |
| 855 } | |
| 856 | |
| 857 // Setting change notify methods | |
| 858 // Note: Call this from the main thread for MSDI apps | |
| 859 BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc) | |
| 860 { | |
| 861 CStaticDataInitCriticalSectionLock lock; | |
| 862 if(FAILED(lock.Lock())) | |
| 863 { | |
| 864 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n")); | |
| 865 ATLASSERT(FALSE); | |
| 866 return FALSE; | |
| 867 } | |
| 868 | |
| 869 if(m_pSettingChangeNotify == NULL) | |
| 870 { | |
| 871 typedef ATL::CSimpleArray<HWND> _notifyClass; | |
| 872 ATLTRY(m_pSettingChangeNotify = new _notifyClass); | |
| 873 ATLASSERT(m_pSettingChangeNotify != NULL); | |
| 874 } | |
| 875 | |
| 876 BOOL bRet = (m_pSettingChangeNotify != NULL); | |
| 877 if(bRet && (m_pSettingChangeNotify->GetSize() == 0)) | |
| 878 { | |
| 879 // init everything | |
| 880 _ATL_EMPTY_DLGTEMPLATE templ; | |
| 881 HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc); | |
| 882 ATLASSERT(::IsWindow(hNtfWnd)); | |
| 883 if(::IsWindow(hNtfWnd)) | |
| 884 { | |
| 885 ::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this); | |
| 886 bRet = m_pSettingChangeNotify->Add(hNtfWnd); | |
| 887 } | |
| 888 else | |
| 889 { | |
| 890 bRet = FALSE; | |
| 891 } | |
| 892 } | |
| 893 | |
| 894 lock.Unlock(); | |
| 895 | |
| 896 return bRet; | |
| 897 } | |
| 898 | |
| 899 void TermSettingChangeNotify() | |
| 900 { | |
| 901 CStaticDataInitCriticalSectionLock lock; | |
| 902 if(FAILED(lock.Lock())) | |
| 903 { | |
| 904 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n")); | |
| 905 ATLASSERT(FALSE); | |
| 906 return; | |
| 907 } | |
| 908 | |
| 909 if((m_pSettingChangeNotify != NULL) && (m_pSettingChangeNotify->GetSize() > 0)) | |
| 910 ::DestroyWindow((*m_pSettingChangeNotify)[0]); | |
| 911 delete m_pSettingChangeNotify; | |
| 912 m_pSettingChangeNotify = NULL; | |
| 913 | |
| 914 lock.Unlock(); | |
| 915 } | |
| 916 | |
| 917 BOOL AddSettingChangeNotify(HWND hWnd) | |
| 918 { | |
| 919 CStaticDataInitCriticalSectionLock lock; | |
| 920 if(FAILED(lock.Lock())) | |
| 921 { | |
| 922 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n")); | |
| 923 ATLASSERT(FALSE); | |
| 924 return FALSE; | |
| 925 } | |
| 926 | |
| 927 ATLASSERT(::IsWindow(hWnd)); | |
| 928 BOOL bRet = FALSE; | |
| 929 if(InitSettingChangeNotify() != FALSE) | |
| 930 bRet = m_pSettingChangeNotify->Add(hWnd); | |
| 931 | |
| 932 lock.Unlock(); | |
| 933 | |
| 934 return bRet; | |
| 935 } | |
| 936 | |
| 937 BOOL RemoveSettingChangeNotify(HWND hWnd) | |
| 938 { | |
| 939 CStaticDataInitCriticalSectionLock lock; | |
| 940 if(FAILED(lock.Lock())) | |
| 941 { | |
| 942 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n")); | |
| 943 ATLASSERT(FALSE); | |
| 944 return FALSE; | |
| 945 } | |
| 946 | |
| 947 BOOL bRet = FALSE; | |
| 948 if(m_pSettingChangeNotify != NULL) | |
| 949 bRet = m_pSettingChangeNotify->Remove(hWnd); | |
| 950 | |
| 951 lock.Unlock(); | |
| 952 | |
| 953 return bRet; | |
| 954 } | |
| 955 | |
| 956 // Implementation - setting change notify dialog template and dialog procedure | |
| 957 struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE | |
| 958 { | |
| 959 _ATL_EMPTY_DLGTEMPLATE() | |
| 960 { | |
| 961 memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE)); | |
| 962 style = WS_POPUP; | |
| 963 } | |
| 964 WORD wMenu, wClass, wTitle; | |
| 965 }; | |
| 966 | |
| 967 static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
| 968 { | |
| 969 if(uMsg == WM_SETTINGCHANGE) | |
| 970 { | |
| 971 CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); | |
| 972 ATLASSERT(pModule != NULL); | |
| 973 ATLASSERT(pModule->m_pSettingChangeNotify != NULL); | |
| 974 const UINT uTimeout = 1500; // ms | |
| 975 for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++) | |
| 976 ::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL); | |
| 977 | |
| 978 return TRUE; | |
| 979 } | |
| 980 | |
| 981 return FALSE; | |
| 982 } | |
| 983 }; | |
| 984 | |
| 985 #if (_MSC_VER == 1400) // VS2005 | |
| 986 #pragma warning(pop) | |
| 987 #endif | |
| 988 | |
| 989 | |
| 990 /////////////////////////////////////////////////////////////////////////////// | |
| 991 // CServerAppModule - module class for a COM server application | |
| 992 | |
| 993 class CServerAppModule : public CAppModule | |
| 994 { | |
| 995 public: | |
| 996 HANDLE m_hEventShutdown; | |
| 997 bool m_bActivity; | |
| 998 DWORD m_dwTimeOut; | |
| 999 DWORD m_dwPause; | |
| 1000 | |
| 1001 // Override of CAppModule::Init | |
| 1002 HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL) | |
| 1003 { | |
| 1004 m_dwTimeOut = 5000; | |
| 1005 m_dwPause = 1000; | |
| 1006 return CAppModule::Init(pObjMap, hInstance, pLibID); | |
| 1007 } | |
| 1008 | |
| 1009 void Term() | |
| 1010 { | |
| 1011 if((m_hEventShutdown != NULL) && ::CloseHandle(m_hEventShutdown)) | |
| 1012 m_hEventShutdown = NULL; | |
| 1013 CAppModule::Term(); | |
| 1014 } | |
| 1015 | |
| 1016 // COM Server methods | |
| 1017 LONG Unlock() throw() | |
| 1018 { | |
| 1019 LONG lRet = CComModule::Unlock(); | |
| 1020 if(lRet == 0) | |
| 1021 { | |
| 1022 m_bActivity = true; | |
| 1023 ::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero | |
| 1024 } | |
| 1025 return lRet; | |
| 1026 } | |
| 1027 | |
| 1028 void MonitorShutdown() | |
| 1029 { | |
| 1030 for(;;) | |
| 1031 { | |
| 1032 ::WaitForSingleObject(m_hEventShutdown, INFINITE); | |
| 1033 DWORD dwWait = 0; | |
| 1034 do | |
| 1035 { | |
| 1036 m_bActivity = false; | |
| 1037 dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut); | |
| 1038 } | |
| 1039 while(dwWait == WAIT_OBJECT_0); | |
| 1040 // timed out | |
| 1041 if(!m_bActivity && (m_nLockCnt == 0)) // if no activity let's really bail | |
| 1042 { | |
| 1043 #if defined(_WIN32_DCOM) && defined(_ATL_FREE_THREADED) | |
| 1044 ::CoSuspendClassObjects(); | |
| 1045 if(!m_bActivity && (m_nLockCnt == 0)) | |
| 1046 #endif | |
| 1047 break; | |
| 1048 } | |
| 1049 } | |
| 1050 // This handle should be valid now. If it isn't, | |
| 1051 // check if _Module.Term was called first (it shouldn't) | |
| 1052 if(::CloseHandle(m_hEventShutdown)) | |
| 1053 m_hEventShutdown = NULL; | |
| 1054 ::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0); | |
| 1055 } | |
| 1056 | |
| 1057 bool StartMonitor() | |
| 1058 { | |
| 1059 m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL); | |
| 1060 if(m_hEventShutdown == NULL) | |
| 1061 return false; | |
| 1062 DWORD dwThreadID = 0; | |
| 1063 #ifdef _MT | |
| 1064 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID); | |
| 1065 #else | |
| 1066 HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID); | |
| 1067 #endif | |
| 1068 bool bRet = (hThread != NULL); | |
| 1069 if(bRet) | |
| 1070 ::CloseHandle(hThread); | |
| 1071 return bRet; | |
| 1072 } | |
| 1073 | |
| 1074 static DWORD WINAPI MonitorProc(void* pv) | |
| 1075 { | |
| 1076 CServerAppModule* p = (CServerAppModule*)pv; | |
| 1077 p->MonitorShutdown(); | |
| 1078 return 0; | |
| 1079 } | |
| 1080 }; | |
| 1081 | |
| 1082 | |
| 1083 /////////////////////////////////////////////////////////////////////////////// | |
| 1084 // CRegKeyEx - not used any more, here only for compatibility with old projects | |
| 1085 | |
| 1086 typedef ATL::CRegKey CRegKeyEx; | |
| 1087 | |
| 1088 } // namespace WTL | |
| 1089 | |
| 1090 | |
| 1091 /////////////////////////////////////////////////////////////////////////////// | |
| 1092 // CString forward reference (enables CString use in atluser.h and atlgdi.h) | |
| 1093 | |
| 1094 #if (defined(_WTL_USE_CSTRING) || defined(_WTL_FORWARD_DECLARE_CSTRING)) && !defined(__ATLSTR_H__) | |
| 1095 #include <atlstr.h> | |
| 1096 #endif | |
| 1097 | |
| 1098 // CString namespace | |
| 1099 #define _CSTRING_NS ATL | |
| 1100 | |
| 1101 // Type classes namespace | |
| 1102 #define _WTYPES_NS | |
| 1103 | |
| 1104 | |
| 1105 /////////////////////////////////////////////////////////////////////////////// | |
| 1106 // General DLL version helpers (removed in ATL11) | |
| 1107 | |
| 1108 #if (_ATL_VER >= 0x0B00) | |
| 1109 | |
| 1110 namespace ATL | |
| 1111 { | |
| 1112 | |
| 1113 inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo) | |
| 1114 { | |
| 1115 ATLASSERT(pDllVersionInfo != NULL); | |
| 1116 if(pDllVersionInfo == NULL) | |
| 1117 return E_INVALIDARG; | |
| 1118 | |
| 1119 // We must get this function explicitly because some DLLs don't implement it. | |
| 1120 DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion"); | |
| 1121 if(pfnDllGetVersion == NULL) | |
| 1122 return E_NOTIMPL; | |
| 1123 | |
| 1124 return (*pfnDllGetVersion)(pDllVersionInfo); | |
| 1125 } | |
| 1126 | |
| 1127 inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo) | |
| 1128 { | |
| 1129 HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName); | |
| 1130 if(hInstDLL == NULL) | |
| 1131 return E_FAIL; | |
| 1132 HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo); | |
| 1133 ::FreeLibrary(hInstDLL); | |
| 1134 return hRet; | |
| 1135 } | |
| 1136 | |
| 1137 // Common Control Versions: | |
| 1138 // Win95/WinNT 4.0 maj=4 min=00 | |
| 1139 // IE 3.x maj=4 min=70 | |
| 1140 // IE 4.0 maj=4 min=71 | |
| 1141 inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) | |
| 1142 { | |
| 1143 ATLASSERT((pdwMajor != NULL) && (pdwMinor != NULL)); | |
| 1144 if((pdwMajor == NULL) || (pdwMinor == NULL)) | |
| 1145 return E_INVALIDARG; | |
| 1146 | |
| 1147 DLLVERSIONINFO dvi; | |
| 1148 ::ZeroMemory(&dvi, sizeof(dvi)); | |
| 1149 dvi.cbSize = sizeof(dvi); | |
| 1150 HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi); | |
| 1151 | |
| 1152 if(SUCCEEDED(hRet)) | |
| 1153 { | |
| 1154 *pdwMajor = dvi.dwMajorVersion; | |
| 1155 *pdwMinor = dvi.dwMinorVersion; | |
| 1156 } | |
| 1157 else if(hRet == E_NOTIMPL) | |
| 1158 { | |
| 1159 // If DllGetVersion is not there, then the DLL is a version | |
| 1160 // previous to the one shipped with IE 3.x | |
| 1161 *pdwMajor = 4; | |
| 1162 *pdwMinor = 0; | |
| 1163 hRet = S_OK; | |
| 1164 } | |
| 1165 | |
| 1166 return hRet; | |
| 1167 } | |
| 1168 | |
| 1169 // Shell Versions: | |
| 1170 // Win95/WinNT 4.0 maj=4 min=00 | |
| 1171 // IE 3.x, IE 4.0 without Web Integrated Desktop maj=4 min=00 | |
| 1172 // IE 4.0 with Web Integrated Desktop maj=4 min=71 | |
| 1173 // IE 4.01 with Web Integrated Desktop maj=4 min=72 | |
| 1174 inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor) | |
| 1175 { | |
| 1176 ATLASSERT((pdwMajor != NULL) && (pdwMinor != NULL)); | |
| 1177 if((pdwMajor == NULL) || (pdwMinor == NULL)) | |
| 1178 return E_INVALIDARG; | |
| 1179 | |
| 1180 DLLVERSIONINFO dvi; | |
| 1181 ::ZeroMemory(&dvi, sizeof(dvi)); | |
| 1182 dvi.cbSize = sizeof(dvi); | |
| 1183 HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi); | |
| 1184 | |
| 1185 if(SUCCEEDED(hRet)) | |
| 1186 { | |
| 1187 *pdwMajor = dvi.dwMajorVersion; | |
| 1188 *pdwMinor = dvi.dwMinorVersion; | |
| 1189 } | |
| 1190 else if(hRet == E_NOTIMPL) | |
| 1191 { | |
| 1192 // If DllGetVersion is not there, then the DLL is a version | |
| 1193 // previous to the one shipped with IE 4.x | |
| 1194 *pdwMajor = 4; | |
| 1195 *pdwMinor = 0; | |
| 1196 hRet = S_OK; | |
| 1197 } | |
| 1198 | |
| 1199 return hRet; | |
| 1200 } | |
| 1201 | |
| 1202 } // namespace ATL | |
| 1203 | |
| 1204 #endif // (_ATL_VER >= 0x0B00) | |
| 1205 | |
| 1206 | |
| 1207 // These are always included | |
| 1208 #include "atlwinx.h" | |
| 1209 #include "atluser.h" | |
| 1210 #include "atlgdi.h" | |
| 1211 | |
| 1212 #ifndef _WTL_NO_AUTOMATIC_NAMESPACE | |
| 1213 using namespace WTL; | |
| 1214 #endif // !_WTL_NO_AUTOMATIC_NAMESPACE | |
| 1215 | |
| 1216 #endif // __ATLAPP_H__ |
