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
31.8 KiB1231 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 __ATLUSER_H__
10#define __ATLUSER_H__
11
12#pragma once
13
14#ifndef __ATLAPP_H__
15	#error atluser.h requires atlapp.h to be included first
16#endif
17
18
19///////////////////////////////////////////////////////////////////////////////
20// Classes in this file:
21//
22// CMenuItemInfo
23// CMenuT<t_bManaged>
24// CAcceleratorT<t_bManaged>
25// CIconT<t_bManaged>
26// CCursorT<t_bManaged>
27// CResource
28//
29// Global functions:
30//   AtlMessageBox()
31//
32//   AtlLoadAccelerators()
33//   AtlLoadMenu()
34//   AtlLoadBitmap()
35//   AtlLoadSysBitmap()
36//   AtlLoadCursor()
37//   AtlLoadSysCursor()
38//   AtlLoadIcon()
39//   AtlLoadSysIcon()
40//   AtlLoadBitmapImage()
41//   AtlLoadCursorImage()
42//   AtlLoadIconImage()
43//   AtlLoadSysBitmapImage()
44//   AtlLoadSysCursorImage()
45//   AtlLoadSysIconImage()
46//   AtlLoadString()
47
48
49namespace WTL
50{
51
52///////////////////////////////////////////////////////////////////////////////
53// AtlMessageBox - accepts both memory and resource based strings
54
55inline int AtlMessageBox(HWND hWndOwner, ATL::_U_STRINGorID message, ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uType = MB_OK | MB_ICONINFORMATION)
56{
57	ATLASSERT((hWndOwner == NULL) || ::IsWindow(hWndOwner));
58
59	LPTSTR lpstrMessage = NULL;
60	if(IS_INTRESOURCE(message.m_lpstr))
61	{
62		for(int nLen = 256; ; nLen *= 2)
63		{
64			ATLTRY(lpstrMessage = new TCHAR[nLen]);
65			if(lpstrMessage == NULL)
66			{
67				ATLASSERT(FALSE);
68				return 0;
69			}
70			int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(message.m_lpstr), lpstrMessage, nLen);
71			if(nRes < nLen - 1)
72				break;
73			delete [] lpstrMessage;
74			lpstrMessage = NULL;
75		}
76
77		message.m_lpstr = lpstrMessage;
78	}
79
80	LPTSTR lpstrTitle = NULL;
81	if(IS_INTRESOURCE(title.m_lpstr) && (LOWORD(title.m_lpstr) != 0))
82	{
83		for(int nLen = 256; ; nLen *= 2)
84		{
85			ATLTRY(lpstrTitle = new TCHAR[nLen]);
86			if(lpstrTitle == NULL)
87			{
88				ATLASSERT(FALSE);
89				return 0;
90			}
91			int nRes = ::LoadString(ModuleHelper::GetResourceInstance(), LOWORD(title.m_lpstr), lpstrTitle, nLen);
92			if(nRes < nLen - 1)
93				break;
94			delete [] lpstrTitle;
95			lpstrTitle = NULL;
96		}
97
98		title.m_lpstr = lpstrTitle;
99	}
100
101	int nRet = ::MessageBox(hWndOwner, message.m_lpstr, title.m_lpstr, uType);
102
103	delete [] lpstrMessage;
104	delete [] lpstrTitle;
105
106	return nRet;
107}
108
109
110///////////////////////////////////////////////////////////////////////////////
111// CMenu
112
113class CMenuItemInfo : public MENUITEMINFO
114{
115public:
116	CMenuItemInfo()
117	{
118		memset(this, 0, sizeof(MENUITEMINFO));
119		cbSize = sizeof(MENUITEMINFO);
120	}
121};
122
123
124// forward declarations
125template <bool t_bManaged> class CMenuT;
126typedef CMenuT<false>   CMenuHandle;
127typedef CMenuT<true>    CMenu;
128
129
130template <bool t_bManaged>
131class CMenuT
132{
133public:
134// Data members
135	HMENU m_hMenu;
136
137// Constructor/destructor/operators
138	CMenuT(HMENU hMenu = NULL) : m_hMenu(hMenu)
139	{ }
140
141	~CMenuT()
142	{
143		if(t_bManaged && (m_hMenu != NULL))
144			DestroyMenu();
145	}
146
147	CMenuT<t_bManaged>& operator =(HMENU hMenu)
148	{
149		Attach(hMenu);
150		return *this;
151	}
152
153	void Attach(HMENU hMenuNew)
154	{
155		ATLASSERT(::IsMenu(hMenuNew));
156		if(t_bManaged && (m_hMenu != NULL) && (m_hMenu != hMenuNew))
157			::DestroyMenu(m_hMenu);
158		m_hMenu = hMenuNew;
159	}
160
161	HMENU Detach()
162	{
163		HMENU hMenu = m_hMenu;
164		m_hMenu = NULL;
165		return hMenu;
166	}
167
168	operator HMENU() const { return m_hMenu; }
169
170	bool IsNull() const { return (m_hMenu == NULL); }
171
172	BOOL IsMenu() const
173	{
174		return ::IsMenu(m_hMenu);
175	}
176
177// Create/destroy methods
178	BOOL CreateMenu()
179	{
180		ATLASSERT(m_hMenu == NULL);
181		m_hMenu = ::CreateMenu();
182		return (m_hMenu != NULL) ? TRUE : FALSE;
183	}
184
185	BOOL CreatePopupMenu()
186	{
187		ATLASSERT(m_hMenu == NULL);
188		m_hMenu = ::CreatePopupMenu();
189		return (m_hMenu != NULL) ? TRUE : FALSE;
190	}
191
192	BOOL LoadMenu(ATL::_U_STRINGorID menu)
193	{
194		ATLASSERT(m_hMenu == NULL);
195		m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
196		return (m_hMenu != NULL) ? TRUE : FALSE;
197	}
198
199	BOOL LoadMenuIndirect(const void* lpMenuTemplate)
200	{
201		ATLASSERT(m_hMenu == NULL);
202		m_hMenu = ::LoadMenuIndirect(lpMenuTemplate);
203		return (m_hMenu != NULL) ? TRUE : FALSE;
204	}
205
206	BOOL DestroyMenu()
207	{
208		if (m_hMenu == NULL)
209			return FALSE;
210		BOOL bRet = ::DestroyMenu(m_hMenu);
211		if(bRet)
212			m_hMenu = NULL;
213		return bRet;
214	}
215
216// Menu Operations
217	BOOL DeleteMenu(UINT nPosition, UINT nFlags)
218	{
219		ATLASSERT(::IsMenu(m_hMenu));
220		return ::DeleteMenu(m_hMenu, nPosition, nFlags);
221	}
222
223	BOOL TrackPopupMenu(UINT nFlags, int x, int y, HWND hWnd, LPCRECT lpRect = NULL)
224	{
225		ATLASSERT(::IsMenu(m_hMenu));
226		x = _FixTrackMenuPopupX(x, y);
227		return ::TrackPopupMenu(m_hMenu, nFlags, x, y, 0, hWnd, lpRect);
228	}
229
230	BOOL TrackPopupMenuEx(UINT uFlags, int x, int y, HWND hWnd, LPTPMPARAMS lptpm = NULL)
231	{
232		ATLASSERT(::IsMenu(m_hMenu));
233		x = _FixTrackMenuPopupX(x, y);
234		return ::TrackPopupMenuEx(m_hMenu, uFlags, x, y, hWnd, lptpm);
235	}
236
237	// helper that fixes popup menu X position when it's off-screen
238	static int _FixTrackMenuPopupX(int x, int y)
239	{
240		POINT pt = { x, y };
241		HMONITOR hMonitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
242		if(hMonitor == NULL)
243		{
244			HMONITOR hMonitorNear = ::MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
245			if(hMonitorNear != NULL)
246			{
247				MONITORINFO mi = { sizeof(MONITORINFO) };
248				if(::GetMonitorInfo(hMonitorNear, &mi) != FALSE)
249				{
250					if(x < mi.rcWork.left)
251						x = mi.rcWork.left;
252					else if(x > mi.rcWork.right)
253						x = mi.rcWork.right;
254				}
255			}
256		}
257
258		return x;
259	}
260
261	BOOL GetMenuInfo(LPMENUINFO lpMenuInfo) const
262	{
263		ATLASSERT(::IsMenu(m_hMenu));
264		return ::GetMenuInfo(m_hMenu, lpMenuInfo);
265	}
266
267	BOOL SetMenuInfo(LPCMENUINFO lpMenuInfo)
268	{
269		ATLASSERT(::IsMenu(m_hMenu));
270		return ::SetMenuInfo(m_hMenu, lpMenuInfo);
271	}
272
273// Menu Item Operations
274	BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL)
275	{
276		ATLASSERT(::IsMenu(m_hMenu));
277		return ::AppendMenu(m_hMenu, nFlags, nIDNewItem, lpszNewItem);
278	}
279
280	BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem)
281	{
282		ATLASSERT(::IsMenu(m_hMenu));
283		ATLASSERT(::IsMenu(hSubMenu));
284		return ::AppendMenu(m_hMenu, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem);
285	}
286
287	BOOL AppendMenu(UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp)
288	{
289		ATLASSERT(::IsMenu(m_hMenu));
290		return ::AppendMenu(m_hMenu, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp);
291	}
292
293	BOOL AppendMenu(UINT nFlags, HMENU hSubMenu, HBITMAP hBmp)
294	{
295		ATLASSERT(::IsMenu(m_hMenu));
296		ATLASSERT(::IsMenu(hSubMenu));
297		return ::AppendMenu(m_hMenu, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp);
298	}
299
300	UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck)
301	{
302		ATLASSERT(::IsMenu(m_hMenu));
303		return (UINT)::CheckMenuItem(m_hMenu, nIDCheckItem, nCheck);
304	}
305
306	UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable)
307	{
308		ATLASSERT(::IsMenu(m_hMenu));
309		return ::EnableMenuItem(m_hMenu, nIDEnableItem, nEnable);
310	}
311
312	BOOL HiliteMenuItem(HWND hWnd, UINT uIDHiliteItem, UINT uHilite)
313	{
314		ATLASSERT(::IsMenu(m_hMenu));
315		return ::HiliteMenuItem(hWnd, m_hMenu, uIDHiliteItem, uHilite);
316	}
317
318	int GetMenuItemCount() const
319	{
320		ATLASSERT(::IsMenu(m_hMenu));
321		return ::GetMenuItemCount(m_hMenu);
322	}
323
324	UINT GetMenuItemID(int nPos) const
325	{
326		ATLASSERT(::IsMenu(m_hMenu));
327		return ::GetMenuItemID(m_hMenu, nPos);
328	}
329
330	UINT GetMenuState(UINT nID, UINT nFlags) const
331	{
332		ATLASSERT(::IsMenu(m_hMenu));
333		return ::GetMenuState(m_hMenu, nID, nFlags);
334	}
335
336	int GetMenuString(UINT nIDItem, LPTSTR lpString, int nMaxCount, UINT nFlags) const
337	{
338		ATLASSERT(::IsMenu(m_hMenu));
339		return ::GetMenuString(m_hMenu, nIDItem, lpString, nMaxCount, nFlags);
340	}
341
342	int GetMenuStringLen(UINT nIDItem, UINT nFlags) const
343	{
344		ATLASSERT(::IsMenu(m_hMenu));
345		return ::GetMenuString(m_hMenu, nIDItem, NULL, 0, nFlags);
346	}
347
348	BOOL GetMenuString(UINT nIDItem, BSTR& bstrText, UINT nFlags) const
349	{
350		USES_CONVERSION;
351		ATLASSERT(::IsMenu(m_hMenu));
352		ATLASSERT(bstrText == NULL);
353
354		int nLen = GetMenuStringLen(nIDItem, nFlags);
355		if(nLen == 0)
356		{
357			bstrText = ::SysAllocString(OLESTR(""));
358			return (bstrText != NULL) ? TRUE : FALSE;
359		}
360
361		nLen++;   // increment to include terminating NULL char
362		ATL::CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
363		LPTSTR lpszText = buff.Allocate(nLen);
364		if(lpszText == NULL)
365			return FALSE;
366
367		if(!GetMenuString(nIDItem, lpszText, nLen, nFlags))
368			return FALSE;
369
370		bstrText = ::SysAllocString(T2OLE(lpszText));
371		return (bstrText != NULL) ? TRUE : FALSE;
372	}
373
374#ifdef __ATLSTR_H__
375	int GetMenuString(UINT nIDItem, ATL::CString& strText, UINT nFlags) const
376	{
377		ATLASSERT(::IsMenu(m_hMenu));
378
379		int nLen = GetMenuStringLen(nIDItem, nFlags);
380		if(nLen == 0)
381			return 0;
382
383		nLen++;   // increment to include terminating NULL char
384		LPTSTR lpstr = strText.GetBufferSetLength(nLen);
385		if(lpstr == NULL)
386			return 0;
387		int nRet = GetMenuString(nIDItem, lpstr, nLen, nFlags);
388		strText.ReleaseBuffer();
389		return nRet;
390	}
391#endif // __ATLSTR_H__
392
393	CMenuHandle GetSubMenu(int nPos) const
394	{
395		ATLASSERT(::IsMenu(m_hMenu));
396		return CMenuHandle(::GetSubMenu(m_hMenu, nPos));
397	}
398
399	BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL)
400	{
401		ATLASSERT(::IsMenu(m_hMenu));
402		return ::InsertMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem);
403	}
404
405	BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem)
406	{
407		ATLASSERT(::IsMenu(m_hMenu));
408		ATLASSERT(::IsMenu(hSubMenu));
409		return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem);
410	}
411
412	BOOL InsertMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp)
413	{
414		ATLASSERT(::IsMenu(m_hMenu));
415		return ::InsertMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp);
416	}
417
418	BOOL InsertMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp)
419	{
420		ATLASSERT(::IsMenu(m_hMenu));
421		ATLASSERT(::IsMenu(hSubMenu));
422		return ::InsertMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp);
423	}
424
425	BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem = 0, LPCTSTR lpszNewItem = NULL)
426	{
427		ATLASSERT(::IsMenu(m_hMenu));
428		return ::ModifyMenu(m_hMenu, nPosition, nFlags, nIDNewItem, lpszNewItem);
429	}
430
431	BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, LPCTSTR lpszNewItem)
432	{
433		ATLASSERT(::IsMenu(m_hMenu));
434		ATLASSERT(::IsMenu(hSubMenu));
435		return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_POPUP, (UINT_PTR)hSubMenu, lpszNewItem);
436	}
437
438	BOOL ModifyMenu(UINT nPosition, UINT nFlags, UINT_PTR nIDNewItem, HBITMAP hBmp)
439	{
440		ATLASSERT(::IsMenu(m_hMenu));
441		return ::ModifyMenu(m_hMenu, nPosition, nFlags | MF_BITMAP, nIDNewItem, (LPCTSTR)hBmp);
442	}
443
444	BOOL ModifyMenu(UINT nPosition, UINT nFlags, HMENU hSubMenu, HBITMAP hBmp)
445	{
446		ATLASSERT(::IsMenu(m_hMenu));
447		ATLASSERT(::IsMenu(hSubMenu));
448		return ::ModifyMenu(m_hMenu, nPosition, nFlags | (MF_BITMAP | MF_POPUP), (UINT_PTR)hSubMenu, (LPCTSTR)hBmp);
449	}
450
451	BOOL RemoveMenu(UINT nPosition, UINT nFlags)
452	{
453		ATLASSERT(::IsMenu(m_hMenu));
454		return ::RemoveMenu(m_hMenu, nPosition, nFlags);
455	}
456
457	BOOL SetMenuItemBitmaps(UINT nPosition, UINT nFlags, HBITMAP hBmpUnchecked, HBITMAP hBmpChecked)
458	{
459		ATLASSERT(::IsMenu(m_hMenu));
460		return ::SetMenuItemBitmaps(m_hMenu, nPosition, nFlags, hBmpUnchecked, hBmpChecked);
461	}
462
463	BOOL CheckMenuRadioItem(UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags)
464	{
465		ATLASSERT(::IsMenu(m_hMenu));
466		return ::CheckMenuRadioItem(m_hMenu, nIDFirst, nIDLast, nIDItem, nFlags);
467	}
468
469	BOOL GetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii) const
470	{
471		ATLASSERT(::IsMenu(m_hMenu));
472		return (BOOL)::GetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii);
473	}
474
475	BOOL SetMenuItemInfo(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii)
476	{
477		ATLASSERT(::IsMenu(m_hMenu));
478		return (BOOL)::SetMenuItemInfo(m_hMenu, uItem, bByPosition, lpmii);
479	}
480
481	BOOL InsertMenuItem(UINT uItem, BOOL bByPosition, LPMENUITEMINFO lpmii)
482	{
483		ATLASSERT(::IsMenu(m_hMenu));
484		return (BOOL)::InsertMenuItem(m_hMenu, uItem, bByPosition, lpmii);
485	}
486
487	UINT GetMenuDefaultItem(BOOL bByPosition = FALSE, UINT uFlags = 0U) const
488	{
489		ATLASSERT(::IsMenu(m_hMenu));
490		return ::GetMenuDefaultItem(m_hMenu, (UINT)bByPosition, uFlags);
491	}
492
493	BOOL SetMenuDefaultItem(UINT uItem = (UINT)-1,  BOOL bByPosition = FALSE)
494	{
495		ATLASSERT(::IsMenu(m_hMenu));
496		return ::SetMenuDefaultItem(m_hMenu, uItem, (UINT)bByPosition);
497	}
498
499	BOOL GetMenuItemRect(HWND hWnd, UINT uItem, LPRECT lprcItem) const
500	{
501		ATLASSERT(::IsMenu(m_hMenu));
502		return ::GetMenuItemRect(hWnd, m_hMenu, uItem, lprcItem);
503	}
504
505	int MenuItemFromPoint(HWND hWnd, POINT point) const
506	{
507		ATLASSERT(::IsMenu(m_hMenu));
508		return ::MenuItemFromPoint(hWnd, m_hMenu, point);
509	}
510
511// Context Help Functions
512	BOOL SetMenuContextHelpId(DWORD dwContextHelpId)
513	{
514		ATLASSERT(::IsMenu(m_hMenu));
515		return ::SetMenuContextHelpId(m_hMenu, dwContextHelpId);
516	}
517
518	DWORD GetMenuContextHelpId() const
519	{
520		ATLASSERT(::IsMenu(m_hMenu));
521		return ::GetMenuContextHelpId(m_hMenu);
522	}
523};
524
525
526///////////////////////////////////////////////////////////////////////////////
527// CAccelerator
528
529template <bool t_bManaged>
530class CAcceleratorT
531{
532public:
533	HACCEL m_hAccel;
534
535// Constructor/destructor/operators
536	CAcceleratorT(HACCEL hAccel = NULL) : m_hAccel(hAccel)
537	{ }
538
539	~CAcceleratorT()
540	{
541		if(t_bManaged && (m_hAccel != NULL))
542			::DestroyAcceleratorTable(m_hAccel);
543	}
544
545	CAcceleratorT<t_bManaged>& operator =(HACCEL hAccel)
546	{
547		Attach(hAccel);
548		return *this;
549	}
550
551	void Attach(HACCEL hAccel)
552	{
553		if(t_bManaged && (m_hAccel != NULL))
554			::DestroyAcceleratorTable(m_hAccel);
555		m_hAccel = hAccel;
556	}
557
558	HACCEL Detach()
559	{
560		HACCEL hAccel = m_hAccel;
561		m_hAccel = NULL;
562		return hAccel;
563	}
564
565	operator HACCEL() const { return m_hAccel; }
566
567	bool IsNull() const { return m_hAccel == NULL; }
568
569// Create/destroy methods
570	HACCEL LoadAccelerators(ATL::_U_STRINGorID accel)
571	{
572		ATLASSERT(m_hAccel == NULL);
573		m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), accel.m_lpstr);
574		return m_hAccel;
575	}
576
577	HACCEL CreateAcceleratorTable(LPACCEL pAccel, int cEntries)
578	{
579		ATLASSERT(m_hAccel == NULL);
580		ATLASSERT(pAccel != NULL);
581		m_hAccel = ::CreateAcceleratorTable(pAccel, cEntries);
582		return m_hAccel;
583	}
584
585	void DestroyObject()
586	{
587		if(m_hAccel != NULL)
588		{
589			::DestroyAcceleratorTable(m_hAccel);
590			m_hAccel = NULL;
591		}
592	}
593
594// Operations
595	int CopyAcceleratorTable(LPACCEL lpAccelDst, int cEntries)
596	{
597		ATLASSERT(m_hAccel != NULL);
598		ATLASSERT(lpAccelDst != NULL);
599		return ::CopyAcceleratorTable(m_hAccel, lpAccelDst, cEntries);
600	}
601
602	int GetEntriesCount() const
603	{
604		ATLASSERT(m_hAccel != NULL);
605		return ::CopyAcceleratorTable(m_hAccel, NULL, 0);
606	}
607
608	BOOL TranslateAccelerator(HWND hWnd, LPMSG pMsg)
609	{
610		ATLASSERT(m_hAccel != NULL);
611		ATLASSERT(::IsWindow(hWnd));
612		ATLASSERT(pMsg != NULL);
613		return ::TranslateAccelerator(hWnd, m_hAccel, pMsg);
614	}
615};
616
617typedef CAcceleratorT<false>   CAcceleratorHandle;
618typedef CAcceleratorT<true>    CAccelerator;
619
620
621///////////////////////////////////////////////////////////////////////////////
622// CIcon
623
624template <bool t_bManaged>
625class CIconT
626{
627public:
628	HICON m_hIcon;
629
630// Constructor/destructor/operators
631	CIconT(HICON hIcon = NULL) : m_hIcon(hIcon)
632	{ }
633
634	~CIconT()
635	{
636		if(t_bManaged && (m_hIcon != NULL))
637			::DestroyIcon(m_hIcon);
638	}
639
640	CIconT<t_bManaged>& operator =(HICON hIcon)
641	{
642		Attach(hIcon);
643		return *this;
644	}
645
646	void Attach(HICON hIcon)
647	{
648		if(t_bManaged && (m_hIcon != NULL))
649			::DestroyIcon(m_hIcon);
650		m_hIcon = hIcon;
651	}
652
653	HICON Detach()
654	{
655		HICON hIcon = m_hIcon;
656		m_hIcon = NULL;
657		return hIcon;
658	}
659
660	operator HICON() const { return m_hIcon; }
661
662	bool IsNull() const { return m_hIcon == NULL; }
663
664// Create/destroy methods
665	HICON LoadIcon(ATL::_U_STRINGorID icon)
666	{
667		ATLASSERT(m_hIcon == NULL);
668		m_hIcon = ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
669		return m_hIcon;
670	}
671
672	HICON LoadIcon(ATL::_U_STRINGorID icon, int cxDesired, int cyDesired, UINT fuLoad = 0)
673	{
674		ATLASSERT(m_hIcon == NULL);
675		m_hIcon = (HICON) ::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
676		return m_hIcon;
677	}
678
679	HICON LoadOEMIcon(LPCTSTR lpstrIconName)
680	{
681		ATLASSERT(m_hIcon == NULL);
682		ATLASSERT(IsOEMIcon(lpstrIconName));
683		m_hIcon = ::LoadIcon(NULL, lpstrIconName);
684		return m_hIcon;
685	}
686
687	HICON CreateIcon(int nWidth, int nHeight, BYTE cPlanes, BYTE cBitsPixel, CONST BYTE* lpbANDbits, CONST BYTE *lpbXORbits)
688	{
689		ATLASSERT(m_hIcon == NULL);
690		ATLASSERT(lpbANDbits != NULL);
691		ATLASSERT(lpbXORbits != NULL);
692		m_hIcon = ::CreateIcon(ModuleHelper::GetResourceInstance(), nWidth, nHeight, cPlanes, cBitsPixel, lpbANDbits, lpbXORbits);
693		return m_hIcon;
694	}
695
696	HICON CreateIconFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000)
697	{
698		ATLASSERT(m_hIcon == NULL);
699		ATLASSERT(pBits != NULL);
700		m_hIcon = ::CreateIconFromResource(pBits, dwResSize, TRUE, dwVersion);
701		return m_hIcon;
702	}
703
704	HICON CreateIconFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR)
705	{
706		ATLASSERT(m_hIcon == NULL);
707		ATLASSERT(pbBits != NULL);
708		ATLASSERT(cbBits > 0);
709		m_hIcon = ::CreateIconFromResourceEx(pbBits, cbBits, TRUE, dwVersion, cxDesired, cyDesired, uFlags);
710		return m_hIcon;
711	}
712
713	HICON CreateIconIndirect(PICONINFO pIconInfo)
714	{
715		ATLASSERT(m_hIcon == NULL);
716		ATLASSERT(pIconInfo != NULL);
717		m_hIcon = ::CreateIconIndirect(pIconInfo);
718		return m_hIcon;
719	}
720
721	HICON ExtractIcon(LPCTSTR lpszExeFileName, UINT nIconIndex)
722	{
723		ATLASSERT(m_hIcon == NULL);
724		ATLASSERT(lpszExeFileName != NULL);
725		m_hIcon = ::ExtractIcon(ModuleHelper::GetModuleInstance(), lpszExeFileName, nIconIndex);
726		return m_hIcon;
727	}
728
729	HICON ExtractAssociatedIcon(HINSTANCE hInst, LPTSTR lpIconPath, LPWORD lpiIcon)
730	{
731		ATLASSERT(m_hIcon == NULL);
732		ATLASSERT(lpIconPath != NULL);
733		ATLASSERT(lpiIcon != NULL);
734		m_hIcon = ::ExtractAssociatedIcon(hInst, lpIconPath, lpiIcon);
735		return m_hIcon;
736	}
737
738	BOOL DestroyIcon()
739	{
740		ATLASSERT(m_hIcon != NULL);
741		BOOL bRet = ::DestroyIcon(m_hIcon);
742		if(bRet != FALSE)
743			m_hIcon = NULL;
744		return bRet;
745	}
746
747// Operations
748	HICON CopyIcon()
749	{
750		ATLASSERT(m_hIcon != NULL);
751		return ::CopyIcon(m_hIcon);
752	}
753
754	HICON DuplicateIcon()
755	{
756		ATLASSERT(m_hIcon != NULL);
757		return ::DuplicateIcon(NULL, m_hIcon);
758	}
759
760	BOOL DrawIcon(HDC hDC, int x, int y)
761	{
762		ATLASSERT(m_hIcon != NULL);
763		return ::DrawIcon(hDC, x, y, m_hIcon);
764	}
765
766	BOOL DrawIcon(HDC hDC, POINT pt)
767	{
768		ATLASSERT(m_hIcon != NULL);
769		return ::DrawIcon(hDC, pt.x, pt.y, m_hIcon);
770	}
771
772	BOOL DrawIconEx(HDC hDC, int x, int y, int cxWidth, int cyWidth, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
773	{
774		ATLASSERT(m_hIcon != NULL);
775		return ::DrawIconEx(hDC, x, y, m_hIcon, cxWidth, cyWidth, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
776	}
777
778	BOOL DrawIconEx(HDC hDC, POINT pt, SIZE size, UINT uStepIfAniCur = 0, HBRUSH hbrFlickerFreeDraw = NULL, UINT uFlags = DI_NORMAL)
779	{
780		ATLASSERT(m_hIcon != NULL);
781		return ::DrawIconEx(hDC, pt.x, pt.y, m_hIcon, size.cx, size.cy, uStepIfAniCur, hbrFlickerFreeDraw, uFlags);
782	}
783
784	BOOL GetIconInfo(PICONINFO pIconInfo) const
785	{
786		ATLASSERT(m_hIcon != NULL);
787		ATLASSERT(pIconInfo != NULL);
788		return ::GetIconInfo(m_hIcon, pIconInfo);
789	}
790
791#if (_WIN32_WINNT >= 0x0600)
792	BOOL GetIconInfoEx(PICONINFOEX pIconInfo) const
793	{
794		ATLASSERT(m_hIcon != NULL);
795		ATLASSERT(pIconInfo != NULL);
796		return ::GetIconInfoEx(m_hIcon, pIconInfo);
797	}
798#endif // (_WIN32_WINNT >= 0x0600)
799
800#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
801	HRESULT LoadIconMetric(ATL::_U_STRINGorID icon, int lims)
802	{
803		ATLASSERT(m_hIcon == NULL);
804		USES_CONVERSION;
805		return ::LoadIconMetric(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), lims, &m_hIcon);
806	}
807
808	HRESULT LoadIconWithScaleDown(ATL::_U_STRINGorID icon, int cx, int cy)
809	{
810		ATLASSERT(m_hIcon == NULL);
811		USES_CONVERSION;
812		return ::LoadIconWithScaleDown(ModuleHelper::GetResourceInstance(), T2CW(icon.m_lpstr), cx, cy, &m_hIcon);
813	}
814
815	HRESULT LoadOEMIconMetric(LPCTSTR lpstrIconName, int lims)
816	{
817		ATLASSERT(m_hIcon == NULL);
818		ATLASSERT(IsOEMIcon(lpstrIconName));
819		return ::LoadIconMetric(NULL, (LPCWSTR)lpstrIconName, lims, &m_hIcon);
820	}
821
822	HRESULT LoadOEMIconWithScaleDown(LPCTSTR lpstrIconName, int cx, int cy)
823	{
824		ATLASSERT(m_hIcon == NULL);
825		ATLASSERT(IsOEMIcon(lpstrIconName));
826		USES_CONVERSION;
827		return ::LoadIconWithScaleDown(NULL, (LPCWSTR)lpstrIconName, cx, cy, &m_hIcon);
828	}
829#endif // defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_LONGHORN)
830
831	// Helper
832	static bool IsOEMIcon(LPCTSTR lpstrIconName)
833	{
834#if (WINVER >= 0x0600)
835		return ((lpstrIconName == IDI_APPLICATION) || (lpstrIconName == IDI_ASTERISK) || (lpstrIconName == IDI_EXCLAMATION) ||
836		          (lpstrIconName == IDI_HAND) || (lpstrIconName == IDI_QUESTION) || (lpstrIconName == IDI_WINLOGO) ||
837		          (lpstrIconName == IDI_SHIELD));
838#else // !(WINVER >= 0x0600)
839		return ((lpstrIconName == IDI_APPLICATION) || (lpstrIconName == IDI_ASTERISK) || (lpstrIconName == IDI_EXCLAMATION) ||
840		          (lpstrIconName == IDI_HAND) || (lpstrIconName == IDI_QUESTION) || (lpstrIconName == IDI_WINLOGO));
841#endif // !(WINVER >= 0x0600)
842	}
843};
844
845typedef CIconT<false>   CIconHandle;
846typedef CIconT<true>    CIcon;
847
848
849///////////////////////////////////////////////////////////////////////////////
850// CCursor
851
852// protect template member from a winuser.h macro
853#ifdef CopyCursor
854  #undef CopyCursor
855#endif
856
857template <bool t_bManaged>
858class CCursorT
859{
860public:
861	HCURSOR m_hCursor;
862
863// Constructor/destructor/operators
864	CCursorT(HCURSOR hCursor = NULL) : m_hCursor(hCursor)
865	{ }
866
867	~CCursorT()
868	{
869		if(t_bManaged && (m_hCursor != NULL))
870			DestroyCursor();
871	}
872
873	CCursorT<t_bManaged>& operator =(HCURSOR hCursor)
874	{
875		Attach(hCursor);
876		return *this;
877	}
878
879	void Attach(HCURSOR hCursor)
880	{
881		if(t_bManaged && (m_hCursor != NULL))
882			DestroyCursor();
883		m_hCursor = hCursor;
884	}
885
886	HCURSOR Detach()
887	{
888		HCURSOR hCursor = m_hCursor;
889		m_hCursor = NULL;
890		return hCursor;
891	}
892
893	operator HCURSOR() const { return m_hCursor; }
894
895	bool IsNull() const { return m_hCursor == NULL; }
896
897// Create/destroy methods
898	HCURSOR LoadCursor(ATL::_U_STRINGorID cursor)
899	{
900		ATLASSERT(m_hCursor == NULL);
901		m_hCursor = ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr);
902		return m_hCursor;
903	}
904
905	HCURSOR LoadSysCursor(LPCTSTR lpstrCursorName)
906	{
907		ATLASSERT(m_hCursor == NULL);
908		ATLASSERT((lpstrCursorName == IDC_ARROW) || (lpstrCursorName == IDC_IBEAM) || (lpstrCursorName == IDC_WAIT) ||
909			(lpstrCursorName == IDC_CROSS) || (lpstrCursorName == IDC_UPARROW) || (lpstrCursorName == IDC_SIZE) ||
910			(lpstrCursorName == IDC_ICON) || (lpstrCursorName == IDC_SIZENWSE) || (lpstrCursorName == IDC_SIZENESW) ||
911			(lpstrCursorName == IDC_SIZEWE) || (lpstrCursorName == IDC_SIZENS) || (lpstrCursorName == IDC_SIZEALL) ||
912			(lpstrCursorName == IDC_NO) || (lpstrCursorName == IDC_APPSTARTING) || (lpstrCursorName == IDC_HELP) ||
913			(lpstrCursorName == IDC_HAND));
914		m_hCursor = ::LoadCursor(NULL, lpstrCursorName);
915		return m_hCursor;
916	}
917
918	// deprecated
919	HCURSOR LoadOEMCursor(LPCTSTR lpstrCursorName)
920	{
921		return LoadSysCursor(lpstrCursorName);
922	}
923
924	HCURSOR LoadCursor(ATL::_U_STRINGorID cursor, int cxDesired, int cyDesired, UINT fuLoad = 0)
925	{
926		ATLASSERT(m_hCursor == NULL);
927		m_hCursor = (HCURSOR) ::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
928		return m_hCursor;
929	}
930
931	HCURSOR LoadCursorFromFile(LPCTSTR pstrFilename)
932	{
933		ATLASSERT(m_hCursor == NULL);
934		ATLASSERT(pstrFilename != NULL);
935		m_hCursor = ::LoadCursorFromFile(pstrFilename);
936		return m_hCursor;
937	}
938
939	HCURSOR CreateCursor(int xHotSpot, int yHotSpot, int nWidth, int nHeight, CONST VOID *pvANDPlane, CONST VOID *pvXORPlane)
940	{
941		ATLASSERT(m_hCursor == NULL);
942		m_hCursor = ::CreateCursor(ModuleHelper::GetResourceInstance(), xHotSpot, yHotSpot, nWidth, nHeight, pvANDPlane, pvXORPlane);
943		return m_hCursor;
944	}
945
946	HCURSOR CreateCursorFromResource(PBYTE pBits, DWORD dwResSize, DWORD dwVersion = 0x00030000)
947	{
948		ATLASSERT(m_hCursor == NULL);
949		ATLASSERT(pBits != NULL);
950		m_hCursor = (HCURSOR)::CreateIconFromResource(pBits, dwResSize, FALSE, dwVersion);
951		return m_hCursor;
952	}
953
954	HCURSOR CreateCursorFromResourceEx(PBYTE pbBits, DWORD cbBits, DWORD dwVersion = 0x00030000, int cxDesired = 0, int cyDesired = 0, UINT uFlags = LR_DEFAULTCOLOR)
955	{
956		ATLASSERT(m_hCursor == NULL);
957		ATLASSERT(pbBits != NULL);
958		ATLASSERT(cbBits > 0);
959		m_hCursor = (HCURSOR)::CreateIconFromResourceEx(pbBits, cbBits, FALSE, dwVersion, cxDesired, cyDesired, uFlags);
960		return m_hCursor;
961	}
962
963	BOOL DestroyCursor()
964	{
965		ATLASSERT(m_hCursor != NULL);
966		BOOL bRet = ::DestroyCursor(m_hCursor);
967		if(bRet != FALSE)
968			m_hCursor = NULL;
969		return bRet;
970	}
971
972// Operations
973	HCURSOR CopyCursor()
974	{
975		ATLASSERT(m_hCursor != NULL);
976		return (HCURSOR)::CopyIcon((HICON)m_hCursor);
977	}
978
979	BOOL GetCursorInfo(LPCURSORINFO pCursorInfo)
980	{
981		ATLASSERT(m_hCursor != NULL);
982		ATLASSERT(pCursorInfo != NULL);
983		return ::GetCursorInfo(pCursorInfo);
984	}
985};
986
987typedef CCursorT<false>   CCursorHandle;
988typedef CCursorT<true>    CCursor;
989
990
991///////////////////////////////////////////////////////////////////////////////
992// CResource - Wraps a generic Windows resource.
993//             Use it with custom resource types other than the
994//             standard RT_CURSOR, RT_BITMAP, etc.
995
996class CResource
997{
998public:
999	HGLOBAL m_hGlobal;
1000	HRSRC m_hResource;
1001
1002// Constructor/destructor
1003	CResource() : m_hGlobal(NULL), m_hResource(NULL)
1004	{ }
1005
1006	~CResource()
1007	{
1008		Release();
1009	}
1010
1011// Load methods
1012	bool Load(ATL::_U_STRINGorID Type, ATL::_U_STRINGorID ID)
1013	{
1014		ATLASSERT(m_hResource == NULL);
1015		ATLASSERT(m_hGlobal == NULL);
1016
1017		m_hResource = ::FindResource(ModuleHelper::GetResourceInstance(), ID.m_lpstr, Type.m_lpstr);
1018		if(m_hResource == NULL)
1019			return false;
1020
1021		m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource);
1022		if(m_hGlobal == NULL)
1023		{
1024			m_hResource = NULL;
1025			return false;
1026		}
1027
1028		return true;
1029	}
1030
1031	bool LoadEx(ATL::_U_STRINGorID ID, ATL::_U_STRINGorID Type, WORD wLanguage)
1032	{
1033		ATLASSERT(m_hResource == NULL);
1034		ATLASSERT(m_hGlobal == NULL);
1035
1036		m_hResource = ::FindResourceEx(ModuleHelper::GetResourceInstance(), Type.m_lpstr, ID.m_lpstr, wLanguage);
1037		if(m_hResource == NULL)
1038			return false;
1039
1040		m_hGlobal = ::LoadResource(ModuleHelper::GetResourceInstance(), m_hResource);
1041		if(m_hGlobal == NULL)
1042		{
1043			m_hResource = NULL;
1044			return false;
1045		}
1046
1047		return true;
1048	}
1049
1050// Misc. operations
1051	DWORD GetSize() const
1052	{
1053		ATLASSERT(m_hResource != NULL);
1054		return ::SizeofResource(ModuleHelper::GetResourceInstance(), m_hResource);
1055	}
1056
1057	LPVOID Lock()
1058	{
1059		ATLASSERT(m_hResource != NULL);
1060		ATLASSERT(m_hGlobal != NULL);
1061		LPVOID pVoid = ::LockResource(m_hGlobal);
1062		ATLASSERT(pVoid != NULL);
1063		return pVoid;
1064	}
1065
1066	void Release()
1067	{
1068		if(m_hGlobal != NULL)
1069		{
1070			FreeResource(m_hGlobal);
1071			m_hGlobal = NULL;
1072			m_hResource = NULL;
1073		}
1074	}
1075};
1076
1077
1078///////////////////////////////////////////////////////////////////////////////
1079// Toolbar resource descriptor
1080
1081struct _AtlToolBarData
1082{
1083	WORD wVersion;
1084	WORD wWidth;
1085	WORD wHeight;
1086	WORD wItemCount;
1087
1088	WORD* items()
1089		{ return (WORD*)(this+1); }
1090};
1091
1092
1093///////////////////////////////////////////////////////////////////////////////
1094// Global functions for loading resources
1095
1096inline HACCEL AtlLoadAccelerators(ATL::_U_STRINGorID table)
1097{
1098	return ::LoadAccelerators(ModuleHelper::GetResourceInstance(), table.m_lpstr);
1099}
1100
1101inline HMENU AtlLoadMenu(ATL::_U_STRINGorID menu)
1102{
1103	return ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
1104}
1105
1106inline HBITMAP AtlLoadBitmap(ATL::_U_STRINGorID bitmap)
1107{
1108	return ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr);
1109}
1110
1111#ifdef OEMRESOURCE
1112inline HBITMAP AtlLoadSysBitmap(ATL::_U_STRINGorID bitmap)
1113{
1114#ifdef _DEBUG
1115	WORD wID = LOWORD(bitmap.m_lpstr);
1116	ATLASSERT((wID >= 32734) && (wID <= 32767));
1117#endif // _DEBUG
1118	return ::LoadBitmap(NULL, bitmap.m_lpstr);
1119}
1120#endif // OEMRESOURCE
1121
1122inline HCURSOR AtlLoadCursor(ATL::_U_STRINGorID cursor)
1123{
1124	return ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr);
1125}
1126
1127inline HCURSOR AtlLoadSysCursor(LPCTSTR lpCursorName)
1128{
1129	ATLASSERT((lpCursorName == IDC_ARROW) || (lpCursorName == IDC_IBEAM) || (lpCursorName == IDC_WAIT) ||
1130		(lpCursorName == IDC_CROSS) || (lpCursorName == IDC_UPARROW) || (lpCursorName == IDC_SIZE) ||
1131		(lpCursorName == IDC_ICON) || (lpCursorName == IDC_SIZENWSE) || (lpCursorName == IDC_SIZENESW) ||
1132		(lpCursorName == IDC_SIZEWE) || (lpCursorName == IDC_SIZENS) || (lpCursorName == IDC_SIZEALL) ||
1133		(lpCursorName == IDC_NO) || (lpCursorName == IDC_APPSTARTING) || (lpCursorName == IDC_HELP) ||
1134		(lpCursorName == IDC_HAND));
1135	return ::LoadCursor(NULL, lpCursorName);
1136}
1137
1138inline HICON AtlLoadIcon(ATL::_U_STRINGorID icon)
1139{
1140	return ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
1141}
1142
1143inline HICON AtlLoadSysIcon(LPCTSTR lpIconName)
1144{
1145#if (WINVER >= 0x0600)
1146	ATLASSERT((lpIconName == IDI_APPLICATION) || (lpIconName == IDI_ASTERISK) || (lpIconName == IDI_EXCLAMATION) ||
1147	          (lpIconName == IDI_HAND) || (lpIconName == IDI_QUESTION) || (lpIconName == IDI_WINLOGO) ||
1148	          (lpIconName == IDI_SHIELD));
1149#else // !(WINVER >= 0x0600)
1150	ATLASSERT((lpIconName == IDI_APPLICATION) || (lpIconName == IDI_ASTERISK) || (lpIconName == IDI_EXCLAMATION) ||
1151	          (lpIconName == IDI_HAND) || (lpIconName == IDI_QUESTION) || (lpIconName == IDI_WINLOGO));
1152#endif // !(WINVER >= 0x0600)
1153	return ::LoadIcon(NULL, lpIconName);
1154}
1155
1156inline HBITMAP AtlLoadBitmapImage(ATL::_U_STRINGorID bitmap, UINT fuLoad = LR_DEFAULTCOLOR)
1157{
1158	return (HBITMAP)::LoadImage(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr, IMAGE_BITMAP, 0, 0, fuLoad);
1159}
1160
1161inline HCURSOR AtlLoadCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1162{
1163	return (HCURSOR)::LoadImage(ModuleHelper::GetResourceInstance(), cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
1164}
1165
1166inline HICON AtlLoadIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1167{
1168	return (HICON)::LoadImage(ModuleHelper::GetResourceInstance(), icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
1169}
1170
1171#ifdef OEMRESOURCE
1172inline HBITMAP AtlLoadSysBitmapImage(WORD wBitmapID, UINT fuLoad = LR_DEFAULTCOLOR)
1173{
1174	ATLASSERT((wBitmapID >= 32734) && (wBitmapID <= 32767));
1175	ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0);   // this one doesn't load from a file
1176	return (HBITMAP)::LoadImage(NULL, MAKEINTRESOURCE(wBitmapID), IMAGE_BITMAP, 0, 0, fuLoad);
1177}
1178#endif // OEMRESOURCE
1179
1180inline HCURSOR AtlLoadSysCursorImage(ATL::_U_STRINGorID cursor, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1181{
1182#ifdef _DEBUG
1183	WORD wID = LOWORD(cursor.m_lpstr);
1184	ATLASSERT(((wID >= 32512) && (wID <= 32516)) || ((wID >= 32640) && (wID <= 32648)) || (wID == 32650) || (wID == 32651));
1185	ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0);   // this one doesn't load from a file
1186#endif // _DEBUG
1187	return (HCURSOR)::LoadImage(NULL, cursor.m_lpstr, IMAGE_CURSOR, cxDesired, cyDesired, fuLoad);
1188}
1189
1190inline HICON AtlLoadSysIconImage(ATL::_U_STRINGorID icon, UINT fuLoad = LR_DEFAULTCOLOR | LR_DEFAULTSIZE, int cxDesired = 0, int cyDesired = 0)
1191{
1192#ifdef _DEBUG
1193	WORD wID = LOWORD(icon.m_lpstr);
1194	ATLASSERT((wID >= 32512) && (wID <= 32517));
1195	ATLASSERT((fuLoad & LR_LOADFROMFILE) == 0);   // this one doesn't load from a file
1196#endif // _DEBUG
1197	return (HICON)::LoadImage(NULL, icon.m_lpstr, IMAGE_ICON, cxDesired, cyDesired, fuLoad);
1198}
1199
1200inline bool AtlLoadString(UINT uID, BSTR& bstrText)
1201{
1202	USES_CONVERSION;
1203	ATLASSERT(bstrText == NULL);
1204
1205	LPTSTR lpstrText = NULL;
1206	int nRes = 0;
1207	for(int nLen = 256; ; nLen *= 2)
1208	{
1209		ATLTRY(lpstrText = new TCHAR[nLen]);
1210		if(lpstrText == NULL)
1211			break;
1212		nRes = ::LoadString(ModuleHelper::GetResourceInstance(), uID, lpstrText, nLen);
1213		if(nRes < nLen - 1)
1214			break;
1215		delete [] lpstrText;
1216		lpstrText = NULL;
1217	}
1218
1219	if(lpstrText != NULL)
1220	{
1221		if(nRes != 0)
1222			bstrText = ::SysAllocString(T2OLE(lpstrText));
1223		delete [] lpstrText;
1224	}
1225
1226	return (bstrText != NULL) ? true : false;
1227}
1228
1229} // namespace WTL
1230
1231#endif // __ATLUSER_H__