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 
49 namespace WTL
50 {
51 
52 ///////////////////////////////////////////////////////////////////////////////
53 // AtlMessageBox - accepts both memory and resource based strings
54 
55 inline 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 
113 class CMenuItemInfo : public MENUITEMINFO
114 {
115 public:
CMenuItemInfo()116 	CMenuItemInfo()
117 	{
118 		memset(this, 0, sizeof(MENUITEMINFO));
119 		cbSize = sizeof(MENUITEMINFO);
120 	}
121 };
122 
123 
124 // forward declarations
125 template <bool t_bManaged> class CMenuT;
126 typedef CMenuT<false>   CMenuHandle;
127 typedef CMenuT<true>    CMenu;
128 
129 
130 template <bool t_bManaged>
131 class CMenuT
132 {
133 public:
134 // Data members
135 	HMENU m_hMenu;
136 
137 // Constructor/destructor/operators
m_hMenu(hMenu)138 	CMenuT(HMENU hMenu = NULL) : m_hMenu(hMenu)
139 	{ }
140 
~CMenuT()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 
Attach(HMENU hMenuNew)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 
Detach()161 	HMENU Detach()
162 	{
163 		HMENU hMenu = m_hMenu;
164 		m_hMenu = NULL;
165 		return hMenu;
166 	}
167 
HMENU()168 	operator HMENU() const { return m_hMenu; }
169 
IsNull()170 	bool IsNull() const { return (m_hMenu == NULL); }
171 
IsMenu()172 	BOOL IsMenu() const
173 	{
174 		return ::IsMenu(m_hMenu);
175 	}
176 
177 // Create/destroy methods
CreateMenu()178 	BOOL CreateMenu()
179 	{
180 		ATLASSERT(m_hMenu == NULL);
181 		m_hMenu = ::CreateMenu();
182 		return (m_hMenu != NULL) ? TRUE : FALSE;
183 	}
184 
CreatePopupMenu()185 	BOOL CreatePopupMenu()
186 	{
187 		ATLASSERT(m_hMenu == NULL);
188 		m_hMenu = ::CreatePopupMenu();
189 		return (m_hMenu != NULL) ? TRUE : FALSE;
190 	}
191 
LoadMenu(ATL::_U_STRINGorID menu)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 
LoadMenuIndirect(const void * lpMenuTemplate)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 
DestroyMenu()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
DeleteMenu(UINT nPosition,UINT nFlags)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
_FixTrackMenuPopupX(int x,int y)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 
GetMenuInfo(LPMENUINFO lpMenuInfo)261 	BOOL GetMenuInfo(LPMENUINFO lpMenuInfo) const
262 	{
263 		ATLASSERT(::IsMenu(m_hMenu));
264 		return ::GetMenuInfo(m_hMenu, lpMenuInfo);
265 	}
266 
SetMenuInfo(LPCMENUINFO lpMenuInfo)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 
AppendMenu(UINT nFlags,HMENU hSubMenu,LPCTSTR lpszNewItem)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 
AppendMenu(UINT nFlags,UINT_PTR nIDNewItem,HBITMAP hBmp)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 
AppendMenu(UINT nFlags,HMENU hSubMenu,HBITMAP hBmp)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 
CheckMenuItem(UINT nIDCheckItem,UINT nCheck)300 	UINT CheckMenuItem(UINT nIDCheckItem, UINT nCheck)
301 	{
302 		ATLASSERT(::IsMenu(m_hMenu));
303 		return (UINT)::CheckMenuItem(m_hMenu, nIDCheckItem, nCheck);
304 	}
305 
EnableMenuItem(UINT nIDEnableItem,UINT nEnable)306 	UINT EnableMenuItem(UINT nIDEnableItem, UINT nEnable)
307 	{
308 		ATLASSERT(::IsMenu(m_hMenu));
309 		return ::EnableMenuItem(m_hMenu, nIDEnableItem, nEnable);
310 	}
311 
HiliteMenuItem(HWND hWnd,UINT uIDHiliteItem,UINT uHilite)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 
GetMenuItemCount()318 	int GetMenuItemCount() const
319 	{
320 		ATLASSERT(::IsMenu(m_hMenu));
321 		return ::GetMenuItemCount(m_hMenu);
322 	}
323 
GetMenuItemID(int nPos)324 	UINT GetMenuItemID(int nPos) const
325 	{
326 		ATLASSERT(::IsMenu(m_hMenu));
327 		return ::GetMenuItemID(m_hMenu, nPos);
328 	}
329 
GetMenuState(UINT nID,UINT nFlags)330 	UINT GetMenuState(UINT nID, UINT nFlags) const
331 	{
332 		ATLASSERT(::IsMenu(m_hMenu));
333 		return ::GetMenuState(m_hMenu, nID, nFlags);
334 	}
335 
GetMenuString(UINT nIDItem,LPTSTR lpString,int nMaxCount,UINT nFlags)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 
GetMenuStringLen(UINT nIDItem,UINT nFlags)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 
GetMenuString(UINT nIDItem,BSTR & bstrText,UINT nFlags)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__
GetMenuString(UINT nIDItem,ATL::CString & strText,UINT nFlags)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 
GetSubMenu(int nPos)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 
InsertMenu(UINT nPosition,UINT nFlags,HMENU hSubMenu,LPCTSTR lpszNewItem)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 
InsertMenu(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem,HBITMAP hBmp)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 
InsertMenu(UINT nPosition,UINT nFlags,HMENU hSubMenu,HBITMAP hBmp)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 
ModifyMenu(UINT nPosition,UINT nFlags,HMENU hSubMenu,LPCTSTR lpszNewItem)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 
ModifyMenu(UINT nPosition,UINT nFlags,UINT_PTR nIDNewItem,HBITMAP hBmp)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 
ModifyMenu(UINT nPosition,UINT nFlags,HMENU hSubMenu,HBITMAP hBmp)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 
RemoveMenu(UINT nPosition,UINT nFlags)451 	BOOL RemoveMenu(UINT nPosition, UINT nFlags)
452 	{
453 		ATLASSERT(::IsMenu(m_hMenu));
454 		return ::RemoveMenu(m_hMenu, nPosition, nFlags);
455 	}
456 
SetMenuItemBitmaps(UINT nPosition,UINT nFlags,HBITMAP hBmpUnchecked,HBITMAP hBmpChecked)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 
CheckMenuRadioItem(UINT nIDFirst,UINT nIDLast,UINT nIDItem,UINT nFlags)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 
GetMenuItemInfo(UINT uItem,BOOL bByPosition,LPMENUITEMINFO lpmii)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 
SetMenuItemInfo(UINT uItem,BOOL bByPosition,LPMENUITEMINFO lpmii)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 
InsertMenuItem(UINT uItem,BOOL bByPosition,LPMENUITEMINFO lpmii)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 
GetMenuItemRect(HWND hWnd,UINT uItem,LPRECT lprcItem)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 
MenuItemFromPoint(HWND hWnd,POINT point)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
SetMenuContextHelpId(DWORD dwContextHelpId)512 	BOOL SetMenuContextHelpId(DWORD dwContextHelpId)
513 	{
514 		ATLASSERT(::IsMenu(m_hMenu));
515 		return ::SetMenuContextHelpId(m_hMenu, dwContextHelpId);
516 	}
517 
GetMenuContextHelpId()518 	DWORD GetMenuContextHelpId() const
519 	{
520 		ATLASSERT(::IsMenu(m_hMenu));
521 		return ::GetMenuContextHelpId(m_hMenu);
522 	}
523 };
524 
525 
526 ///////////////////////////////////////////////////////////////////////////////
527 // CAccelerator
528 
529 template <bool t_bManaged>
530 class CAcceleratorT
531 {
532 public:
533 	HACCEL m_hAccel;
534 
535 // Constructor/destructor/operators
m_hAccel(hAccel)536 	CAcceleratorT(HACCEL hAccel = NULL) : m_hAccel(hAccel)
537 	{ }
538 
~CAcceleratorT()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 
Attach(HACCEL hAccel)551 	void Attach(HACCEL hAccel)
552 	{
553 		if(t_bManaged && (m_hAccel != NULL))
554 			::DestroyAcceleratorTable(m_hAccel);
555 		m_hAccel = hAccel;
556 	}
557 
Detach()558 	HACCEL Detach()
559 	{
560 		HACCEL hAccel = m_hAccel;
561 		m_hAccel = NULL;
562 		return hAccel;
563 	}
564 
HACCEL()565 	operator HACCEL() const { return m_hAccel; }
566 
IsNull()567 	bool IsNull() const { return m_hAccel == NULL; }
568 
569 // Create/destroy methods
LoadAccelerators(ATL::_U_STRINGorID accel)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 
CreateAcceleratorTable(LPACCEL pAccel,int cEntries)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 
DestroyObject()585 	void DestroyObject()
586 	{
587 		if(m_hAccel != NULL)
588 		{
589 			::DestroyAcceleratorTable(m_hAccel);
590 			m_hAccel = NULL;
591 		}
592 	}
593 
594 // Operations
CopyAcceleratorTable(LPACCEL lpAccelDst,int cEntries)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 
GetEntriesCount()602 	int GetEntriesCount() const
603 	{
604 		ATLASSERT(m_hAccel != NULL);
605 		return ::CopyAcceleratorTable(m_hAccel, NULL, 0);
606 	}
607 
TranslateAccelerator(HWND hWnd,LPMSG pMsg)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 
617 typedef CAcceleratorT<false>   CAcceleratorHandle;
618 typedef CAcceleratorT<true>    CAccelerator;
619 
620 
621 ///////////////////////////////////////////////////////////////////////////////
622 // CIcon
623 
624 template <bool t_bManaged>
625 class CIconT
626 {
627 public:
628 	HICON m_hIcon;
629 
630 // Constructor/destructor/operators
m_hIcon(hIcon)631 	CIconT(HICON hIcon = NULL) : m_hIcon(hIcon)
632 	{ }
633 
~CIconT()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 
Attach(HICON hIcon)646 	void Attach(HICON hIcon)
647 	{
648 		if(t_bManaged && (m_hIcon != NULL))
649 			::DestroyIcon(m_hIcon);
650 		m_hIcon = hIcon;
651 	}
652 
Detach()653 	HICON Detach()
654 	{
655 		HICON hIcon = m_hIcon;
656 		m_hIcon = NULL;
657 		return hIcon;
658 	}
659 
HICON()660 	operator HICON() const { return m_hIcon; }
661 
IsNull()662 	bool IsNull() const { return m_hIcon == NULL; }
663 
664 // Create/destroy methods
LoadIcon(ATL::_U_STRINGorID icon)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 
LoadOEMIcon(LPCTSTR lpstrIconName)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 
CreateIcon(int nWidth,int nHeight,BYTE cPlanes,BYTE cBitsPixel,CONST BYTE * lpbANDbits,CONST BYTE * lpbXORbits)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 
CreateIconIndirect(PICONINFO pIconInfo)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 
ExtractIcon(LPCTSTR lpszExeFileName,UINT nIconIndex)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 
ExtractAssociatedIcon(HINSTANCE hInst,LPTSTR lpIconPath,LPWORD lpiIcon)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 
DestroyIcon()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
CopyIcon()748 	HICON CopyIcon()
749 	{
750 		ATLASSERT(m_hIcon != NULL);
751 		return ::CopyIcon(m_hIcon);
752 	}
753 
DuplicateIcon()754 	HICON DuplicateIcon()
755 	{
756 		ATLASSERT(m_hIcon != NULL);
757 		return ::DuplicateIcon(NULL, m_hIcon);
758 	}
759 
DrawIcon(HDC hDC,int x,int y)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 
DrawIcon(HDC hDC,POINT pt)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 
GetIconInfo(PICONINFO pIconInfo)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)
GetIconInfoEx(PICONINFOEX pIconInfo)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)
LoadIconMetric(ATL::_U_STRINGorID icon,int lims)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 
LoadIconWithScaleDown(ATL::_U_STRINGorID icon,int cx,int cy)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 
LoadOEMIconMetric(LPCTSTR lpstrIconName,int lims)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 
LoadOEMIconWithScaleDown(LPCTSTR lpstrIconName,int cx,int cy)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
IsOEMIcon(LPCTSTR lpstrIconName)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 
845 typedef CIconT<false>   CIconHandle;
846 typedef 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 
857 template <bool t_bManaged>
858 class CCursorT
859 {
860 public:
861 	HCURSOR m_hCursor;
862 
863 // Constructor/destructor/operators
m_hCursor(hCursor)864 	CCursorT(HCURSOR hCursor = NULL) : m_hCursor(hCursor)
865 	{ }
866 
~CCursorT()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 
Attach(HCURSOR hCursor)879 	void Attach(HCURSOR hCursor)
880 	{
881 		if(t_bManaged && (m_hCursor != NULL))
882 			DestroyCursor();
883 		m_hCursor = hCursor;
884 	}
885 
Detach()886 	HCURSOR Detach()
887 	{
888 		HCURSOR hCursor = m_hCursor;
889 		m_hCursor = NULL;
890 		return hCursor;
891 	}
892 
HCURSOR()893 	operator HCURSOR() const { return m_hCursor; }
894 
IsNull()895 	bool IsNull() const { return m_hCursor == NULL; }
896 
897 // Create/destroy methods
LoadCursor(ATL::_U_STRINGorID cursor)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 
LoadSysCursor(LPCTSTR lpstrCursorName)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
LoadOEMCursor(LPCTSTR lpstrCursorName)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 
LoadCursorFromFile(LPCTSTR pstrFilename)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 
CreateCursor(int xHotSpot,int yHotSpot,int nWidth,int nHeight,CONST VOID * pvANDPlane,CONST VOID * pvXORPlane)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 
DestroyCursor()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
CopyCursor()973 	HCURSOR CopyCursor()
974 	{
975 		ATLASSERT(m_hCursor != NULL);
976 		return (HCURSOR)::CopyIcon((HICON)m_hCursor);
977 	}
978 
GetCursorInfo(LPCURSORINFO pCursorInfo)979 	BOOL GetCursorInfo(LPCURSORINFO pCursorInfo)
980 	{
981 		ATLASSERT(m_hCursor != NULL);
982 		ATLASSERT(pCursorInfo != NULL);
983 		return ::GetCursorInfo(pCursorInfo);
984 	}
985 };
986 
987 typedef CCursorT<false>   CCursorHandle;
988 typedef 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 
996 class CResource
997 {
998 public:
999 	HGLOBAL m_hGlobal;
1000 	HRSRC m_hResource;
1001 
1002 // Constructor/destructor
CResource()1003 	CResource() : m_hGlobal(NULL), m_hResource(NULL)
1004 	{ }
1005 
~CResource()1006 	~CResource()
1007 	{
1008 		Release();
1009 	}
1010 
1011 // Load methods
Load(ATL::_U_STRINGorID Type,ATL::_U_STRINGorID ID)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 
LoadEx(ATL::_U_STRINGorID ID,ATL::_U_STRINGorID Type,WORD wLanguage)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
GetSize()1051 	DWORD GetSize() const
1052 	{
1053 		ATLASSERT(m_hResource != NULL);
1054 		return ::SizeofResource(ModuleHelper::GetResourceInstance(), m_hResource);
1055 	}
1056 
Lock()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 
Release()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 
1081 struct _AtlToolBarData
1082 {
1083 	WORD wVersion;
1084 	WORD wWidth;
1085 	WORD wHeight;
1086 	WORD wItemCount;
1087 
items_AtlToolBarData1088 	WORD* items()
1089 		{ return (WORD*)(this+1); }
1090 };
1091 
1092 
1093 ///////////////////////////////////////////////////////////////////////////////
1094 // Global functions for loading resources
1095 
AtlLoadAccelerators(ATL::_U_STRINGorID table)1096 inline HACCEL AtlLoadAccelerators(ATL::_U_STRINGorID table)
1097 {
1098 	return ::LoadAccelerators(ModuleHelper::GetResourceInstance(), table.m_lpstr);
1099 }
1100 
AtlLoadMenu(ATL::_U_STRINGorID menu)1101 inline HMENU AtlLoadMenu(ATL::_U_STRINGorID menu)
1102 {
1103 	return ::LoadMenu(ModuleHelper::GetResourceInstance(), menu.m_lpstr);
1104 }
1105 
AtlLoadBitmap(ATL::_U_STRINGorID bitmap)1106 inline HBITMAP AtlLoadBitmap(ATL::_U_STRINGorID bitmap)
1107 {
1108 	return ::LoadBitmap(ModuleHelper::GetResourceInstance(), bitmap.m_lpstr);
1109 }
1110 
1111 #ifdef OEMRESOURCE
AtlLoadSysBitmap(ATL::_U_STRINGorID bitmap)1112 inline 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 
AtlLoadCursor(ATL::_U_STRINGorID cursor)1122 inline HCURSOR AtlLoadCursor(ATL::_U_STRINGorID cursor)
1123 {
1124 	return ::LoadCursor(ModuleHelper::GetResourceInstance(), cursor.m_lpstr);
1125 }
1126 
AtlLoadSysCursor(LPCTSTR lpCursorName)1127 inline 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 
AtlLoadIcon(ATL::_U_STRINGorID icon)1138 inline HICON AtlLoadIcon(ATL::_U_STRINGorID icon)
1139 {
1140 	return ::LoadIcon(ModuleHelper::GetResourceInstance(), icon.m_lpstr);
1141 }
1142 
AtlLoadSysIcon(LPCTSTR lpIconName)1143 inline 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 
1156 inline 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 
1161 inline 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 
1166 inline 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
1172 inline 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 
1180 inline 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 
1190 inline 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 
AtlLoadString(UINT uID,BSTR & bstrText)1200 inline 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__
1232