yum-archive/TaSTT-Whisper

High-performance GPGPU inference of OpenAI's Whisper automatic speech recognition (ASR) model

git clone https://git.yummers.dev/yum-archive/TaSTT-Whisper

KonstantinSource codes8c4603c

master
30.3 KiB1225 linesraw
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 doesn't support _ATL_NO_COMMODULE
28#endif
29
30#ifdef _ATL_NO_WIN_SUPPORT
31	#error WTL doesn't support _ATL_NO_WIN_SUPPORT
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
155namespace WTL
156{
157
158DECLARE_TRACE_CATEGORY(atlTraceUI)
159#ifdef _DEBUG
160  __declspec(selectany) ATL::CTraceCategory atlTraceUI(_T("atlTraceUI"));
161#endif // _DEBUG
162
163// Common Controls initialization helper
164inline 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
173inline 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)
180inline 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)
191inline 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
205inline 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
250namespace 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
379namespace 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
407namespace 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
510namespace 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)
545namespace 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
575class ATL_NO_VTABLE CMessageFilter
576{
577public:
578	virtual BOOL PreTranslateMessage(MSG* pMsg) = 0;
579};
580
581
582///////////////////////////////////////////////////////////////////////////////
583// CIdleHandler - Interface for idle processing
584
585class ATL_NO_VTABLE CIdleHandler
586{
587public:
588	virtual BOOL OnIdle() = 0;
589};
590
591
592///////////////////////////////////////////////////////////////////////////////
593// CMessageLoop - message loop implementation
594
595class CMessageLoop
596{
597public:
598	ATL::CSimpleArray<CMessageFilter*> m_aMsgFilter;
599	ATL::CSimpleArray<CIdleHandler*> m_aIdleHandler;
600	MSG m_msg;
601
602	CMessageLoop()
603	{
604		memset(&m_msg, 0, sizeof(m_msg));
605	}
606
607	virtual ~CMessageLoop()
608	{ }
609
610// Message filter operations
611	BOOL AddMessageFilter(CMessageFilter* pMessageFilter)
612	{
613		return m_aMsgFilter.Add(pMessageFilter);
614	}
615
616	BOOL RemoveMessageFilter(CMessageFilter* pMessageFilter)
617	{
618		return m_aMsgFilter.Remove(pMessageFilter);
619	}
620
621// Idle handler operations
622	BOOL AddIdleHandler(CIdleHandler* pIdleHandler)
623	{
624		return m_aIdleHandler.Add(pIdleHandler);
625	}
626
627	BOOL RemoveIdleHandler(CIdleHandler* pIdleHandler)
628	{
629		return m_aIdleHandler.Remove(pIdleHandler);
630	}
631
632// message loop
633	int Run()
634	{
635		BOOL bDoIdle = TRUE;
636		int nIdleCount = 0;
637		BOOL bRet = FALSE;
638
639		for(;;)
640		{
641			while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
642			{
643				if(!OnIdle(nIdleCount++))
644					bDoIdle = FALSE;
645			}
646
647			bRet = ::GetMessage(&m_msg, NULL, 0, 0);
648
649			if(bRet == -1)
650			{
651				ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
652				continue;   // error, don't process
653			}
654			else if(!bRet)
655			{
656				ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
657				break;   // WM_QUIT, exit message loop
658			}
659
660			if(!PreTranslateMessage(&m_msg))
661			{
662				::TranslateMessage(&m_msg);
663				::DispatchMessage(&m_msg);
664			}
665
666			if(IsIdleMessage(&m_msg))
667			{
668				bDoIdle = TRUE;
669				nIdleCount = 0;
670			}
671		}
672
673		return (int)m_msg.wParam;
674	}
675
676// Overrideables
677	// Override to change message filtering
678	virtual BOOL PreTranslateMessage(MSG* pMsg)
679	{
680		// loop backwards
681		for(int i = m_aMsgFilter.GetSize() - 1; i >= 0; i--)
682		{
683			CMessageFilter* pMessageFilter = m_aMsgFilter[i];
684			if((pMessageFilter != NULL) && pMessageFilter->PreTranslateMessage(pMsg))
685				return TRUE;
686		}
687		return FALSE;   // not translated
688	}
689
690	// override to change idle processing
691	virtual BOOL OnIdle(int /*nIdleCount*/)
692	{
693		for(int i = 0; i < m_aIdleHandler.GetSize(); i++)
694		{
695			CIdleHandler* pIdleHandler = m_aIdleHandler[i];
696			if(pIdleHandler != NULL)
697				pIdleHandler->OnIdle();
698		}
699		return FALSE;   // don't continue
700	}
701
702	// override to change non-idle messages
703	virtual BOOL IsIdleMessage(MSG* pMsg) const
704	{
705		// These messages should NOT cause idle processing
706		switch(pMsg->message)
707		{
708		case WM_MOUSEMOVE:
709		case WM_NCMOUSEMOVE:
710		case WM_PAINT:
711		case 0x0118:	// WM_SYSTIMER (caret blink)
712			return FALSE;
713		}
714
715		return TRUE;
716	}
717};
718
719
720///////////////////////////////////////////////////////////////////////////////
721// CStaticDataInitCriticalSectionLock and CWindowCreateCriticalSectionLock
722// internal classes to manage critical sections for ATL (deprecated)
723
724class CStaticDataInitCriticalSectionLock
725{
726public:
727	ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
728
729	CStaticDataInitCriticalSectionLock() : m_cslock(ATL::_pAtlModule->m_csStaticDataInitAndTypeInfo, false)
730	{ }
731
732	HRESULT Lock()
733	{
734		return m_cslock.Lock();
735	}
736
737	void Unlock()
738	{
739		m_cslock.Unlock();
740	}
741};
742
743
744class CWindowCreateCriticalSectionLock
745{
746public:
747	ATL::CComCritSecLock<ATL::CComCriticalSection> m_cslock;
748
749	CWindowCreateCriticalSectionLock() : m_cslock(ATL::_AtlWinModule.m_csWindowCreate, false)
750	{ }
751
752	HRESULT Lock()
753	{
754		return m_cslock.Lock();
755	}
756
757	void Unlock()
758	{
759		m_cslock.Unlock();
760	}
761};
762
763
764///////////////////////////////////////////////////////////////////////////////
765// CAppModule - module class for an application
766
767#if (_MSC_VER == 1400)   // VS2005
768  #pragma warning(push)
769  #pragma warning(disable : 4244)
770  #pragma warning(disable : 4312)
771#endif
772
773class CAppModule : public ATL::CComModule
774{
775public:
776	DWORD m_dwMainThreadID;
777	ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap;
778	ATL::CSimpleArray<HWND>* m_pSettingChangeNotify;
779
780	CAppModule() : m_dwMainThreadID(0), m_pMsgLoopMap(NULL), m_pSettingChangeNotify(NULL)
781	{ }
782
783// Overrides of CComModule::Init and Term
784	HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
785	{
786		HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID);
787		if(FAILED(hRet))
788			return hRet;
789
790		m_dwMainThreadID = ::GetCurrentThreadId();
791		typedef ATL::CSimpleMap<DWORD, CMessageLoop*>   _mapClass;
792		m_pMsgLoopMap = NULL;
793		ATLTRY(m_pMsgLoopMap = new _mapClass);
794		if(m_pMsgLoopMap == NULL)
795			return E_OUTOFMEMORY;
796		m_pSettingChangeNotify = NULL;
797
798		return hRet;
799	}
800
801	void Term()
802	{
803		TermSettingChangeNotify();
804		delete m_pMsgLoopMap;
805		CComModule::Term();
806	}
807
808// Message loop map methods
809	BOOL AddMessageLoop(CMessageLoop* pMsgLoop)
810	{
811		CStaticDataInitCriticalSectionLock lock;
812		if(FAILED(lock.Lock()))
813		{
814			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddMessageLoop.\n"));
815			ATLASSERT(FALSE);
816			return FALSE;
817		}
818
819		ATLASSERT(pMsgLoop != NULL);
820		ATLASSERT(m_pMsgLoopMap->Lookup(::GetCurrentThreadId()) == NULL);   // not in map yet
821
822		BOOL bRet = m_pMsgLoopMap->Add(::GetCurrentThreadId(), pMsgLoop);
823
824		lock.Unlock();
825
826		return bRet;
827	}
828
829	BOOL RemoveMessageLoop()
830	{
831		CStaticDataInitCriticalSectionLock lock;
832		if(FAILED(lock.Lock()))
833		{
834			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveMessageLoop.\n"));
835			ATLASSERT(FALSE);
836			return FALSE;
837		}
838
839		BOOL bRet = m_pMsgLoopMap->Remove(::GetCurrentThreadId());
840
841		lock.Unlock();
842
843		return bRet;
844	}
845
846	CMessageLoop* GetMessageLoop(DWORD dwThreadID = ::GetCurrentThreadId()) const
847	{
848		CStaticDataInitCriticalSectionLock lock;
849		if(FAILED(lock.Lock()))
850		{
851			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::GetMessageLoop.\n"));
852			ATLASSERT(FALSE);
853			return NULL;
854		}
855
856		CMessageLoop* pLoop =  m_pMsgLoopMap->Lookup(dwThreadID);
857
858		lock.Unlock();
859
860		return pLoop;
861	}
862
863// Setting change notify methods
864	// Note: Call this from the main thread for MSDI apps
865	BOOL InitSettingChangeNotify(DLGPROC pfnDlgProc = _SettingChangeDlgProc)
866	{
867		CStaticDataInitCriticalSectionLock lock;
868		if(FAILED(lock.Lock()))
869		{
870			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::InitSettingChangeNotify.\n"));
871			ATLASSERT(FALSE);
872			return FALSE;
873		}
874
875		if(m_pSettingChangeNotify == NULL)
876		{
877			typedef ATL::CSimpleArray<HWND>   _notifyClass;
878			ATLTRY(m_pSettingChangeNotify = new _notifyClass);
879			ATLASSERT(m_pSettingChangeNotify != NULL);
880		}
881
882		BOOL bRet = (m_pSettingChangeNotify != NULL);
883		if(bRet && (m_pSettingChangeNotify->GetSize() == 0))
884		{
885			// init everything
886			_ATL_EMPTY_DLGTEMPLATE templ;
887			HWND hNtfWnd = ::CreateDialogIndirect(GetModuleInstance(), &templ, NULL, pfnDlgProc);
888			ATLASSERT(::IsWindow(hNtfWnd));
889			if(::IsWindow(hNtfWnd))
890			{
891				::SetWindowLongPtr(hNtfWnd, GWLP_USERDATA, (LONG_PTR)this);
892				bRet = m_pSettingChangeNotify->Add(hNtfWnd);
893			}
894			else
895			{
896				bRet = FALSE;
897			}
898		}
899
900		lock.Unlock();
901
902		return bRet;
903	}
904
905	void TermSettingChangeNotify()
906	{
907		CStaticDataInitCriticalSectionLock lock;
908		if(FAILED(lock.Lock()))
909		{
910			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::TermSettingChangeNotify.\n"));
911			ATLASSERT(FALSE);
912			return;
913		}
914
915		if((m_pSettingChangeNotify != NULL) && (m_pSettingChangeNotify->GetSize() > 0))
916			::DestroyWindow((*m_pSettingChangeNotify)[0]);
917		delete m_pSettingChangeNotify;
918		m_pSettingChangeNotify = NULL;
919
920		lock.Unlock();
921	}
922
923	BOOL AddSettingChangeNotify(HWND hWnd)
924	{
925		CStaticDataInitCriticalSectionLock lock;
926		if(FAILED(lock.Lock()))
927		{
928			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::AddSettingChangeNotify.\n"));
929			ATLASSERT(FALSE);
930			return FALSE;
931		}
932
933		ATLASSERT(::IsWindow(hWnd));
934		BOOL bRet = FALSE;
935		if(InitSettingChangeNotify() != FALSE)
936			bRet = m_pSettingChangeNotify->Add(hWnd);
937
938		lock.Unlock();
939
940		return bRet;
941	}
942
943	BOOL RemoveSettingChangeNotify(HWND hWnd)
944	{
945		CStaticDataInitCriticalSectionLock lock;
946		if(FAILED(lock.Lock()))
947		{
948			ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CAppModule::RemoveSettingChangeNotify.\n"));
949			ATLASSERT(FALSE);
950			return FALSE;
951		}
952
953		BOOL bRet = FALSE;
954		if(m_pSettingChangeNotify != NULL)
955			bRet = m_pSettingChangeNotify->Remove(hWnd);
956
957		lock.Unlock();
958
959		return bRet;
960	}
961
962// Implementation - setting change notify dialog template and dialog procedure
963	struct _ATL_EMPTY_DLGTEMPLATE : DLGTEMPLATE
964	{
965		_ATL_EMPTY_DLGTEMPLATE()
966		{
967			memset(this, 0, sizeof(_ATL_EMPTY_DLGTEMPLATE));
968			style = WS_POPUP;
969		}
970		WORD wMenu, wClass, wTitle;
971	};
972
973	static INT_PTR CALLBACK _SettingChangeDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
974	{
975		if(uMsg == WM_SETTINGCHANGE)
976		{
977			CAppModule* pModule = (CAppModule*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
978			ATLASSERT(pModule != NULL);
979			ATLASSERT(pModule->m_pSettingChangeNotify != NULL);
980			const UINT uTimeout = 1500;   // ms
981			for(int i = 1; i < pModule->m_pSettingChangeNotify->GetSize(); i++)
982				::SendMessageTimeout((*pModule->m_pSettingChangeNotify)[i], uMsg, wParam, lParam, SMTO_ABORTIFHUNG, uTimeout, NULL);
983
984			return TRUE;
985		}
986
987		return FALSE;
988	}
989};
990
991#if (_MSC_VER == 1400)   // VS2005
992  #pragma warning(pop)
993#endif
994
995
996///////////////////////////////////////////////////////////////////////////////
997// CServerAppModule - module class for a COM server application
998
999class CServerAppModule : public CAppModule
1000{
1001public:
1002	HANDLE m_hEventShutdown;
1003	bool m_bActivity;
1004	DWORD m_dwTimeOut;
1005	DWORD m_dwPause;
1006
1007	CServerAppModule() : m_hEventShutdown(NULL), m_bActivity(false), m_dwTimeOut(5000), m_dwPause(1000)
1008	{ }
1009
1010// Override of CAppModule::Init
1011	HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
1012	{
1013		m_dwTimeOut = 5000;
1014		m_dwPause = 1000;
1015		return CAppModule::Init(pObjMap, hInstance, pLibID);
1016	}
1017
1018	void Term()
1019	{
1020		if((m_hEventShutdown != NULL) && ::CloseHandle(m_hEventShutdown))
1021			m_hEventShutdown = NULL;
1022		CAppModule::Term();
1023	}
1024
1025// COM Server methods
1026	LONG Unlock() throw()
1027	{
1028		LONG lRet = CComModule::Unlock();
1029		if(lRet == 0)
1030		{
1031			m_bActivity = true;
1032			::SetEvent(m_hEventShutdown); // tell monitor that we transitioned to zero
1033		}
1034		return lRet;
1035	}
1036
1037	void MonitorShutdown()
1038	{
1039		for(;;)
1040		{
1041			::WaitForSingleObject(m_hEventShutdown, INFINITE);
1042			DWORD dwWait = 0;
1043			do
1044			{
1045				m_bActivity = false;
1046				dwWait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
1047			}
1048			while(dwWait == WAIT_OBJECT_0);
1049			// timed out
1050			if(!m_bActivity && (m_nLockCnt == 0)) // if no activity let's really bail
1051			{
1052#if defined(_WIN32_DCOM) && defined(_ATL_FREE_THREADED)
1053				::CoSuspendClassObjects();
1054				if(!m_bActivity && (m_nLockCnt == 0))
1055#endif
1056					break;
1057			}
1058		}
1059		// This handle should be valid now. If it isn't, 
1060		// check if _Module.Term was called first (it shouldn't)
1061		if(::CloseHandle(m_hEventShutdown))
1062			m_hEventShutdown = NULL;
1063		::PostThreadMessage(m_dwMainThreadID, WM_QUIT, 0, 0);
1064	}
1065
1066	bool StartMonitor()
1067	{
1068		m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
1069		if(m_hEventShutdown == NULL)
1070			return false;
1071		DWORD dwThreadID = 0;
1072#ifdef _MT
1073		HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, (UINT (WINAPI*)(void*))MonitorProc, this, 0, (UINT*)&dwThreadID);
1074#else
1075		HANDLE hThread = ::CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
1076#endif
1077		bool bRet = (hThread != NULL);
1078		if(bRet)
1079			::CloseHandle(hThread);
1080		return bRet;
1081	}
1082
1083	static DWORD WINAPI MonitorProc(void* pv)
1084	{
1085		CServerAppModule* p = (CServerAppModule*)pv;
1086		p->MonitorShutdown();
1087		return 0;
1088	}
1089};
1090
1091
1092///////////////////////////////////////////////////////////////////////////////
1093// CRegKeyEx - not used any more, here only for compatibility with old projects
1094
1095typedef ATL::CRegKey CRegKeyEx;
1096
1097} // namespace WTL
1098
1099
1100///////////////////////////////////////////////////////////////////////////////
1101// CString forward reference (enables CString use in atluser.h and atlgdi.h)
1102
1103#if (defined(_WTL_USE_CSTRING) || defined(_WTL_FORWARD_DECLARE_CSTRING)) && !defined(__ATLSTR_H__)
1104  #include <atlstr.h>
1105#endif
1106
1107// CString namespace
1108#define _CSTRING_NS	ATL
1109
1110// Type classes namespace
1111#define _WTYPES_NS
1112
1113
1114///////////////////////////////////////////////////////////////////////////////
1115// General DLL version helpers (removed in ATL11)
1116
1117#if (_ATL_VER >= 0x0B00)
1118
1119namespace ATL
1120{
1121
1122inline HRESULT AtlGetDllVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
1123{
1124	ATLASSERT(pDllVersionInfo != NULL);
1125	if(pDllVersionInfo == NULL)
1126		return E_INVALIDARG;
1127
1128	// We must get this function explicitly because some DLLs don't implement it.
1129	DLLGETVERSIONPROC pfnDllGetVersion = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
1130	if(pfnDllGetVersion == NULL)
1131		return E_NOTIMPL;
1132
1133	return (*pfnDllGetVersion)(pDllVersionInfo);
1134}
1135
1136inline HRESULT AtlGetDllVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
1137{
1138	HINSTANCE hInstDLL = ::LoadLibrary(lpstrDllName);
1139	if(hInstDLL == NULL)
1140		return E_FAIL;
1141	HRESULT hRet = AtlGetDllVersion(hInstDLL, pDllVersionInfo);
1142	::FreeLibrary(hInstDLL);
1143	return hRet;
1144}
1145
1146// Common Control Versions:
1147//   Win95/WinNT 4.0    maj=4 min=00
1148//   IE 3.x     maj=4 min=70
1149//   IE 4.0     maj=4 min=71
1150inline HRESULT AtlGetCommCtrlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
1151{
1152	ATLASSERT((pdwMajor != NULL) && (pdwMinor != NULL));
1153	if((pdwMajor == NULL) || (pdwMinor == NULL))
1154		return E_INVALIDARG;
1155
1156	DLLVERSIONINFO dvi;
1157	::ZeroMemory(&dvi, sizeof(dvi));
1158	dvi.cbSize = sizeof(dvi);
1159	HRESULT hRet = AtlGetDllVersion(_T("comctl32.dll"), &dvi);
1160
1161	if(SUCCEEDED(hRet))
1162	{
1163		*pdwMajor = dvi.dwMajorVersion;
1164		*pdwMinor = dvi.dwMinorVersion;
1165	}
1166	else if(hRet == E_NOTIMPL)
1167	{
1168		// If DllGetVersion is not there, then the DLL is a version
1169		// previous to the one shipped with IE 3.x
1170		*pdwMajor = 4;
1171		*pdwMinor = 0;
1172		hRet = S_OK;
1173	}
1174
1175	return hRet;
1176}
1177
1178// Shell Versions:
1179//   Win95/WinNT 4.0                    maj=4 min=00
1180//   IE 3.x, IE 4.0 without Web Integrated Desktop  maj=4 min=00
1181//   IE 4.0 with Web Integrated Desktop         maj=4 min=71
1182//   IE 4.01 with Web Integrated Desktop        maj=4 min=72
1183inline HRESULT AtlGetShellVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
1184{
1185	ATLASSERT((pdwMajor != NULL) && (pdwMinor != NULL));
1186	if((pdwMajor == NULL) || (pdwMinor == NULL))
1187		return E_INVALIDARG;
1188
1189	DLLVERSIONINFO dvi;
1190	::ZeroMemory(&dvi, sizeof(dvi));
1191	dvi.cbSize = sizeof(dvi);
1192	HRESULT hRet = AtlGetDllVersion(_T("shell32.dll"), &dvi);
1193
1194	if(SUCCEEDED(hRet))
1195	{
1196		*pdwMajor = dvi.dwMajorVersion;
1197		*pdwMinor = dvi.dwMinorVersion;
1198	}
1199	else if(hRet == E_NOTIMPL)
1200	{
1201		// If DllGetVersion is not there, then the DLL is a version
1202		// previous to the one shipped with IE 4.x
1203		*pdwMajor = 4;
1204		*pdwMinor = 0;
1205		hRet = S_OK;
1206	}
1207
1208	return hRet;
1209}
1210
1211} // namespace ATL
1212
1213#endif // (_ATL_VER >= 0x0B00)
1214
1215
1216// These are always included
1217#include "atlwinx.h"
1218#include "atluser.h"
1219#include "atlgdi.h"
1220
1221#ifndef _WTL_NO_AUTOMATIC_NAMESPACE
1222using namespace WTL;
1223#endif // !_WTL_NO_AUTOMATIC_NAMESPACE
1224
1225#endif // __ATLAPP_H__