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
15.6 KiB623 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 __ATLWINX_H__
10#define __ATLWINX_H__
11
12#pragma once
13
14#ifndef __ATLAPP_H__
15	#error atlwinx.h requires atlapp.h to be included first
16#endif
17
18#include <atlwin.h>
19
20
21///////////////////////////////////////////////////////////////////////////////
22// Classes in this file:
23//
24// CWindowEx
25
26
27/////////////////////////////////////////////////////////////////////////////
28// Additional macros needed for template classes
29
30#ifndef DECLARE_WND_CLASS_EX2
31  #define DECLARE_WND_CLASS_EX2(WndClassName, EnclosingClass, style, bkgnd) \
32  static ATL::CWndClassInfo& GetWndClassInfo() \
33  { \
34	static ATL::CWndClassInfo wc = \
35	{ \
36		{ sizeof(WNDCLASSEX), style, EnclosingClass::StartWindowProc, \
37		  0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
38		  NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
39	}; \
40	return wc; \
41  }
42#endif // DECLARE_WND_CLASS_EX2
43
44#ifndef DECLARE_WND_SUPERCLASS2
45  #define DECLARE_WND_SUPERCLASS2(WndClassName, EnclosingClass, OrigWndClassName) \
46  static ATL::CWndClassInfo& GetWndClassInfo() \
47  { \
48	static ATL::CWndClassInfo wc = \
49	{ \
50		{ sizeof(WNDCLASSEX), 0, EnclosingClass::StartWindowProc, \
51		  0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
52		  OrigWndClassName, NULL, NULL, TRUE, 0, _T("") \
53	}; \
54	return wc; \
55  }
56#endif // DECLARE_WND_SUPERCLASS2
57
58
59///////////////////////////////////////////////////////////////////////////////
60// Command Chaining Macros
61
62#define CHAIN_COMMANDS(theChainClass) \
63	if(uMsg == WM_COMMAND) \
64		CHAIN_MSG_MAP(theChainClass)
65
66#define CHAIN_COMMANDS_ALT(theChainClass, msgMapID) \
67	if(uMsg == WM_COMMAND) \
68		CHAIN_MSG_MAP_ALT(theChainClass, msgMapID)
69
70#define CHAIN_COMMANDS_MEMBER(theChainMember) \
71	if(uMsg == WM_COMMAND) \
72		CHAIN_MSG_MAP_MEMBER(theChainMember)
73
74#define CHAIN_COMMANDS_ALT_MEMBER(theChainMember, msgMapID) \
75	if(uMsg == WM_COMMAND) \
76		CHAIN_MSG_MAP_ALT_MEMBER(theChainMember, msgMapID)
77
78
79///////////////////////////////////////////////////////////////////////////////
80// Macros for parent message map to selectively reflect control messages
81
82// NOTE: ReflectNotifications is a member of ATL's CWindowImplRoot
83//  (and overridden in 2 cases - CContainedWindowT and CAxHostWindow)
84//  Since we can't modify ATL, we'll provide the needed additions
85//  in a separate function (that is not a member of CWindowImplRoot)
86
87namespace WTL
88{
89
90inline LRESULT WtlReflectNotificationsFiltered(HWND hWndParent, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled,
91                                               UINT uMsgFilter = WM_NULL, UINT_PTR idFromFilter = 0, HWND hWndChildFilter = NULL)
92{
93	if((uMsgFilter != WM_NULL) && (uMsgFilter != uMsg))
94	{
95		// The notification message doesn't match the filter.
96		bHandled = FALSE;
97		return 1;
98	}
99
100	HWND hWndChild = NULL;
101	UINT_PTR idFrom = 0;
102
103	switch(uMsg)
104	{
105	case WM_COMMAND:
106		if(lParam != NULL)	// not from a menu
107		{
108			hWndChild = (HWND)lParam;
109			idFrom = (UINT_PTR)LOWORD(wParam);
110		}
111		break;
112	case WM_NOTIFY:
113		hWndChild = ((LPNMHDR)lParam)->hwndFrom;
114		idFrom = ((LPNMHDR)lParam)->idFrom;
115		break;
116	case WM_PARENTNOTIFY:
117		switch(LOWORD(wParam))
118		{
119		case WM_CREATE:
120		case WM_DESTROY:
121			hWndChild = (HWND)lParam;
122			idFrom = (UINT_PTR)HIWORD(wParam);
123			break;
124		default:
125			hWndChild = ::GetDlgItem(hWndParent, HIWORD(wParam));
126			idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
127			break;
128		}
129		break;
130	case WM_DRAWITEM:
131		if(wParam)	// not from a menu
132		{
133			hWndChild = ((LPDRAWITEMSTRUCT)lParam)->hwndItem;
134			idFrom = (UINT_PTR)wParam;
135		}
136		break;
137	case WM_MEASUREITEM:
138		if(wParam)	// not from a menu
139		{
140			hWndChild = ::GetDlgItem(hWndParent, ((LPMEASUREITEMSTRUCT)lParam)->CtlID);
141			idFrom = (UINT_PTR)wParam;
142		}
143		break;
144	case WM_COMPAREITEM:
145		if(wParam)	// not from a menu
146		{
147			hWndChild = ((LPCOMPAREITEMSTRUCT)lParam)->hwndItem;
148			idFrom = (UINT_PTR)wParam;
149		}
150		break;
151	case WM_DELETEITEM:
152		if(wParam)	// not from a menu
153		{
154			hWndChild = ((LPDELETEITEMSTRUCT)lParam)->hwndItem;
155			idFrom = (UINT_PTR)wParam;
156		}
157		break;
158	case WM_VKEYTOITEM:
159	case WM_CHARTOITEM:
160	case WM_HSCROLL:
161	case WM_VSCROLL:
162	case WM_CTLCOLORBTN:
163	case WM_CTLCOLORDLG:
164	case WM_CTLCOLOREDIT:
165	case WM_CTLCOLORLISTBOX:
166	case WM_CTLCOLORMSGBOX:
167	case WM_CTLCOLORSCROLLBAR:
168	case WM_CTLCOLORSTATIC:
169		hWndChild = (HWND)lParam;
170		idFrom = (UINT_PTR)::GetDlgCtrlID(hWndChild);
171		break;
172	default:
173		break;
174	}
175
176	if((hWndChild == NULL) ||
177		((hWndChildFilter != NULL) && (hWndChildFilter != hWndChild)))
178	{
179		// Either hWndChild isn't valid, or
180		// hWndChild doesn't match the filter.
181		bHandled = FALSE;
182		return 1;
183	}
184
185	if((idFromFilter != 0) && (idFromFilter != idFrom))
186	{
187		// The dialog control id doesn't match the filter.
188		bHandled = FALSE;
189		return 1;
190	}
191
192	ATLASSERT(::IsWindow(hWndChild));
193	LRESULT lResult = ::SendMessage(hWndChild, OCM__BASE + uMsg, wParam, lParam);
194	if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC))
195	{
196		// Try to prevent problems with WM_CTLCOLOR* messages when
197		// the message wasn't really handled
198		bHandled = FALSE;
199	}
200
201	return lResult;
202}
203
204} // namespace WTL
205
206// Try to prevent problems with WM_CTLCOLOR* messages when
207// the message wasn't really handled
208#define REFLECT_NOTIFICATIONS_EX() \
209{ \
210	bHandled = TRUE; \
211	lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
212	if((lResult == 0) && (uMsg >= WM_CTLCOLORMSGBOX) && (uMsg <= WM_CTLCOLORSTATIC)) \
213		bHandled = FALSE; \
214	if(bHandled) \
215		return TRUE; \
216}
217
218#define REFLECT_NOTIFICATIONS_MSG_FILTERED(uMsgFilter) \
219	{ \
220		bHandled = TRUE; \
221		lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, NULL); \
222		if(bHandled) \
223			return TRUE; \
224	}
225
226#define REFLECT_NOTIFICATIONS_ID_FILTERED(idFromFilter) \
227	{ \
228		bHandled = TRUE; \
229		lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, idFromFilter, NULL); \
230		if(bHandled) \
231			return TRUE; \
232	}
233
234#define REFLECT_NOTIFICATIONS_HWND_FILTERED(hWndChildFilter) \
235	{ \
236		bHandled = TRUE; \
237		lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, WM_NULL, 0, hWndChildFilter); \
238		if(bHandled) \
239			return TRUE; \
240	}
241
242#define REFLECT_NOTIFICATIONS_MSG_ID_FILTERED(uMsgFilter, idFromFilter) \
243	{ \
244		bHandled = TRUE; \
245		lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, idFromFilter, NULL); \
246		if(bHandled) \
247			return TRUE; \
248	}
249
250#define REFLECT_NOTIFICATIONS_MSG_HWND_FILTERED(uMsgFilter, hWndChildFilter) \
251	{ \
252		bHandled = TRUE; \
253		lResult = WTL::WtlReflectNotificationsFiltered(this->m_hWnd, uMsg, wParam, lParam, bHandled, uMsgFilter, 0, hWndChildFilter); \
254		if(bHandled) \
255			return TRUE; \
256	}
257
258#define REFLECT_COMMAND(id, code) \
259	if((uMsg == WM_COMMAND) && (id == LOWORD(wParam)) && (code == HIWORD(wParam))) \
260	{ \
261		bHandled = TRUE; \
262		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
263		if(bHandled) \
264			return TRUE; \
265	}
266
267#define REFLECT_COMMAND_ID(id) \
268	if((uMsg == WM_COMMAND) && (id == LOWORD(wParam))) \
269	{ \
270		bHandled = TRUE; \
271		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
272		if(bHandled) \
273			return TRUE; \
274	}
275
276#define REFLECT_COMMAND_CODE(code) \
277	if((uMsg == WM_COMMAND) && (code == HIWORD(wParam))) \
278	{ \
279		bHandled = TRUE; \
280		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
281		if(bHandled) \
282			return TRUE; \
283	}
284
285#define REFLECT_COMMAND_RANGE(idFirst, idLast) \
286	if((uMsg == WM_COMMAND) && (LOWORD(wParam) >= idFirst) && (LOWORD(wParam) <= idLast)) \
287	{ \
288		bHandled = TRUE; \
289		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
290		if(bHandled) \
291			return TRUE; \
292	}
293
294#define REFLECT_COMMAND_RANGE_CODE(idFirst, idLast, code) \
295	if((uMsg == WM_COMMAND) && (code == HIWORD(wParam)) && (LOWORD(wParam) >= idFirst) && (LOWORD(wParam) <= idLast)) \
296	{ \
297		bHandled = TRUE; \
298		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
299		if(bHandled) \
300			return TRUE; \
301	}
302
303#define REFLECT_NOTIFY(id, cd) \
304	if((uMsg == WM_NOTIFY) && (id == ((LPNMHDR)lParam)->idFrom) && (cd == ((LPNMHDR)lParam)->code)) \
305	{ \
306		bHandled = TRUE; \
307		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
308		if(bHandled) \
309			return TRUE; \
310	}
311
312#define REFLECT_NOTIFY_ID(id) \
313	if((uMsg == WM_NOTIFY) && (id == ((LPNMHDR)lParam)->idFrom)) \
314	{ \
315		bHandled = TRUE; \
316		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
317		if(bHandled) \
318			return TRUE; \
319	}
320
321#define REFLECT_NOTIFY_CODE(cd) \
322	if((uMsg == WM_NOTIFY) && (cd == ((LPNMHDR)lParam)->code)) \
323	{ \
324		bHandled = TRUE; \
325		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
326		if(bHandled) \
327			return TRUE; \
328	}
329
330#define REFLECT_NOTIFY_RANGE(idFirst, idLast) \
331	if((uMsg == WM_NOTIFY) && (((LPNMHDR)lParam)->idFrom >= idFirst) && (((LPNMHDR)lParam)->idFrom <= idLast)) \
332	{ \
333		bHandled = TRUE; \
334		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
335		if(bHandled) \
336			return TRUE; \
337	}
338
339#define REFLECT_NOTIFY_RANGE_CODE(idFirst, idLast, cd) \
340	if((uMsg == WM_NOTIFY) && (cd == ((LPNMHDR)lParam)->code) && (((LPNMHDR)lParam)->idFrom >= idFirst) && (((LPNMHDR)lParam)->idFrom <= idLast)) \
341	{ \
342		bHandled = TRUE; \
343		lResult = this->ReflectNotifications(uMsg, wParam, lParam, bHandled); \
344		if(bHandled) \
345			return TRUE; \
346	}
347
348
349///////////////////////////////////////////////////////////////////////////////
350// GetClassLong/SetClassLong redefinition to avoid problems with class members
351
352#ifdef SetClassLongPtrA
353  #undef SetClassLongPtrA
354  inline LONG_PTR SetClassLongPtrA(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
355  {
356	return ::SetClassLongA(hWnd, nIndex, LONG(dwNewLong));
357  }
358#endif
359
360#ifdef SetClassLongPtrW
361  #undef SetClassLongPtrW
362  inline LONG_PTR SetClassLongPtrW(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
363  {
364	return ::SetClassLongW(hWnd, nIndex, LONG(dwNewLong));
365  }
366#endif
367
368#ifdef GetClassLongPtrA
369  #undef GetClassLongPtrA
370  inline LONG_PTR GetClassLongPtrA(HWND hWnd, int nIndex)
371  {
372	return ::GetClassLongA(hWnd, nIndex);
373  }
374#endif
375
376#ifdef GetClassLongPtrW
377  #undef GetClassLongPtrW
378  inline LONG_PTR GetClassLongPtrW(HWND hWnd, int nIndex)
379  {
380	return ::GetClassLongW(hWnd, nIndex);
381  }
382#endif
383
384
385///////////////////////////////////////////////////////////////////////////////
386// CWindowEx - extension of ATL::CWindow
387
388namespace WTL
389{
390
391class CWindowEx : public ATL::CWindow
392{
393public:
394	CWindowEx(HWND hWnd = NULL) : ATL::CWindow(hWnd)
395	{ }
396
397	CWindowEx& operator =(HWND hWnd)
398	{
399		m_hWnd = hWnd;
400		return *this;
401	}
402
403	operator HWND() const
404	{
405		return m_hWnd;
406	}
407
408// Methods
409	BOOL PrintWindow(HDC hDC, UINT uFlags = 0)
410	{
411		ATLASSERT(::IsWindow(m_hWnd));
412		return ::PrintWindow(m_hWnd, hDC, uFlags);
413	}
414
415	BOOL DragDetect(POINT pt)
416	{
417		ATLASSERT(::IsWindow(m_hWnd));
418		return ::DragDetect(m_hWnd, pt);
419	}
420
421	BOOL DragDetect()
422	{
423		ATLASSERT(::IsWindow(m_hWnd));
424
425		POINT pt = {};
426		::GetCursorPos(&pt);
427		return ::DragDetect(m_hWnd, pt);
428	}
429
430	CWindowEx GetAncestor(UINT uFlags) const
431	{
432		ATLASSERT(::IsWindow(m_hWnd));
433		return CWindowEx(::GetAncestor(m_hWnd, uFlags));
434	}
435
436	// Note: Does not work properly on Vista Aero and above
437	BOOL AnimateWindow(DWORD dwFlags, DWORD dwTime = 200)
438	{
439		ATLASSERT(::IsWindow(m_hWnd));
440		return ::AnimateWindow(m_hWnd, dwTime, dwFlags);
441	}
442
443	BOOL FlashWindowEx(DWORD dwFlags, UINT uCount, DWORD dwTimeout = 0)
444	{
445		ATLASSERT(::IsWindow(m_hWnd));
446
447		FLASHWINFO fi = { sizeof(FLASHWINFO) };
448		fi.hwnd = m_hWnd;
449		fi.dwFlags = dwFlags;
450		fi.uCount = uCount;
451		fi.dwTimeout = dwTimeout;
452		return ::FlashWindowEx(&fi);
453	}
454
455	BOOL StopFlashWindowEx()
456	{
457		ATLASSERT(::IsWindow(m_hWnd));
458
459		FLASHWINFO fi = { sizeof(FLASHWINFO) };
460		fi.hwnd = m_hWnd;
461		fi.dwFlags = FLASHW_STOP;
462		return ::FlashWindowEx(&fi);
463	}
464
465// Class long properties
466	DWORD GetClassLong(int nIndex) const
467	{
468		ATLASSERT(::IsWindow(m_hWnd));
469		return ::GetClassLong(m_hWnd, nIndex);
470	}
471
472	DWORD SetClassLong(int nIndex, LONG dwNewLong)
473	{
474		ATLASSERT(::IsWindow(m_hWnd));
475		return ::SetClassLong(m_hWnd, nIndex, dwNewLong);
476	}
477
478	ULONG_PTR GetClassLongPtr(int nIndex) const
479	{
480		ATLASSERT(::IsWindow(m_hWnd));
481		return ::GetClassLongPtr(m_hWnd, nIndex);
482	}
483
484	ULONG_PTR SetClassLongPtr(int nIndex, LONG_PTR dwNewLong)
485	{
486		ATLASSERT(::IsWindow(m_hWnd));
487		return ::SetClassLongPtr(m_hWnd, nIndex, dwNewLong);
488	}
489
490// Layered windows
491	BOOL SetLayeredWindowAttributes(COLORREF crlKey, BYTE byteAlpha, DWORD dwFlags)
492	{
493		ATLASSERT(::IsWindow(m_hWnd));
494		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
495
496		return ::SetLayeredWindowAttributes(m_hWnd, crlKey, byteAlpha, dwFlags);
497	}
498
499	BOOL UpdateLayeredWindow(HDC hdcDst, LPPOINT pptDst, LPSIZE psize, HDC hdcSrc, LPPOINT pptSrc, COLORREF crlKey, BLENDFUNCTION* pblend, DWORD dwFlags)
500	{
501		ATLASSERT(::IsWindow(m_hWnd));
502		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
503
504		return ::UpdateLayeredWindow(m_hWnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crlKey, pblend, dwFlags);
505	}
506
507	BOOL UpdateLayeredWindow(LPPOINT pptDst = NULL)
508	{
509		ATLASSERT(::IsWindow(m_hWnd));
510		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
511
512		return ::UpdateLayeredWindow(m_hWnd, NULL, pptDst, NULL, NULL, NULL, CLR_NONE, NULL, 0);
513	}
514
515	BOOL GetLayeredWindowAttributes(COLORREF* pcrlKey, BYTE* pbyteAlpha, DWORD* pdwFlags) const
516	{
517		ATLASSERT(::IsWindow(m_hWnd));
518		ATLASSERT((GetExStyle() & WS_EX_LAYERED) != 0);
519
520		return ::GetLayeredWindowAttributes(m_hWnd, pcrlKey, pbyteAlpha, pdwFlags);
521	}
522
523// Mouse tracking
524	BOOL StartTrackMouseLeave()
525	{
526		ATLASSERT(::IsWindow(m_hWnd));
527
528		TRACKMOUSEEVENT tme = {};
529		tme.cbSize = sizeof(TRACKMOUSEEVENT);
530		tme.dwFlags = TME_LEAVE;
531		tme.hwndTrack = m_hWnd;
532		return ::TrackMouseEvent(&tme);
533	}
534
535	BOOL StartTrackMouse(DWORD dwFlags, DWORD dwHoverTime = HOVER_DEFAULT)
536	{
537		ATLASSERT(::IsWindow(m_hWnd));
538
539		TRACKMOUSEEVENT tme = {};
540		tme.cbSize = sizeof(TRACKMOUSEEVENT);
541		tme.dwFlags = dwFlags;
542		tme.hwndTrack = m_hWnd;
543		tme.dwHoverTime = dwHoverTime;
544		return ::TrackMouseEvent(&tme);
545	}
546
547	BOOL CancelTrackMouse(DWORD dwType)
548	{
549		ATLASSERT(::IsWindow(m_hWnd));
550
551		TRACKMOUSEEVENT tme = {};
552		tme.cbSize = sizeof(TRACKMOUSEEVENT);
553		tme.dwFlags = TME_CANCEL | dwType;
554		tme.hwndTrack = m_hWnd;
555		return ::TrackMouseEvent(&tme);
556	}
557
558// CString support
559#ifdef __ATLSTR_H__
560	int GetWindowText(ATL::CString& strText) const
561	{
562		int nLength = GetWindowTextLength();
563		LPTSTR pszText = strText.GetBuffer(nLength + 1);
564		nLength = ::GetWindowText(m_hWnd, pszText, nLength + 1);
565		strText.ReleaseBuffer(nLength);
566
567		return nLength;
568	}
569
570	UINT GetDlgItemText(int nID, ATL::CString& strText) const
571	{
572		ATLASSERT(::IsWindow(m_hWnd));
573
574		HWND hItem = GetDlgItem(nID);
575		if(hItem != NULL)
576		{
577			int nLength = ::GetWindowTextLength(hItem);
578			LPTSTR pszText = strText.GetBuffer(nLength + 1);
579			nLength = ::GetWindowText(hItem, pszText, nLength + 1);
580			strText.ReleaseBuffer(nLength);
581
582			return nLength;
583		}
584		else
585		{
586			strText.Empty();
587
588			return 0;
589		}
590	}
591#endif // __ATLSTR_H__
592
593// Dialog window only
594	UINT DlgGetDefID() const
595	{
596		ATLASSERT(::IsWindow(m_hWnd));
597
598		LRESULT lRet = ::SendMessage(m_hWnd, DM_GETDEFID, 0, 0L);
599		UINT uID = 0U;
600		if(HIWORD(lRet) == DC_HASDEFID)
601			uID = LOWORD(lRet);
602
603		return uID;
604	}
605
606	void DlgSetDefID(UINT uID)
607	{
608		ATLASSERT(::IsWindow(m_hWnd));
609
610		::SendMessage(m_hWnd, DM_SETDEFID, uID, 0L);
611	}
612
613	void DlgReposition()
614	{
615		ATLASSERT(::IsWindow(m_hWnd));
616
617		::SendMessage(m_hWnd, DM_REPOSITION, 0, 0L);
618	}
619};
620
621} // namespace WTL
622
623#endif // __ATLWINX_H__