|
1
|
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__
|