Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: third_party/wtl/include/atlframe.h

Issue 703753005: More Windows build fixes. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: remove generated files Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/wtl/include/atlfind.h ('k') | third_party/wtl/include/atlgdi.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Windows Template Library - WTL version 8.0
2 // Copyright (C) Microsoft Corporation. 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 Permissive License (Ms-PL) which can be found in the file
7 // Ms-PL.txt at the root of this distribution.
8
9 #ifndef __ATLFRAME_H__
10 #define __ATLFRAME_H__
11
12 #pragma once
13
14 #ifndef __cplusplus
15 #error ATL requires C++ compilation (use a .cpp suffix)
16 #endif
17
18 #ifndef __ATLAPP_H__
19 #error atlframe.h requires atlapp.h to be included first
20 #endif
21
22 #ifndef __ATLWIN_H__
23 #error atlframe.h requires atlwin.h to be included first
24 #endif
25
26
27 ///////////////////////////////////////////////////////////////////////////////
28 // Classes in this file:
29 //
30 // CFrameWindowImpl<T, TBase, TWinTraits>
31 // CMDIWindow
32 // CMDIFrameWindowImpl<T, TBase, TWinTraits>
33 // CMDIChildWindowImpl<T, TBase, TWinTraits>
34 // COwnerDraw<T>
35 // CUpdateUIBase
36 // CUpdateUI<T>
37 // CDynamicUpdateUI<T>
38 // CDialogResize<T>
39 // CDoubleBufferImpl<T>
40 // CDoubleBufferWindowImpl<T, TBase, TWinTraits>
41 //
42 // Global functions:
43 // AtlCreateSimpleToolBar()
44
45
46 namespace WTL
47 {
48
49 ///////////////////////////////////////////////////////////////////////////////
50 // CFrameWndClassInfo - Manages frame window Windows class information
51
52 class CFrameWndClassInfo
53 {
54 public:
55 #ifndef _WIN32_WCE
56 enum { cchAutoName = 5 + sizeof(void*) * 2 }; // sizeof(void*) * 2 is the number of digits %p outputs
57 WNDCLASSEX m_wc;
58 #else // CE specific
59 enum { cchAutoName = MAX_PATH }; // MAX_PATH because this can be set i n the wizard generated CMainFrame::ActivatePreviousInstance to a user defined st ring.
60 WNDCLASS m_wc;
61 #endif // !_WIN32_WCE
62 LPCTSTR m_lpszOrigName;
63 WNDPROC pWndProc;
64 LPCTSTR m_lpszCursorID;
65 BOOL m_bSystemCursor;
66 ATOM m_atom;
67 TCHAR m_szAutoName[cchAutoName];
68 UINT m_uCommonResourceID;
69
70 #ifndef _WIN32_WCE
71 ATOM Register(WNDPROC* pProc)
72 {
73 if (m_atom == 0)
74 {
75 CWindowCreateCriticalSectionLock lock;
76 if(FAILED(lock.Lock()))
77 {
78 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l ock critical section in CFrameWndClassInfo::Register.\n"));
79 ATLASSERT(FALSE);
80 return 0;
81 }
82
83 if(m_atom == 0)
84 {
85 HINSTANCE hInst = ModuleHelper::GetModuleInstanc e();
86
87 if (m_lpszOrigName != NULL)
88 {
89 ATLASSERT(pProc != NULL);
90 LPCTSTR lpsz = m_wc.lpszClassName;
91 WNDPROC proc = m_wc.lpfnWndProc;
92
93 WNDCLASSEX wc = { 0 };
94 wc.cbSize = sizeof(WNDCLASSEX);
95 // try process local class first
96 if(!::GetClassInfoEx(ModuleHelper::GetMo duleInstance(), m_lpszOrigName, &wc))
97 {
98 // try global class
99 if(!::GetClassInfoEx(NULL, m_lps zOrigName, &wc))
100 {
101 lock.Unlock();
102 return 0;
103 }
104 }
105 m_wc = wc;
106 pWndProc = m_wc.lpfnWndProc;
107 m_wc.lpszClassName = lpsz;
108 m_wc.lpfnWndProc = proc;
109 }
110 else
111 {
112 m_wc.hCursor = ::LoadCursor(m_bSystemCur sor ? NULL : hInst, m_lpszCursorID);
113 }
114
115 m_wc.hInstance = hInst;
116 m_wc.style &= ~CS_GLOBALCLASS; // we don't reg ister global classes
117 if (m_wc.lpszClassName == NULL)
118 {
119 #if (_WIN32_WINNT >= 0x0500) || defined(_WIN64)
120 SecureHelper::wsprintf_x(m_szAutoName, c chAutoName, _T("ATL:%p"), &m_wc);
121 #else // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64))
122 SecureHelper::wsprintf_x(m_szAutoName, c chAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc);
123 #endif // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64))
124 m_wc.lpszClassName = m_szAutoName;
125 }
126
127 WNDCLASSEX wcTemp = m_wc;
128 m_atom = (ATOM)::GetClassInfoEx(m_wc.hInstance, m_wc.lpszClassName, &wcTemp);
129 if (m_atom == 0)
130 {
131 if(m_uCommonResourceID != 0) // use it if not zero
132 {
133 m_wc.hIcon = (HICON)::LoadImage( ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE _ICON, 32, 32, LR_DEFAULTCOLOR);
134 m_wc.hIconSm = (HICON)::LoadImag e(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMA GE_ICON, 16, 16, LR_DEFAULTCOLOR);
135 }
136 m_atom = ::RegisterClassEx(&m_wc);
137 }
138 }
139
140 lock.Unlock();
141 }
142
143 if (m_lpszOrigName != NULL)
144 {
145 ATLASSERT(pProc != NULL);
146 ATLASSERT(pWndProc != NULL);
147 *pProc = pWndProc;
148 }
149
150 return m_atom;
151 }
152 #else // CE specific
153 ATOM Register(WNDPROC* pProc)
154 {
155 if (m_atom == 0)
156 {
157 CWindowCreateCriticalSectionLock lock;
158 if(FAILED(lock.Lock()))
159 {
160 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l ock critical section in CFrameWndClassInfo::Register.\n"));
161 ATLASSERT(FALSE);
162 return 0;
163 }
164
165 if(m_atom == 0)
166 {
167 HINSTANCE hInst = ModuleHelper::GetModuleInstanc e();
168
169 if (m_lpszOrigName != NULL)
170 {
171 ATLASSERT(pProc != NULL);
172 LPCTSTR lpsz = m_wc.lpszClassName;
173 WNDPROC proc = m_wc.lpfnWndProc;
174
175 WNDCLASS wc = { 0 };
176 // try process local class first
177 if(!::GetClassInfo(ModuleHelper::GetModu leInstance(), m_lpszOrigName, &wc))
178 {
179 // try global class
180 if(!::GetClassInfo(NULL, m_lpszO rigName, &wc))
181 {
182 lock.Unlock();
183 return 0;
184 }
185 }
186 m_wc = wc;
187 pWndProc = m_wc.lpfnWndProc;
188 m_wc.lpszClassName = lpsz;
189 m_wc.lpfnWndProc = proc;
190 }
191 else
192 {
193 #if defined(GWES_CURSOR) || defined(GWES_MCURSOR)
194 m_wc.hCursor = ::LoadCursor(m_bSystemCur sor ? NULL : hInst, m_lpszCursorID);
195 #else // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR))
196 m_wc.hCursor = NULL;
197 #endif // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR))
198 }
199
200 m_wc.hInstance = hInst;
201 m_wc.style &= ~CS_GLOBALCLASS; // we don't reg ister global classes
202 if (m_wc.lpszClassName == NULL)
203 {
204 wsprintf(m_szAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc);
205 m_wc.lpszClassName = m_szAutoName;
206 }
207
208 WNDCLASS wcTemp = m_wc;
209 m_atom = (ATOM)::GetClassInfo(m_wc.hInstance, m_ wc.lpszClassName, &wcTemp);
210 if (m_atom == 0)
211 {
212 if(m_uCommonResourceID != 0) // use it if not zero
213 m_wc.hIcon = (HICON)::LoadImage( ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE _ICON, 32, 32, LR_DEFAULTCOLOR);
214 m_atom = ::RegisterClass(&m_wc);
215 }
216 }
217
218 lock.Unlock();
219 }
220
221 if (m_lpszOrigName != NULL)
222 {
223 ATLASSERT(pProc != NULL);
224 ATLASSERT(pWndProc != NULL);
225 *pProc = pWndProc;
226 }
227
228 return m_atom;
229 }
230 #endif // _WIN32_WCE
231 };
232
233
234 ///////////////////////////////////////////////////////////////////////////////
235 // Macros for declaring frame window WNDCLASS
236
237 #ifndef _WIN32_WCE
238
239 #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
240 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
241 { \
242 static WTL::CFrameWndClassInfo wc = \
243 { \
244 { sizeof(WNDCLASSEX), 0, StartWindowProc, \
245 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndC lassName, NULL }, \
246 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
247 }; \
248 return wc; \
249 }
250
251 #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd ) \
252 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
253 { \
254 static WTL::CFrameWndClassInfo wc = \
255 { \
256 { sizeof(WNDCLASSEX), style, StartWindowProc, \
257 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassNam e, NULL }, \
258 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
259 }; \
260 return wc; \
261 }
262
263 #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonReso urceID) \
264 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
265 { \
266 static WTL::CFrameWndClassInfo wc = \
267 { \
268 { sizeof(WNDCLASSEX), 0, StartWindowProc, \
269 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \
270 OrigWndClassName, NULL, NULL, TRUE, 0, _T(""), uCommonResourceID \
271 }; \
272 return wc; \
273 }
274
275 #else // CE specific
276
277 #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \
278 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
279 { \
280 static WTL::CFrameWndClassInfo wc = \
281 { \
282 { 0, StartWindowProc, \
283 0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndC lassName }, \
284 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
285 }; \
286 return wc; \
287 }
288
289 #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd ) \
290 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
291 { \
292 static WTL::CFrameWndClassInfo wc = \
293 { \
294 { style, StartWindowProc, \
295 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassNam e }, \
296 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \
297 }; \
298 return wc; \
299 }
300
301 #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonReso urceID) \
302 static WTL::CFrameWndClassInfo& GetWndClassInfo() \
303 { \
304 static WTL::CFrameWndClassInfo wc = \
305 { \
306 { NULL, StartWindowProc, \
307 0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName }, \
308 OrigWndClassName, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResou rceID \
309 }; \
310 return wc; \
311 }
312
313 #endif // !_WIN32_WCE
314
315
316 ///////////////////////////////////////////////////////////////////////////////
317 // CFrameWindowImpl
318
319 // Client window command chaining macro (only for frame windows)
320 #define CHAIN_CLIENT_COMMANDS() \
321 if(uMsg == WM_COMMAND && m_hWndClient != NULL) \
322 ::SendMessage(m_hWndClient, uMsg, wParam, lParam);
323
324 // standard toolbar styles
325 #define ATL_SIMPLE_TOOLBAR_STYLE \
326 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOO LTIPS)
327 // toolbar in a rebar pane
328 #define ATL_SIMPLE_TOOLBAR_PANE_STYLE \
329 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVID ER | CCS_NORESIZE | CCS_NOPARENTALIGN | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT)
330 // standard rebar styles
331 #if (_WIN32_IE >= 0x0400)
332 #define ATL_SIMPLE_REBAR_STYLE \
333 (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE)
334 #else
335 #define ATL_SIMPLE_REBAR_STYLE \
336 (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIGHT | RBS_BANDBORDERS)
337 #endif // !(_WIN32_IE >= 0x0400)
338 // rebar without borders
339 #if (_WIN32_IE >= 0x0400)
340 #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \
341 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIG HT | RBS_BANDBORDERS | RBS_AUTOSIZE | CCS_NODIVIDER)
342 #else
343 #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \
344 (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIG HT | RBS_BANDBORDERS | CCS_NODIVIDER)
345 #endif // !(_WIN32_IE >= 0x0400)
346
347 // command bar support
348 #if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
349
350 #define CBRM_GETCMDBAR (WM_USER + 301) // returns command bar H WND
351 #define CBRM_GETMENU (WM_USER + 302) // returns loaded or att ached menu
352 #define CBRM_TRACKPOPUPMENU (WM_USER + 303) // displays a popup menu
353
354 struct _AtlFrameWnd_CmdBarPopupMenu
355 {
356 int cbSize;
357 HMENU hMenu;
358 UINT uFlags;
359 int x;
360 int y;
361 LPTPMPARAMS lptpm;
362 };
363
364 #define CBRPOPUPMENU _AtlFrameWnd_CmdBarPopupMenu
365
366 #endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
367
368
369 template <class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits>
370 class ATL_NO_VTABLE CFrameWindowImplBase : public ATL::CWindowImplBaseT< TBase, TWinTraits >
371 {
372 public:
373 DECLARE_FRAME_WND_CLASS(NULL, 0)
374
375 // Data members
376 HWND m_hWndToolBar;
377 HWND m_hWndStatusBar;
378 HWND m_hWndClient;
379
380 HACCEL m_hAccel;
381
382 #ifdef _WIN32_WCE
383 HWND m_hWndCECommandBar;
384 #endif // _WIN32_WCE
385
386 struct _AtlToolBarData
387 {
388 WORD wVersion;
389 WORD wWidth;
390 WORD wHeight;
391 WORD wItemCount;
392 //WORD aItems[wItemCount]
393
394 WORD* items()
395 { return (WORD*)(this+1); }
396 };
397
398 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
399 struct _ChevronMenuInfo
400 {
401 HMENU hMenu;
402 LPNMREBARCHEVRON lpnm;
403 bool bCmdBar;
404 };
405 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
406
407 // Constructor
408 CFrameWindowImplBase() :
409 #ifdef _WIN32_WCE
410 m_hWndCECommandBar(NULL),
411 #endif // _WIN32_WCE
412 m_hWndToolBar(NULL),
413 m_hWndStatusBar(NULL),
414 m_hWndClient(NULL),
415 m_hAccel(NULL)
416 { }
417
418 // Methods
419 HWND Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DW ORD dwStyle, DWORD dwExStyle, ATL::_U_MENUorID MenuOrID, ATOM atom, LPVOID lpCre ateParam)
420 {
421 ATLASSERT(m_hWnd == NULL);
422
423 if(atom == 0)
424 return NULL;
425
426 ModuleHelper::AddCreateWndData(&m_thunk.cd, this);
427
428 if(MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD))
429 MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this;
430 if(rect.m_lpRect == NULL)
431 rect.m_lpRect = &TBase::rcDefault;
432
433 HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWin dowName,
434 dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m _lpRect->right - rect.m_lpRect->left,
435 rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, MenuOrID.m_hMenu,
436 ModuleHelper::GetModuleInstance(), lpCreateParam);
437
438 ATLASSERT(hWnd == NULL || m_hWnd == hWnd);
439
440 return hWnd;
441 }
442
443 static HWND CreateSimpleToolBarCtrl(HWND hWndParent, UINT nResourceID, B OOL bInitialSeparator = FALSE,
444 DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL _IDW_TOOLBAR)
445 {
446 HINSTANCE hInst = ModuleHelper::GetResourceInstance();
447 HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID) , RT_TOOLBAR);
448 if (hRsrc == NULL)
449 return NULL;
450
451 HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc);
452 if (hGlobal == NULL)
453 return NULL;
454
455 _AtlToolBarData* pData = (_AtlToolBarData*)::LockResource(hGloba l);
456 if (pData == NULL)
457 return NULL;
458 ATLASSERT(pData->wVersion == 1);
459
460 WORD* pItems = pData->items();
461 int nItems = pData->wItemCount + (bInitialSeparator ? 1 : 0);
462 CTempBuffer<TBBUTTON, _WTL_STACK_ALLOC_THRESHOLD> buff;
463 TBBUTTON* pTBBtn = buff.Allocate(nItems);
464 ATLASSERT(pTBBtn != NULL);
465 if(pTBBtn == NULL)
466 return NULL;
467
468 const int cxSeparator = 8;
469
470 // set initial separator (half width)
471 if(bInitialSeparator)
472 {
473 pTBBtn[0].iBitmap = cxSeparator / 2;
474 pTBBtn[0].idCommand = 0;
475 pTBBtn[0].fsState = 0;
476 pTBBtn[0].fsStyle = TBSTYLE_SEP;
477 pTBBtn[0].dwData = 0;
478 pTBBtn[0].iString = 0;
479 }
480
481 int nBmp = 0;
482 for(int i = 0, j = bInitialSeparator ? 1 : 0; i < pData->wItemCo unt; i++, j++)
483 {
484 if(pItems[i] != 0)
485 {
486 pTBBtn[j].iBitmap = nBmp++;
487 pTBBtn[j].idCommand = pItems[i];
488 pTBBtn[j].fsState = TBSTATE_ENABLED;
489 pTBBtn[j].fsStyle = TBSTYLE_BUTTON;
490 pTBBtn[j].dwData = 0;
491 pTBBtn[j].iString = 0;
492 }
493 else
494 {
495 pTBBtn[j].iBitmap = cxSeparator;
496 pTBBtn[j].idCommand = 0;
497 pTBBtn[j].fsState = 0;
498 pTBBtn[j].fsStyle = TBSTYLE_SEP;
499 pTBBtn[j].dwData = 0;
500 pTBBtn[j].iString = 0;
501 }
502 }
503
504 #ifndef _WIN32_WCE
505 HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleIn stance(), NULL);
506 if(hWnd == NULL)
507 {
508 ATLASSERT(FALSE);
509 return NULL;
510 }
511 #else // CE specific
512 dwStyle;
513 nID;
514 // The toolbar must go onto the existing CommandBar or MenuBar
515 HWND hWnd = hWndParent;
516 #endif // _WIN32_WCE
517
518 ::SendMessage(hWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0L);
519
520 // check if font is taller than our bitmaps
521 CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L) ;
522 if(font.IsNull())
523 font = AtlGetDefaultGuiFont();
524 LOGFONT lf = { 0 };
525 font.GetLogFont(lf);
526 WORD cyFontHeight = (WORD)abs(lf.lfHeight);
527
528 #ifndef _WIN32_WCE
529 WORD bitsPerPixel = AtlGetBitmapResourceBitsPerPixel(nResourceID );
530 if(bitsPerPixel > 4)
531 {
532 COLORREF crMask = CLR_DEFAULT;
533 if(bitsPerPixel == 32)
534 {
535 // 32-bit color bitmap with alpha channel (valid for Windows XP and later)
536 crMask = CLR_NONE;
537 }
538 HIMAGELIST hImageList = ImageList_LoadImage(ModuleHelper ::GetResourceInstance(), MAKEINTRESOURCE(nResourceID), pData->wWidth, 1, crMask, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
539 ATLASSERT(hImageList != NULL);
540 ::SendMessage(hWnd, TB_SETIMAGELIST, 0, (LPARAM)hImageLi st);
541 }
542 else
543 #endif // !_WIN32_WCE
544 {
545 TBADDBITMAP tbab = { 0 };
546 tbab.hInst = hInst;
547 tbab.nID = nResourceID;
548 ::SendMessage(hWnd, TB_ADDBITMAP, nBmp, (LPARAM)&tbab);
549 }
550
551 ::SendMessage(hWnd, TB_ADDBUTTONS, nItems, (LPARAM)pTBBtn);
552 ::SendMessage(hWnd, TB_SETBITMAPSIZE, 0, MAKELONG(pData->wWidth, __max(pData->wHeight, cyFontHeight)));
553 const int cxyButtonMargin = 7;
554 ::SendMessage(hWnd, TB_SETBUTTONSIZE, 0, MAKELONG(pData->wWidth + cxyButtonMargin, __max(pData->wHeight, cyFontHeight) + cxyButtonMargin));
555
556 return hWnd;
557 }
558
559 #ifndef _WIN32_WCE
560 static HWND CreateSimpleReBarCtrl(HWND hWndParent, DWORD dwStyle = ATL_S IMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
561 {
562 // Ensure style combinations for proper rebar painting
563 if(dwStyle & CCS_NODIVIDER && dwStyle & WS_BORDER)
564 dwStyle &= ~WS_BORDER;
565 else if(!(dwStyle & WS_BORDER) && !(dwStyle & CCS_NODIVIDER))
566 dwStyle |= CCS_NODIVIDER;
567
568 // Create rebar window
569 HWND hWndReBar = ::CreateWindowEx(0, REBARCLASSNAME, NULL, dwSty le, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModul eInstance(), NULL);
570 if(hWndReBar == NULL)
571 {
572 ATLTRACE2(atlTraceUI, 0, _T("Failed to create rebar.\n") );
573 return NULL;
574 }
575
576 // Initialize and send the REBARINFO structure
577 REBARINFO rbi = { 0 };
578 rbi.cbSize = sizeof(REBARINFO);
579 rbi.fMask = 0;
580 if(!::SendMessage(hWndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi))
581 {
582 ATLTRACE2(atlTraceUI, 0, _T("Failed to initialize rebar. \n"));
583 ::DestroyWindow(hWndReBar);
584 return NULL;
585 }
586
587 return hWndReBar;
588 }
589
590 BOOL CreateSimpleReBar(DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
591 {
592 ATLASSERT(!::IsWindow(m_hWndToolBar));
593 m_hWndToolBar = CreateSimpleReBarCtrl(m_hWnd, dwStyle, nID);
594 return (m_hWndToolBar != NULL);
595 }
596
597 static BOOL AddSimpleReBarBandCtrl(HWND hWndReBar, HWND hWndBand, int nI D = 0, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bF ullWidthAlways = FALSE)
598 {
599 ATLASSERT(::IsWindow(hWndReBar)); // must be already created
600 #ifdef _DEBUG
601 // block - check if this is really a rebar
602 {
603 TCHAR lpszClassName[sizeof(REBARCLASSNAME)] = { 0 };
604 ::GetClassName(hWndReBar, lpszClassName, sizeof(REBARCLA SSNAME));
605 ATLASSERT(lstrcmp(lpszClassName, REBARCLASSNAME) == 0);
606 }
607 #endif // _DEBUG
608 ATLASSERT(::IsWindow(hWndBand)); // must be already created
609
610 // Get number of buttons on the toolbar
611 int nBtnCount = (int)::SendMessage(hWndBand, TB_BUTTONCOUNT, 0, 0L);
612
613 // Set band info structure
614 REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() } ;
615 #if (_WIN32_IE >= 0x0400)
616 rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBB IM_ID | RBBIM_SIZE | RBBIM_IDEALSIZE;
617 #else
618 rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBB IM_ID | RBBIM_SIZE;
619 #endif // !(_WIN32_IE >= 0x0400)
620 if(lpstrTitle != NULL)
621 rbBand.fMask |= RBBIM_TEXT;
622 rbBand.fStyle = RBBS_CHILDEDGE;
623 #if (_WIN32_IE >= 0x0500)
624 if(nBtnCount > 0) // add chevron style for toolbar with button s
625 rbBand.fStyle |= RBBS_USECHEVRON;
626 #endif // (_WIN32_IE >= 0x0500)
627 if(bNewRow)
628 rbBand.fStyle |= RBBS_BREAK;
629
630 rbBand.lpText = (LPTSTR)lpstrTitle;
631 rbBand.hwndChild = hWndBand;
632 if(nID == 0) // calc band ID
633 nID = ATL_IDW_BAND_FIRST + (int)::SendMessage(hWndReBar, RB_GETBANDCOUNT, 0, 0L);
634 rbBand.wID = nID;
635
636 // Calculate the size of the band
637 BOOL bRet = FALSE;
638 RECT rcTmp = { 0 };
639 if(nBtnCount > 0)
640 {
641 bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, nBt nCount - 1, (LPARAM)&rcTmp);
642 ATLASSERT(bRet);
643 rbBand.cx = (cxWidth != 0) ? cxWidth : rcTmp.right;
644 rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
645 if(bFullWidthAlways)
646 {
647 rbBand.cxMinChild = rbBand.cx;
648 }
649 else if(lpstrTitle == NULL)
650 {
651 bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMR ECT, 0, (LPARAM)&rcTmp);
652 ATLASSERT(bRet);
653 rbBand.cxMinChild = rcTmp.right;
654 }
655 else
656 {
657 rbBand.cxMinChild = 0;
658 }
659 }
660 else // no buttons, either not a toolbar or really has no but tons
661 {
662 bRet = ::GetWindowRect(hWndBand, &rcTmp);
663 ATLASSERT(bRet);
664 rbBand.cx = (cxWidth != 0) ? cxWidth : (rcTmp.right - rc Tmp.left);
665 rbBand.cxMinChild = bFullWidthAlways ? rbBand.cx : 0;
666 rbBand.cyMinChild = rcTmp.bottom - rcTmp.top;
667 }
668
669 #if (_WIN32_IE >= 0x0400)
670 rbBand.cxIdeal = rbBand.cx;
671 #endif // (_WIN32_IE >= 0x0400)
672
673 // Add the band
674 LRESULT lRes = ::SendMessage(hWndReBar, RB_INSERTBAND, (WPARAM)- 1, (LPARAM)&rbBand);
675 if(lRes == 0)
676 {
677 ATLTRACE2(atlTraceUI, 0, _T("Failed to add a band to the rebar.\n"));
678 return FALSE;
679 }
680
681 #if (_WIN32_IE >= 0x0501)
682 DWORD dwExStyle = (DWORD)::SendMessage(hWndBand, TB_GETEXTENDEDS TYLE, 0, 0L);
683 ::SendMessage(hWndBand, TB_SETEXTENDEDSTYLE, 0, dwExStyle | TBST YLE_EX_HIDECLIPPEDBUTTONS);
684 #endif // (_WIN32_IE >= 0x0501)
685
686 return TRUE;
687 }
688
689 BOOL AddSimpleReBarBand(HWND hWndBand, LPCTSTR lpstrTitle = NULL, BOOL b NewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE)
690 {
691 ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing r ebar
692 ATLASSERT(::IsWindow(hWndBand)); // must be created
693 return AddSimpleReBarBandCtrl(m_hWndToolBar, hWndBand, 0, lpstrT itle, bNewRow, cxWidth, bFullWidthAlways);
694 }
695
696 #if (_WIN32_IE >= 0x0400)
697 void SizeSimpleReBarBands()
698 {
699 ATLASSERT(::IsWindow(m_hWndToolBar)); // must be an existing r ebar
700
701 int nCount = (int)::SendMessage(m_hWndToolBar, RB_GETBANDCOUNT, 0, 0L);
702
703 for(int i = 0; i < nCount; i++)
704 {
705 REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBAND INFO() };
706 rbBand.fMask = RBBIM_SIZE;
707 BOOL bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_GETBAN DINFO, i, (LPARAM)&rbBand);
708 ATLASSERT(bRet);
709 RECT rect = { 0, 0, 0, 0 };
710 ::SendMessage(m_hWndToolBar, RB_GETBANDBORDERS, i, (LPAR AM)&rect);
711 rbBand.cx += rect.left + rect.right;
712 bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_SETBANDINFO , i, (LPARAM)&rbBand);
713 ATLASSERT(bRet);
714 }
715 }
716 #endif // (_WIN32_IE >= 0x0400)
717 #endif // _WIN32_WCE
718
719 #ifndef _WIN32_WCE
720 BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL _IDW_STATUS_BAR)
721 #else // CE specific
722 BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR)
723 #endif // _WIN32_WCE
724 {
725 ATLASSERT(!::IsWindow(m_hWndStatusBar));
726 m_hWndStatusBar = ::CreateStatusWindow(dwStyle, lpstrText, m_hWn d, nID);
727 return (m_hWndStatusBar != NULL);
728 }
729
730 #ifndef _WIN32_WCE
731 BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwS tyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRI P, UINT nID = ATL_IDW_STATUS_BAR)
732 #else // CE specific
733 BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwS tyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL _IDW_STATUS_BAR)
734 #endif // _WIN32_WCE
735 {
736 const int cchMax = 128; // max text length is 127 for status b ars (+1 for null)
737 TCHAR szText[cchMax];
738 szText[0] = 0;
739 ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szTex t, cchMax);
740 return CreateSimpleStatusBar(szText, dwStyle, nID);
741 }
742
743 #ifdef _WIN32_WCE
744 BOOL CreateSimpleCECommandBar(LPTSTR pszMenu = NULL, WORD iButton = 0, D WORD dwFlags = 0, int nCmdBarID = 1)
745 {
746 ATLASSERT(m_hWndCECommandBar == NULL);
747 ATLASSERT(m_hWndToolBar == NULL);
748
749 m_hWndCECommandBar = ::CommandBar_Create(ModuleHelper::GetModule Instance(), m_hWnd, nCmdBarID);
750 if(m_hWndCECommandBar == NULL)
751 return FALSE;
752
753 m_hWndToolBar = m_hWndCECommandBar;
754
755 BOOL bRet = TRUE;
756
757 if(pszMenu != NULL)
758 bRet &= ::CommandBar_InsertMenubarEx(m_hWndCECommandBar, IS_INTRESOURCE(pszMenu) ? ModuleHelper::GetResourceInstance() : NULL, pszMenu, iButton);
759
760 bRet &= ::CommandBar_AddAdornments(m_hWndCECommandBar, dwFlags, 0);
761
762 return bRet;
763 }
764
765 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
766 BOOL CreateSimpleCEMenuBar(UINT nToolBarId = ATL_IDW_MENU_BAR, DWORD dwF lags = 0, int nBmpId = 0, int cBmpImages = 0)
767 {
768 ATLASSERT(m_hWndCECommandBar == NULL);
769
770 SHMENUBARINFO mbi = { 0 };
771 mbi.cbSize = sizeof(mbi);
772 mbi.hwndParent = m_hWnd;
773 mbi.dwFlags = dwFlags;
774 mbi.nToolBarId = nToolBarId;
775 mbi.hInstRes = ModuleHelper::GetResourceInstance();
776 mbi.nBmpId = nBmpId;
777 mbi.cBmpImages = cBmpImages;
778 mbi.hwndMB = NULL; // This gets set by SHCreateMenuBar
779
780 BOOL bRet = ::SHCreateMenuBar(&mbi);
781 if(bRet != FALSE)
782 {
783 m_hWndCECommandBar = mbi.hwndMB;
784 SizeToMenuBar();
785 }
786
787 return bRet;
788 }
789
790 void SizeToMenuBar() // for menu bar only
791 {
792 ATLASSERT(::IsWindow(m_hWnd));
793 ATLASSERT(::IsWindow(m_hWndCECommandBar));
794
795 RECT rect = { 0 };
796 GetWindowRect(&rect);
797 RECT rectMB = { 0 };
798 ::GetWindowRect(m_hWndCECommandBar, &rectMB);
799 int cy = ::IsWindowVisible(m_hWndCECommandBar) ? rectMB.top - re ct.top : rectMB.bottom - rect.top;
800 SetWindowPos(NULL, 0, 0, rect.right - rect.left, cy, SWP_NOZORDE R | SWP_NOMOVE);
801 }
802 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
803 #endif // _WIN32_WCE
804
805 void UpdateLayout(BOOL bResizeBars = TRUE)
806 {
807 RECT rect = { 0 };
808 GetClientRect(&rect);
809
810 // position bars and offset their dimensions
811 UpdateBarsPosition(rect, bResizeBars);
812
813 // resize client window
814 if(m_hWndClient != NULL)
815 ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top,
816 rect.right - rect.left, rect.bottom - rect.top,
817 SWP_NOZORDER | SWP_NOACTIVATE);
818 }
819
820 void UpdateBarsPosition(RECT& rect, BOOL bResizeBars = TRUE)
821 {
822 // resize toolbar
823 if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBa r, GWL_STYLE) & WS_VISIBLE))
824 {
825 if(bResizeBars)
826 {
827 ::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0);
828 ::InvalidateRect(m_hWndToolBar, NULL, FALSE);
829 }
830 RECT rectTB = { 0 };
831 ::GetWindowRect(m_hWndToolBar, &rectTB);
832 rect.top += rectTB.bottom - rectTB.top;
833 }
834
835 // resize status bar
836 if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStat usBar, GWL_STYLE) & WS_VISIBLE))
837 {
838 if(bResizeBars)
839 ::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0);
840 RECT rectSB = { 0 };
841 ::GetWindowRect(m_hWndStatusBar, &rectSB);
842 rect.bottom -= rectSB.bottom - rectSB.top;
843 }
844 }
845
846 BOOL PreTranslateMessage(MSG* pMsg)
847 {
848 if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
849 return TRUE;
850 return FALSE;
851 }
852
853 BEGIN_MSG_MAP(CFrameWindowImplBase)
854 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
855 #ifndef _WIN32_WCE
856 MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
857 #endif // !_WIN32_WCE
858 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
859 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
860 #ifndef _WIN32_WCE
861 NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA)
862 NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW)
863 #endif // !_WIN32_WCE
864 END_MSG_MAP()
865
866 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa ram*/, BOOL& bHandled)
867 {
868 if(m_hWndClient != NULL) // view will paint itself instead
869 return 1;
870
871 bHandled = FALSE;
872 return 0;
873 }
874
875 #ifndef _WIN32_WCE
876 LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
877 {
878 bHandled = FALSE;
879
880 if(m_hWndStatusBar == NULL)
881 return 1;
882
883 WORD wFlags = HIWORD(wParam);
884 if(wFlags == 0xFFFF && lParam == NULL) // menu closing
885 {
886 ::SendMessage(m_hWndStatusBar, SB_SIMPLE, FALSE, 0L);
887 }
888 else
889 {
890 const int cchBuff = 256;
891 TCHAR szBuff[cchBuff];
892 szBuff[0] = 0;
893 if(!(wFlags & MF_POPUP))
894 {
895 WORD wID = LOWORD(wParam);
896 // check for special cases
897 if(wID >= 0xF000 && wID < 0xF1F0) // system me nu IDs
898 wID = (WORD)(((wID - 0xF000) >> 4) + ATL _IDS_SCFIRST);
899 else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FI LE_MRU_LAST) // MRU items
900 wID = ATL_IDS_MRU_FILE;
901 else if(wID >= ATL_IDM_FIRST_MDICHILD && wID <= ATL_IDM_LAST_MDICHILD) // MDI child windows
902 wID = ATL_IDS_MDICHILD;
903
904 int nRet = ::LoadString(ModuleHelper::GetResourc eInstance(), wID, szBuff, cchBuff);
905 for(int i = 0; i < nRet; i++)
906 {
907 if(szBuff[i] == _T('\n'))
908 {
909 szBuff[i] = 0;
910 break;
911 }
912 }
913 }
914 ::SendMessage(m_hWndStatusBar, SB_SIMPLE, TRUE, 0L);
915 ::SendMessage(m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NO BORDERS), (LPARAM)szBuff);
916 }
917
918 return 1;
919 }
920 #endif // !_WIN32_WCE
921
922 LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled)
923 {
924 if(m_hWndClient != NULL)
925 ::SetFocus(m_hWndClient);
926
927 bHandled = FALSE;
928 return 1;
929 }
930
931 LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled)
932 {
933 if((GetStyle() & (WS_CHILD | WS_POPUP)) == 0)
934 ::PostQuitMessage(1);
935
936 bHandled = FALSE;
937 return 1;
938 }
939
940 #ifndef _WIN32_WCE
941 LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
942 {
943 LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh;
944 pDispInfo->szText[0] = 0;
945
946 if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
947 {
948 const int cchBuff = 256;
949 char szBuff[cchBuff];
950 szBuff[0] = 0;
951 int nRet = ::LoadStringA(ModuleHelper::GetResourceInstan ce(), idCtrl, szBuff, cchBuff);
952 for(int i = 0; i < nRet; i++)
953 {
954 if(szBuff[i] == '\n')
955 {
956 SecureHelper::strncpyA_x(pDispInfo->szTe xt, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
957 break;
958 }
959 }
960 #if (_WIN32_IE >= 0x0300)
961 if(nRet > 0) // string was loaded, save it
962 pDispInfo->uFlags |= TTF_DI_SETITEM;
963 #endif // (_WIN32_IE >= 0x0300)
964 }
965
966 return 0;
967 }
968
969 LRESULT OnToolTipTextW(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/)
970 {
971 LPNMTTDISPINFOW pDispInfo = (LPNMTTDISPINFOW)pnmh;
972 pDispInfo->szText[0] = 0;
973
974 if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
975 {
976 const int cchBuff = 256;
977 wchar_t szBuff[cchBuff];
978 szBuff[0] = 0;
979 int nRet = ::LoadStringW(ModuleHelper::GetResourceInstan ce(), idCtrl, szBuff, cchBuff);
980 for(int i = 0; i < nRet; i++)
981 {
982 if(szBuff[i] == L'\n')
983 {
984 SecureHelper::strncpyW_x(pDispInfo->szTe xt, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE);
985 break;
986 }
987 }
988 #if (_WIN32_IE >= 0x0300)
989 if(nRet > 0) // string was loaded, save it
990 pDispInfo->uFlags |= TTF_DI_SETITEM;
991 #endif // (_WIN32_IE >= 0x0300)
992 }
993
994 return 0;
995 }
996 #endif // !_WIN32_WCE
997
998 // Implementation - chevron menu support
999 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1000 bool PrepareChevronMenu(_ChevronMenuInfo& cmi)
1001 {
1002 // get rebar and toolbar
1003 REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() };
1004 rbbi.fMask = RBBIM_CHILD;
1005 BOOL bRet = (BOOL)::SendMessage(cmi.lpnm->hdr.hwndFrom, RB_GETBA NDINFO, cmi.lpnm->uBand, (LPARAM)&rbbi);
1006 ATLASSERT(bRet);
1007
1008 // assume the band is a toolbar
1009 ATL::CWindow wnd = rbbi.hwndChild;
1010 int nCount = (int)wnd.SendMessage(TB_BUTTONCOUNT);
1011 if(nCount <= 0) // probably not a toolbar
1012 return false;
1013
1014 // check if it's a command bar
1015 CMenuHandle menuCmdBar = (HMENU)wnd.SendMessage(CBRM_GETMENU);
1016 cmi.bCmdBar = (menuCmdBar.m_hMenu != NULL);
1017
1018 // build a menu from hidden items
1019 CMenuHandle menu;
1020 bRet = menu.CreatePopupMenu();
1021 ATLASSERT(bRet);
1022 RECT rcClient = { 0 };
1023 bRet = wnd.GetClientRect(&rcClient);
1024 ATLASSERT(bRet);
1025 for(int i = 0; i < nCount; i++)
1026 {
1027 TBBUTTON tbb = { 0 };
1028 bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&t bb);
1029 ATLASSERT(bRet);
1030 // skip hidden buttons
1031 if((tbb.fsState & TBSTATE_HIDDEN) != 0)
1032 continue;
1033 RECT rcButton = { 0 };
1034 bRet = (BOOL)wnd.SendMessage(TB_GETITEMRECT, i, (LPARAM) &rcButton);
1035 ATLASSERT(bRet);
1036 bool bEnabled = ((tbb.fsState & TBSTATE_ENABLED) != 0);
1037 if(rcButton.right > rcClient.right)
1038 {
1039 if(tbb.fsStyle & BTNS_SEP)
1040 {
1041 if(menu.GetMenuItemCount() > 0)
1042 menu.AppendMenu(MF_SEPARATOR);
1043 }
1044 else if(cmi.bCmdBar)
1045 {
1046 const int cchBuff = 200;
1047 TCHAR szBuff[cchBuff] = { 0 };
1048 CMenuItemInfo mii;
1049 mii.fMask = MIIM_TYPE | MIIM_SUBMENU;
1050 mii.dwTypeData = szBuff;
1051 mii.cch = cchBuff;
1052 bRet = menuCmdBar.GetMenuItemInfo(i, TRU E, &mii);
1053 ATLASSERT(bRet);
1054 // Note: CmdBar currently supports only drop-down items
1055 ATLASSERT(::IsMenu(mii.hSubMenu));
1056 bRet = menu.AppendMenu(MF_STRING | MF_PO PUP | (bEnabled ? MF_ENABLED : MF_GRAYED), (UINT_PTR)mii.hSubMenu, mii.dwTypeDat a);
1057 ATLASSERT(bRet);
1058 }
1059 else
1060 {
1061 // get button's text
1062 const int cchBuff = 200;
1063 TCHAR szBuff[cchBuff] = { 0 };
1064 LPTSTR lpstrText = szBuff;
1065 TBBUTTONINFO tbbi = { 0 };
1066 tbbi.cbSize = sizeof(TBBUTTONINFO);
1067 tbbi.dwMask = TBIF_TEXT;
1068 tbbi.pszText = szBuff;
1069 tbbi.cchText = cchBuff;
1070 if(wnd.SendMessage(TB_GETBUTTONINFO, tbb .idCommand, (LPARAM)&tbbi) == -1 || lstrlen(szBuff) == 0)
1071 {
1072 // no text for this button, try a resource string
1073 lpstrText = _T("");
1074 int nRet = ::LoadString(ModuleHe lper::GetResourceInstance(), tbb.idCommand, szBuff, cchBuff);
1075 for(int n = 0; n < nRet; n++)
1076 {
1077 if(szBuff[n] == _T('\n') )
1078 {
1079 lpstrText = &szB uff[n + 1];
1080 break;
1081 }
1082 }
1083 }
1084 bRet = menu.AppendMenu(MF_STRING | (bEna bled ? MF_ENABLED : MF_GRAYED), tbb.idCommand, lpstrText);
1085 ATLASSERT(bRet);
1086 }
1087 }
1088 }
1089
1090 if(menu.GetMenuItemCount() == 0) // no hidden buttons after al l
1091 {
1092 menu.DestroyMenu();
1093 ::MessageBeep((UINT)-1);
1094 return false;
1095 }
1096
1097 cmi.hMenu = menu;
1098 return true;
1099 }
1100
1101 void DisplayChevronMenu(_ChevronMenuInfo& cmi)
1102 {
1103 #ifndef TPM_VERPOSANIMATION
1104 const UINT TPM_VERPOSANIMATION = 0x1000L; // Menu animation fl ag
1105 #endif
1106 // convert chevron rect to screen coordinates
1107 ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
1108 POINT pt = { cmi.lpnm->rc.left, cmi.lpnm->rc.bottom };
1109 wndFrom.MapWindowPoints(NULL, &pt, 1);
1110 RECT rc = cmi.lpnm->rc;
1111 wndFrom.MapWindowPoints(NULL, &rc);
1112 // set up flags and rect
1113 UINT uMenuFlags = TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN | TPM_TOPALIGN | (!AtlIsOldWindows() ? TPM_VERPOSANIMATION : 0);
1114 TPMPARAMS TPMParams = { 0 };
1115 TPMParams.cbSize = sizeof(TPMPARAMS);
1116 TPMParams.rcExclude = rc;
1117 // check if this window has a command bar
1118 HWND hWndCmdBar = (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0, 0L);
1119 if(::IsWindow(hWndCmdBar))
1120 {
1121 CBRPOPUPMENU CBRPopupMenu = { sizeof(CBRPOPUPMENU), cmi. hMenu, uMenuFlags, pt.x, pt.y, &TPMParams };
1122 ::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARA M)&CBRPopupMenu);
1123 }
1124 else
1125 {
1126 CMenuHandle menu = cmi.hMenu;
1127 menu.TrackPopupMenuEx(uMenuFlags, pt.x, pt.y, m_hWnd, &T PMParams);
1128 }
1129 }
1130
1131 void CleanupChevronMenu(_ChevronMenuInfo& cmi)
1132 {
1133 CMenuHandle menu = cmi.hMenu;
1134 // if menu is from a command bar, detach submenus so they are no t destroyed
1135 if(cmi.bCmdBar)
1136 {
1137 for(int i = menu.GetMenuItemCount() - 1; i >=0; i--)
1138 menu.RemoveMenu(i, MF_BYPOSITION);
1139 }
1140 // destroy menu
1141 menu.DestroyMenu();
1142 // convert chevron rect to screen coordinates
1143 ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom;
1144 RECT rc = cmi.lpnm->rc;
1145 wndFrom.MapWindowPoints(NULL, &rc);
1146 // eat next message if click is on the same button
1147 MSG msg = { 0 };
1148 if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, P M_NOREMOVE) && ::PtInRect(&rc, msg.pt))
1149 ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDO WN, PM_REMOVE);
1150 }
1151 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1152 };
1153
1154
1155 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWin Traits>
1156 class ATL_NO_VTABLE CFrameWindowImpl : public CFrameWindowImplBase< TBase, TWinT raits >
1157 {
1158 public:
1159 HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR sz WindowName = NULL,
1160 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1161 HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
1162 {
1163 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc) ;
1164
1165 dwStyle = T::GetWndStyle(dwStyle);
1166 dwExStyle = T::GetWndExStyle(dwExStyle);
1167
1168 if(rect.m_lpRect == NULL)
1169 rect.m_lpRect = &TBase::rcDefault;
1170
1171 return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndPar ent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam );
1172 }
1173
1174 HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dw Style = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
1175 {
1176 const int cchName = 256;
1177 TCHAR szWindowName[cchName];
1178 szWindowName[0] = 0;
1179 #ifndef _WIN32_WCE
1180 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClass Info().m_uCommonResourceID, szWindowName, cchName);
1181 HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MA KEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1182 #else // CE specific
1183 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClass Info().m_uCommonResourceID, szWindowName, cchName);
1184
1185 // This always needs to be NULL for Windows CE.
1186 // Frame Window menus have to go onto the CommandBar.
1187 // Use CreateSimpleCECommandBar
1188 HMENU hMenu = NULL;
1189 #endif // _WIN32_WCE
1190
1191 T* pT = static_cast<T*>(this);
1192 HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
1193
1194 if(hWnd != NULL)
1195 m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceI nstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1196
1197 return hWnd;
1198 }
1199
1200 BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPL E_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1201 {
1202 if(nResourceID == 0)
1203 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1204 #ifndef _WIN32_WCE
1205 ATLASSERT(!::IsWindow(m_hWndToolBar));
1206 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
1207 return (m_hWndToolBar != NULL);
1208 #else // CE specific
1209 HWND hWnd= T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResou rceID, TRUE, dwStyle, nID);
1210 return (hWnd != NULL);
1211 #endif // _WIN32_WCE
1212 }
1213
1214 #ifdef _WIN32_WCE
1215 // CE specific variant that returns the handle of the toolbar
1216 HWND CreateSimpleCEToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIM PLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1217 {
1218 if(nResourceID == 0)
1219 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1220
1221 return T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceI D, TRUE, dwStyle, nID);
1222 }
1223 #endif // _WIN32_WCE
1224
1225 // message map and handlers
1226 typedef CFrameWindowImplBase< TBase, TWinTraits > _baseClass;
1227
1228 BEGIN_MSG_MAP(CFrameWindowImpl)
1229 MESSAGE_HANDLER(WM_SIZE, OnSize)
1230 #ifndef _ATL_NO_REBAR_SUPPORT
1231 #if (_WIN32_IE >= 0x0400)
1232 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
1233 #endif // (_WIN32_IE >= 0x0400)
1234 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1235 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
1236 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1237 #endif // !_ATL_NO_REBAR_SUPPORT
1238 CHAIN_MSG_MAP(_baseClass)
1239 END_MSG_MAP()
1240
1241 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bH andled)
1242 {
1243 if(wParam != SIZE_MINIMIZED)
1244 {
1245 T* pT = static_cast<T*>(this);
1246 pT->UpdateLayout();
1247 }
1248 bHandled = FALSE;
1249 return 1;
1250 }
1251
1252 #ifndef _ATL_NO_REBAR_SUPPORT
1253 #if (_WIN32_IE >= 0x0400)
1254 LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandl ed*/)
1255 {
1256 T* pT = static_cast<T*>(this);
1257 pT->UpdateLayout(FALSE);
1258 return 0;
1259 }
1260 #endif // (_WIN32_IE >= 0x0400)
1261
1262 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1263 LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1264 {
1265 T* pT = static_cast<T*>(this);
1266 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
1267 if(!pT->PrepareChevronMenu(cmi))
1268 {
1269 bHandled = FALSE;
1270 return 1;
1271 }
1272 // display a popup menu with hidden items
1273 pT->DisplayChevronMenu(cmi);
1274 // cleanup
1275 pT->CleanupChevronMenu(cmi);
1276 return 0;
1277 }
1278 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
1279 #endif // !_ATL_NO_REBAR_SUPPORT
1280 };
1281
1282
1283 ///////////////////////////////////////////////////////////////////////////////
1284 // AtlCreateSimpleToolBar - helper for creating simple toolbars
1285
1286 #ifndef _WIN32_WCE
1287
1288 inline HWND AtlCreateSimpleToolBar(HWND hWndParent, UINT nResourceID, BOOL bInit ialSeparator = FALSE,
1289 DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOO LBAR)
1290 {
1291 return CFrameWindowImplBase<>::CreateSimpleToolBarCtrl(hWndParent, nReso urceID, bInitialSeparator, dwStyle, nID);
1292 }
1293
1294 #endif // !_WIN32_WCE
1295
1296
1297 ///////////////////////////////////////////////////////////////////////////////
1298 // CMDIWindow
1299
1300 #ifndef _WIN32_WCE
1301
1302 #ifndef _WTL_MDIWINDOWMENU_TEXT
1303 #define _WTL_MDIWINDOWMENU_TEXT _T("&Window")
1304 #endif
1305
1306 class CMDIWindow : public ATL::CWindow
1307 {
1308 public:
1309 // Data members
1310 HWND m_hWndMDIClient;
1311 HMENU m_hMenu;
1312
1313 // Constructors
1314 CMDIWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd), m_hWndMDIClient(NULL) , m_hMenu(NULL)
1315 { }
1316
1317 CMDIWindow& operator =(HWND hWnd)
1318 {
1319 m_hWnd = hWnd;
1320 return *this;
1321 }
1322
1323 // Operations
1324 HWND MDIGetActive(BOOL* lpbMaximized = NULL)
1325 {
1326 ATLASSERT(::IsWindow(m_hWndMDIClient));
1327 return (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0, (LPARAM)lpbMaximized);
1328 }
1329
1330 void MDIActivate(HWND hWndChildToActivate)
1331 {
1332 ATLASSERT(::IsWindow(m_hWndMDIClient));
1333 ATLASSERT(::IsWindow(hWndChildToActivate));
1334 ::SendMessage(m_hWndMDIClient, WM_MDIACTIVATE, (WPARAM)hWndChild ToActivate, 0);
1335 }
1336
1337 void MDINext(HWND hWndChild, BOOL bPrevious = FALSE)
1338 {
1339 ATLASSERT(::IsWindow(m_hWndMDIClient));
1340 ATLASSERT(hWndChild == NULL || ::IsWindow(hWndChild));
1341 ::SendMessage(m_hWndMDIClient, WM_MDINEXT, (WPARAM)hWndChild, (L PARAM)bPrevious);
1342 }
1343
1344 void MDIMaximize(HWND hWndChildToMaximize)
1345 {
1346 ATLASSERT(::IsWindow(m_hWndMDIClient));
1347 ATLASSERT(::IsWindow(hWndChildToMaximize));
1348 ::SendMessage(m_hWndMDIClient, WM_MDIMAXIMIZE, (WPARAM)hWndChild ToMaximize, 0);
1349 }
1350
1351 void MDIRestore(HWND hWndChildToRestore)
1352 {
1353 ATLASSERT(::IsWindow(m_hWndMDIClient));
1354 ATLASSERT(::IsWindow(hWndChildToRestore));
1355 ::SendMessage(m_hWndMDIClient, WM_MDIRESTORE, (WPARAM)hWndChildT oRestore, 0);
1356 }
1357
1358 void MDIDestroy(HWND hWndChildToDestroy)
1359 {
1360 ATLASSERT(::IsWindow(m_hWndMDIClient));
1361 ATLASSERT(::IsWindow(hWndChildToDestroy));
1362 ::SendMessage(m_hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndChildT oDestroy, 0);
1363 }
1364
1365 BOOL MDICascade(UINT uFlags = 0)
1366 {
1367 ATLASSERT(::IsWindow(m_hWndMDIClient));
1368 return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDICASCADE, (WPAR AM)uFlags, 0);
1369 }
1370
1371 BOOL MDITile(UINT uFlags = MDITILE_HORIZONTAL)
1372 {
1373 ATLASSERT(::IsWindow(m_hWndMDIClient));
1374 return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDITILE, (WPARAM) uFlags, 0);
1375 }
1376
1377 void MDIIconArrange()
1378 {
1379 ATLASSERT(::IsWindow(m_hWndMDIClient));
1380 ::SendMessage(m_hWndMDIClient, WM_MDIICONARRANGE, 0, 0);
1381 }
1382
1383 HMENU MDISetMenu(HMENU hMenuFrame, HMENU hMenuWindow)
1384 {
1385 ATLASSERT(::IsWindow(m_hWndMDIClient));
1386 return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDISETMENU, (WPA RAM)hMenuFrame, (LPARAM)hMenuWindow);
1387 }
1388
1389 HMENU MDIRefreshMenu()
1390 {
1391 ATLASSERT(::IsWindow(m_hWndMDIClient));
1392 return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0);
1393 }
1394
1395 // Additional operations
1396 static HMENU GetStandardWindowMenu(HMENU hMenu)
1397 {
1398 int nCount = ::GetMenuItemCount(hMenu);
1399 if(nCount == -1)
1400 return NULL;
1401 int nLen = ::GetMenuString(hMenu, nCount - 2, NULL, 0, MF_BYPOSI TION);
1402 if(nLen == 0)
1403 return NULL;
1404 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff;
1405 LPTSTR lpszText = buff.Allocate(nLen + 1);
1406 if(lpszText == NULL)
1407 return NULL;
1408 if(::GetMenuString(hMenu, nCount - 2, lpszText, nLen + 1, MF_BYP OSITION) != nLen)
1409 return NULL;
1410 if(lstrcmp(lpszText, _WTL_MDIWINDOWMENU_TEXT) != 0)
1411 return NULL;
1412 return ::GetSubMenu(hMenu, nCount - 2);
1413 }
1414
1415 void SetMDIFrameMenu()
1416 {
1417 HMENU hWindowMenu = GetStandardWindowMenu(m_hMenu);
1418 MDISetMenu(m_hMenu, hWindowMenu);
1419 MDIRefreshMenu();
1420 ::DrawMenuBar(GetMDIFrame());
1421 }
1422
1423 HWND GetMDIFrame() const
1424 {
1425 return ::GetParent(m_hWndMDIClient);
1426 }
1427 };
1428
1429 #endif // !_WIN32_WCE
1430
1431
1432 ///////////////////////////////////////////////////////////////////////////////
1433 // CMDIFrameWindowImpl
1434
1435 #ifndef _WIN32_WCE
1436
1437 // MDI child command chaining macro (only for MDI frame windows)
1438 #define CHAIN_MDI_CHILD_COMMANDS() \
1439 if(uMsg == WM_COMMAND) \
1440 { \
1441 HWND hWndChild = MDIGetActive(); \
1442 if(hWndChild != NULL) \
1443 ::SendMessage(hWndChild, uMsg, wParam, lParam); \
1444 }
1445
1446 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CFrameWinTr aits>
1447 class ATL_NO_VTABLE CMDIFrameWindowImpl : public CFrameWindowImplBase<TBase, TWi nTraits >
1448 {
1449 public:
1450 HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR sz WindowName = NULL,
1451 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1452 HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
1453 {
1454 m_hMenu = hMenu;
1455 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc) ;
1456
1457 dwStyle = T::GetWndStyle(dwStyle);
1458 dwExStyle = T::GetWndExStyle(dwExStyle);
1459
1460 if(rect.m_lpRect == NULL)
1461 rect.m_lpRect = &TBase::rcDefault;
1462
1463 return CFrameWindowImplBase<TBase, TWinTraits >::Create(hWndPare nt, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam) ;
1464 }
1465
1466 HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dw Style = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
1467 {
1468 const int cchName = 256;
1469 TCHAR szWindowName[cchName];
1470 szWindowName[0] = 0;
1471 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClass Info().m_uCommonResourceID, szWindowName, cchName);
1472 HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MA KEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1473
1474 T* pT = static_cast<T*>(this);
1475 HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
1476
1477 if(hWnd != NULL)
1478 m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceI nstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1479
1480 return hWnd;
1481 }
1482
1483 BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPL E_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1484 {
1485 ATLASSERT(!::IsWindow(m_hWndToolBar));
1486 if(nResourceID == 0)
1487 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1488 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
1489 return (m_hWndToolBar != NULL);
1490 }
1491
1492 virtual WNDPROC GetWindowProc()
1493 {
1494 return MDIFrameWindowProc;
1495 }
1496
1497 static LRESULT CALLBACK MDIFrameWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1498 {
1499 CMDIFrameWindowImpl< T, TBase, TWinTraits >* pThis = (CMDIFrameW indowImpl< T, TBase, TWinTraits >*)hWnd;
1500 // set a ptr to this message and save the old value
1501 #if (_ATL_VER >= 0x0700)
1502 ATL::_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1503 const ATL::_ATL_MSG* pOldMsg = pThis->m_pCurrentMsg;
1504 #else // !(_ATL_VER >= 0x0700)
1505 MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
1506 const MSG* pOldMsg = pThis->m_pCurrentMsg;
1507 #endif // !(_ATL_VER >= 0x0700)
1508 pThis->m_pCurrentMsg = &msg;
1509 // pass to the message map to process
1510 LRESULT lRes = 0;
1511 BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wPa ram, lParam, lRes, 0);
1512 // restore saved value for the current message
1513 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1514 pThis->m_pCurrentMsg = pOldMsg;
1515 // do the default processing if message was not handled
1516 if(!bRet)
1517 {
1518 if(uMsg != WM_NCDESTROY)
1519 lRes = pThis->DefWindowProc(uMsg, wParam, lParam );
1520 else
1521 {
1522 // unsubclass, if needed
1523 LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis-> m_hWnd, GWLP_WNDPROC);
1524 lRes = pThis->DefWindowProc(uMsg, wParam, lParam );
1525 if(pThis->m_pfnSuperWindowProc != ::DefWindowPro c && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc)
1526 ::SetWindowLongPtr(pThis->m_hWnd, GWLP_W NDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc);
1527 #if (_ATL_VER >= 0x0700)
1528 // mark window as destryed
1529 pThis->m_dwState |= WINSTATE_DESTROYED;
1530 #else // !(_ATL_VER >= 0x0700)
1531 // clear out window handle
1532 HWND hWnd = pThis->m_hWnd;
1533 pThis->m_hWnd = NULL;
1534 // clean up after window is destroyed
1535 pThis->OnFinalMessage(hWnd);
1536 #endif // !(_ATL_VER >= 0x0700)
1537 }
1538 }
1539 #if (_ATL_VER >= 0x0700)
1540 if(pThis->m_dwState & WINSTATE_DESTROYED && pThis->m_pCurrentMsg == NULL)
1541 {
1542 // clear out window handle
1543 HWND hWnd = pThis->m_hWnd;
1544 pThis->m_hWnd = NULL;
1545 pThis->m_dwState &= ~WINSTATE_DESTROYED;
1546 // clean up after window is destroyed
1547 pThis->OnFinalMessage(hWnd);
1548 }
1549 #endif // (_ATL_VER >= 0x0700)
1550 return lRes;
1551 }
1552
1553 // Overriden to call DefWindowProc which uses DefFrameProc
1554 LRESULT DefWindowProc()
1555 {
1556 const MSG* pMsg = m_pCurrentMsg;
1557 LRESULT lRes = 0;
1558 if (pMsg != NULL)
1559 lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg-> lParam);
1560 return lRes;
1561 }
1562
1563 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
1564 {
1565 return ::DefFrameProc(m_hWnd, m_hWndMDIClient, uMsg, wParam, lPa ram);
1566 }
1567
1568 BOOL PreTranslateMessage(MSG* pMsg)
1569 {
1570 if(CFrameWindowImplBase<TBase, TWinTraits>::PreTranslateMessage( pMsg))
1571 return TRUE;
1572 return ::TranslateMDISysAccel(m_hWndMDIClient, pMsg);
1573 }
1574
1575 HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT , UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD)
1576 {
1577 DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLI PSIBLINGS | MDIS_ALLCHILDSTYLES;
1578 DWORD dwExStyle = WS_EX_CLIENTEDGE;
1579
1580 CLIENTCREATESTRUCT ccs = { 0 };
1581 ccs.hWindowMenu = hWindowMenu;
1582 ccs.idFirstChild = nFirstChildID;
1583
1584 if((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) != 0)
1585 {
1586 // parent MDI frame's scroll styles move to the MDICLIEN T
1587 dwStyle |= (GetStyle() & (WS_HSCROLL | WS_VSCROLL));
1588
1589 // fast way to turn off the scrollbar bits (without a re size)
1590 ModifyStyle(WS_HSCROLL | WS_VSCROLL, 0, SWP_NOREDRAW | S WP_FRAMECHANGED);
1591 }
1592
1593 // Create MDICLIENT window
1594 m_hWndClient = ::CreateWindowEx(dwExStyle, _T("MDIClient"), NULL ,
1595 dwStyle, 0, 0, 1, 1, m_hWnd, (HMENU)LongToHandle(nID),
1596 ModuleHelper::GetModuleInstance(), (LPVOID)&ccs);
1597 if (m_hWndClient == NULL)
1598 {
1599 ATLTRACE2(atlTraceUI, 0, _T("MDI Frame failed to create MDICLIENT.\n"));
1600 return NULL;
1601 }
1602
1603 // Move it to the top of z-order
1604 ::BringWindowToTop(m_hWndClient);
1605
1606 // set as MDI client window
1607 m_hWndMDIClient = m_hWndClient;
1608
1609 // update to proper size
1610 T* pT = static_cast<T*>(this);
1611 pT->UpdateLayout();
1612
1613 return m_hWndClient;
1614 }
1615
1616 typedef CFrameWindowImplBase<TBase, TWinTraits > _baseClass;
1617
1618 BEGIN_MSG_MAP(CMDIFrameWindowImpl)
1619 MESSAGE_HANDLER(WM_SIZE, OnSize)
1620 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
1621 MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu)
1622 #ifndef _ATL_NO_REBAR_SUPPORT
1623 #if (_WIN32_IE >= 0x0400)
1624 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
1625 #endif // (_WIN32_IE >= 0x0400)
1626 #if (_WIN32_IE >= 0x0500)
1627 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
1628 #endif // (_WIN32_IE >= 0x0500)
1629 #endif // !_ATL_NO_REBAR_SUPPORT
1630 CHAIN_MSG_MAP(_baseClass)
1631 END_MSG_MAP()
1632
1633 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /* bHandled*/)
1634 {
1635 if(wParam != SIZE_MINIMIZED)
1636 {
1637 T* pT = static_cast<T*>(this);
1638 pT->UpdateLayout();
1639 }
1640 // message must be handled, otherwise DefFrameProc would resize the client again
1641 return 0;
1642 }
1643
1644 LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHan dled*/)
1645 {
1646 // don't allow CFrameWindowImplBase to handle this one
1647 return DefWindowProc(uMsg, wParam, lParam);
1648 }
1649
1650 LRESULT OnMDISetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/ , BOOL& /*bHandled*/)
1651 {
1652 SetMDIFrameMenu();
1653 return 0;
1654 }
1655
1656 #ifndef _ATL_NO_REBAR_SUPPORT
1657 #if (_WIN32_IE >= 0x0400)
1658 LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandl ed*/)
1659 {
1660 T* pT = static_cast<T*>(this);
1661 pT->UpdateLayout(FALSE);
1662 return 0;
1663 }
1664 #endif // (_WIN32_IE >= 0x0400)
1665
1666 #if (_WIN32_IE >= 0x0500)
1667 LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1668 {
1669 T* pT = static_cast<T*>(this);
1670 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
1671 if(!pT->PrepareChevronMenu(cmi))
1672 {
1673 bHandled = FALSE;
1674 return 1;
1675 }
1676 // display a popup menu with hidden items
1677 pT->DisplayChevronMenu(cmi);
1678 // cleanup
1679 pT->CleanupChevronMenu(cmi);
1680 return 0;
1681 }
1682 #endif // (_WIN32_IE >= 0x0500)
1683 #endif // !_ATL_NO_REBAR_SUPPORT
1684 };
1685
1686 #endif // !_WIN32_WCE
1687
1688
1689 ///////////////////////////////////////////////////////////////////////////////
1690 // CMDIChildWindowImpl
1691
1692 #ifndef _WIN32_WCE
1693
1694 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CMDIChildWi nTraits>
1695 class ATL_NO_VTABLE CMDIChildWindowImpl : public CFrameWindowImplBase<TBase, TWi nTraits >
1696 {
1697 public:
1698 HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowN ame = NULL,
1699 DWORD dwStyle = 0, DWORD dwExStyle = 0,
1700 UINT nMenuID = 0, LPVOID lpCreateParam = NULL)
1701 {
1702 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc) ;
1703
1704 if(nMenuID != 0)
1705 m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance() , MAKEINTRESOURCE(nMenuID));
1706
1707 dwStyle = T::GetWndStyle(dwStyle);
1708 dwExStyle = T::GetWndExStyle(dwExStyle);
1709
1710 dwExStyle |= WS_EX_MDICHILD; // force this one
1711 m_pfnSuperWindowProc = ::DefMDIChildProc;
1712 m_hWndMDIClient = hWndParent;
1713 ATLASSERT(::IsWindow(m_hWndMDIClient));
1714
1715 if(rect.m_lpRect == NULL)
1716 rect.m_lpRect = &TBase::rcDefault;
1717
1718 // If the currently active MDI child is maximized, we want to cr eate this one maximized too
1719 ATL::CWindow wndParent = hWndParent;
1720 BOOL bMaximized = FALSE;
1721 wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized);
1722 if(bMaximized)
1723 wndParent.SetRedraw(FALSE);
1724
1725 HWND hWnd = CFrameWindowImplBase<TBase, TWinTraits >::Create(hWn dParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)0U, atom, lpCrea teParam);
1726
1727 if(bMaximized)
1728 {
1729 // Maximize and redraw everything
1730 if(hWnd != NULL)
1731 MDIMaximize(hWnd);
1732 wndParent.SetRedraw(TRUE);
1733 wndParent.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_ ALLCHILDREN);
1734 ::SetFocus(GetMDIFrame()); // focus will be set back t o this window
1735 }
1736 else if(hWnd != NULL && ::IsWindowVisible(m_hWnd) && !::IsChild( hWnd, ::GetFocus()))
1737 {
1738 ::SetFocus(hWnd);
1739 }
1740
1741 return hWnd;
1742 }
1743
1744 HWND CreateEx(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR lpcstrW indowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
1745 {
1746 const int cchName = 256;
1747 TCHAR szWindowName[cchName];
1748 szWindowName[0] = 0;
1749 if(lpcstrWindowName == NULL)
1750 {
1751 ::LoadString(ModuleHelper::GetResourceInstance(), T::Get WndClassInfo().m_uCommonResourceID, szWindowName, cchName);
1752 lpcstrWindowName = szWindowName;
1753 }
1754
1755 T* pT = static_cast<T*>(this);
1756 HWND hWnd = pT->Create(hWndParent, rect, lpcstrWindowName, dwSty le, dwExStyle, T::GetWndClassInfo().m_uCommonResourceID, lpCreateParam);
1757
1758 if(hWnd != NULL)
1759 m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceI nstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
1760
1761 return hWnd;
1762 }
1763
1764 BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPL E_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR)
1765 {
1766 ATLASSERT(!::IsWindow(m_hWndToolBar));
1767 if(nResourceID == 0)
1768 nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
1769 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE, dwStyle, nID);
1770 return (m_hWndToolBar != NULL);
1771 }
1772
1773 BOOL UpdateClientEdge(LPRECT lpRect = NULL)
1774 {
1775 // only adjust for active MDI child window
1776 HWND hWndChild = MDIGetActive();
1777 if(hWndChild != NULL && hWndChild != m_hWnd)
1778 return FALSE;
1779
1780 // need to adjust the client edge style as max/restore happens
1781 DWORD dwStyle = ::GetWindowLong(m_hWndMDIClient, GWL_EXSTYLE);
1782 DWORD dwNewStyle = dwStyle;
1783 if(hWndChild != NULL && ((GetExStyle() & WS_EX_CLIENTEDGE) == 0) && ((GetStyle() & WS_MAXIMIZE) != 0))
1784 dwNewStyle &= ~(WS_EX_CLIENTEDGE);
1785 else
1786 dwNewStyle |= WS_EX_CLIENTEDGE;
1787
1788 if(dwStyle != dwNewStyle)
1789 {
1790 // SetWindowPos will not move invalid bits
1791 ::RedrawWindow(m_hWndMDIClient, NULL, NULL,
1792 RDW_INVALIDATE | RDW_ALLCHILDREN);
1793 // remove/add WS_EX_CLIENTEDGE to MDI client area
1794 ::SetWindowLong(m_hWndMDIClient, GWL_EXSTYLE, dwNewStyle );
1795 ::SetWindowPos(m_hWndMDIClient, NULL, 0, 0, 0, 0,
1796 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE |
1797 SWP_NOZORDER | SWP_NOCOPYBITS);
1798
1799 // return new client area
1800 if (lpRect != NULL)
1801 ::GetClientRect(m_hWndMDIClient, lpRect);
1802
1803 return TRUE;
1804 }
1805
1806 return FALSE;
1807 }
1808
1809 typedef CFrameWindowImplBase<TBase, TWinTraits > _baseClass;
1810 BEGIN_MSG_MAP(CMDIChildWindowImpl)
1811 MESSAGE_HANDLER(WM_SIZE, OnSize)
1812 MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
1813 MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate)
1814 MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
1815 MESSAGE_HANDLER(WM_MDIACTIVATE, OnMDIActivate)
1816 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
1817 #ifndef _ATL_NO_REBAR_SUPPORT
1818 #if (_WIN32_IE >= 0x0400)
1819 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize)
1820 #endif // (_WIN32_IE >= 0x0400)
1821 #if (_WIN32_IE >= 0x0500)
1822 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed)
1823 #endif // (_WIN32_IE >= 0x0500)
1824 #endif // !_ATL_NO_REBAR_SUPPORT
1825 CHAIN_MSG_MAP(_baseClass)
1826 END_MSG_MAP()
1827
1828 LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled */)
1829 {
1830 DefWindowProc(uMsg, wParam, lParam); // needed for MDI childre n
1831 if(wParam != SIZE_MINIMIZED)
1832 {
1833 T* pT = static_cast<T*>(this);
1834 pT->UpdateLayout();
1835 }
1836 return 0;
1837 }
1838
1839 LRESULT OnWindowPosChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lPar am, BOOL& bHandled)
1840 {
1841 // update MDI client edge and adjust MDI child rect
1842 LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam;
1843
1844 if(!(lpWndPos->flags & SWP_NOSIZE))
1845 {
1846 RECT rectClient;
1847 if(UpdateClientEdge(&rectClient) && ((GetStyle() & WS_MA XIMIZE) != 0))
1848 {
1849 ::AdjustWindowRectEx(&rectClient, GetStyle(), FA LSE, GetExStyle());
1850 lpWndPos->x = rectClient.left;
1851 lpWndPos->y = rectClient.top;
1852 lpWndPos->cx = rectClient.right - rectClient.lef t;
1853 lpWndPos->cy = rectClient.bottom - rectClient.to p;
1854 }
1855 }
1856
1857 bHandled = FALSE;
1858 return 1;
1859 }
1860
1861 LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& / *bHandled*/)
1862 {
1863 LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
1864
1865 // Activate this MDI window if needed
1866 if(lRes == MA_ACTIVATE || lRes == MA_ACTIVATEANDEAT)
1867 {
1868 if(MDIGetActive() != m_hWnd)
1869 MDIActivate(m_hWnd);
1870 }
1871
1872 return lRes;
1873 }
1874
1875 LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bH andled*/)
1876 {
1877 return ::SendMessage(GetMDIFrame(), uMsg, wParam, lParam);
1878 }
1879
1880 LRESULT OnMDIActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B OOL& bHandled)
1881 {
1882 if((HWND)lParam == m_hWnd && m_hMenu != NULL)
1883 SetMDIFrameMenu();
1884 else if((HWND)lParam == NULL)
1885 ::SendMessage(GetMDIFrame(), WM_MDISETMENU, 0, 0);
1886
1887 bHandled = FALSE;
1888 return 1;
1889 }
1890
1891 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, B OOL& bHandled)
1892 {
1893 if(m_hMenu != NULL)
1894 {
1895 ::DestroyMenu(m_hMenu);
1896 m_hMenu = NULL;
1897 }
1898 UpdateClientEdge();
1899 bHandled = FALSE;
1900 return 1;
1901 }
1902
1903 #ifndef _ATL_NO_REBAR_SUPPORT
1904 #if (_WIN32_IE >= 0x0400)
1905 LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandl ed*/)
1906 {
1907 T* pT = static_cast<T*>(this);
1908 pT->UpdateLayout(FALSE);
1909 return 0;
1910 }
1911 #endif // (_WIN32_IE >= 0x0400)
1912
1913 #if (_WIN32_IE >= 0x0500)
1914 LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
1915 {
1916 T* pT = static_cast<T*>(this);
1917 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false };
1918 if(!pT->PrepareChevronMenu(cmi))
1919 {
1920 bHandled = FALSE;
1921 return 1;
1922 }
1923 // display a popup menu with hidden items
1924 pT->DisplayChevronMenu(cmi);
1925 // cleanup
1926 pT->CleanupChevronMenu(cmi);
1927 return 0;
1928 }
1929 #endif // (_WIN32_IE >= 0x0500)
1930 #endif // !_ATL_NO_REBAR_SUPPORT
1931 };
1932
1933 #endif // !_WIN32_WCE
1934
1935
1936 ///////////////////////////////////////////////////////////////////////////////
1937 // COwnerDraw - MI class for owner-draw support
1938
1939 template <class T>
1940 class COwnerDraw
1941 {
1942 public:
1943 #if (_ATL_VER < 0x0700)
1944 BOOL m_bHandledOD;
1945
1946 BOOL IsMsgHandled() const
1947 {
1948 return m_bHandledOD;
1949 }
1950 void SetMsgHandled(BOOL bHandled)
1951 {
1952 m_bHandledOD = bHandled;
1953 }
1954 #endif // (_ATL_VER < 0x0700)
1955
1956 // Message map and handlers
1957 BEGIN_MSG_MAP(COwnerDraw< T >)
1958 MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
1959 MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem)
1960 MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem)
1961 MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem)
1962 ALT_MSG_MAP(1)
1963 MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem)
1964 MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureItem)
1965 MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem)
1966 MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem)
1967 END_MSG_MAP()
1968
1969 LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL & bHandled)
1970 {
1971 T* pT = static_cast<T*>(this);
1972 pT->SetMsgHandled(TRUE);
1973 pT->DrawItem((LPDRAWITEMSTRUCT)lParam);
1974 bHandled = pT->IsMsgHandled();
1975 return (LRESULT)TRUE;
1976 }
1977
1978 LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B OOL& bHandled)
1979 {
1980 T* pT = static_cast<T*>(this);
1981 pT->SetMsgHandled(TRUE);
1982 pT->MeasureItem((LPMEASUREITEMSTRUCT)lParam);
1983 bHandled = pT->IsMsgHandled();
1984 return (LRESULT)TRUE;
1985 }
1986
1987 LRESULT OnCompareItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B OOL& bHandled)
1988 {
1989 T* pT = static_cast<T*>(this);
1990 pT->SetMsgHandled(TRUE);
1991 bHandled = pT->IsMsgHandled();
1992 return (LRESULT)pT->CompareItem((LPCOMPAREITEMSTRUCT)lParam);
1993 }
1994
1995 LRESULT OnDeleteItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BO OL& bHandled)
1996 {
1997 T* pT = static_cast<T*>(this);
1998 pT->SetMsgHandled(TRUE);
1999 pT->DeleteItem((LPDELETEITEMSTRUCT)lParam);
2000 bHandled = pT->IsMsgHandled();
2001 return (LRESULT)TRUE;
2002 }
2003
2004 // Overrideables
2005 void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
2006 {
2007 // must be implemented
2008 ATLASSERT(FALSE);
2009 }
2010
2011 void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
2012 {
2013 if(lpMeasureItemStruct->CtlType != ODT_MENU)
2014 {
2015 // return default height for a system font
2016 T* pT = static_cast<T*>(this);
2017 HWND hWnd = pT->GetDlgItem(lpMeasureItemStruct->CtlID);
2018 CClientDC dc(hWnd);
2019 TEXTMETRIC tm = { 0 };
2020 dc.GetTextMetrics(&tm);
2021
2022 lpMeasureItemStruct->itemHeight = tm.tmHeight;
2023 }
2024 else
2025 lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_ CYMENU);
2026 }
2027
2028 int CompareItem(LPCOMPAREITEMSTRUCT /*lpCompareItemStruct*/)
2029 {
2030 // all items are equal
2031 return 0;
2032 }
2033
2034 void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/)
2035 {
2036 // default - nothing
2037 }
2038 };
2039
2040
2041 ///////////////////////////////////////////////////////////////////////////////
2042 // Update UI macros
2043
2044 // these build the Update UI map inside a class definition
2045 #define BEGIN_UPDATE_UI_MAP(thisClass) \
2046 static const CUpdateUIBase::_AtlUpdateUIMap* GetUpdateUIMap() \
2047 { \
2048 static const _AtlUpdateUIMap theMap[] = \
2049 {
2050
2051 #define UPDATE_ELEMENT(nID, wType) \
2052 { nID, wType },
2053
2054 #define END_UPDATE_UI_MAP() \
2055 { (WORD)-1, 0 } \
2056 }; \
2057 return theMap; \
2058 }
2059
2060 ///////////////////////////////////////////////////////////////////////////////
2061 // CUpdateUI - manages UI elements updating
2062
2063 class CUpdateUIBase
2064 {
2065 public:
2066 // constants
2067 enum
2068 {
2069 // UI element type
2070 UPDUI_MENUPOPUP = 0x0001,
2071 UPDUI_MENUBAR = 0x0002,
2072 UPDUI_CHILDWINDOW = 0x0004,
2073 UPDUI_TOOLBAR = 0x0008,
2074 UPDUI_STATUSBAR = 0x0010,
2075 // state
2076 UPDUI_ENABLED = 0x0000,
2077 UPDUI_DISABLED = 0x0100,
2078 UPDUI_CHECKED = 0x0200,
2079 UPDUI_CHECKED2 = 0x0400,
2080 UPDUI_RADIO = 0x0800,
2081 UPDUI_DEFAULT = 0x1000,
2082 UPDUI_TEXT = 0x2000,
2083 // internal state
2084 UPDUI_CLEARDEFAULT = 0x4000,
2085 };
2086
2087 // element data
2088 struct _AtlUpdateUIElement
2089 {
2090 HWND m_hWnd;
2091 WORD m_wType;
2092
2093 bool operator ==(const _AtlUpdateUIElement& e) const
2094 { return (m_hWnd == e.m_hWnd && m_wType == e.m_wType); }
2095 };
2096
2097 // map data
2098 struct _AtlUpdateUIMap
2099 {
2100 WORD m_nID;
2101 WORD m_wType;
2102
2103 bool operator ==(const _AtlUpdateUIMap& e) const
2104 { return (m_nID == e.m_nID && m_wType == e.m_wType); }
2105 };
2106
2107 // instance data
2108 struct _AtlUpdateUIData
2109 {
2110 WORD m_wState;
2111 union
2112 {
2113 void* m_lpData;
2114 LPTSTR m_lpstrText;
2115 };
2116
2117 bool operator ==(const _AtlUpdateUIData& e) const
2118 { return (m_wState == e.m_wState && m_lpData == e.m_lpData); }
2119 };
2120
2121 ATL::CSimpleArray<_AtlUpdateUIElement> m_UIElements; // elements data
2122 const _AtlUpdateUIMap* m_pUIMap; // static UI data
2123 _AtlUpdateUIData* m_pUIData; // instance UI da ta
2124 WORD m_wDirtyType; // global dirty f lag
2125
2126 bool m_bBlockAccelerators;
2127
2128
2129 // Constructor, destructor
2130 CUpdateUIBase() : m_pUIMap(NULL), m_pUIData(NULL), m_wDirtyType(0), m_bB lockAccelerators(false)
2131 { }
2132
2133 ~CUpdateUIBase()
2134 {
2135 if(m_pUIMap != NULL && m_pUIData != NULL)
2136 {
2137 const _AtlUpdateUIMap* pUIMap = m_pUIMap;
2138 _AtlUpdateUIData* pUIData = m_pUIData;
2139 while(pUIMap->m_nID != (WORD)-1)
2140 {
2141 if(pUIData->m_wState & UPDUI_TEXT)
2142 delete [] pUIData->m_lpstrText;
2143 pUIMap++;
2144 pUIData++;
2145 }
2146 delete [] m_pUIData;
2147 }
2148 }
2149
2150 // Check for disabled commands
2151 bool UIGetBlockAccelerators() const
2152 {
2153 return m_bBlockAccelerators;
2154 }
2155
2156 bool UISetBlockAccelerators(bool bBlock)
2157 {
2158 bool bOld = m_bBlockAccelerators;
2159 m_bBlockAccelerators = bBlock;
2160 return bOld;
2161 }
2162
2163 // Add elements
2164 BOOL UIAddMenuBar(HWND hWnd) // menu bar (main menu)
2165 {
2166 if(hWnd == NULL)
2167 return FALSE;
2168 _AtlUpdateUIElement e;
2169 e.m_hWnd = hWnd;
2170 e.m_wType = UPDUI_MENUBAR;
2171 return m_UIElements.Add(e);
2172 }
2173
2174 BOOL UIAddToolBar(HWND hWnd) // toolbar
2175 {
2176 if(hWnd == NULL)
2177 return FALSE;
2178 _AtlUpdateUIElement e;
2179 e.m_hWnd = hWnd;
2180 e.m_wType = UPDUI_TOOLBAR;
2181 return m_UIElements.Add(e);
2182 }
2183
2184 BOOL UIAddStatusBar(HWND hWnd) // status bar
2185 {
2186 if(hWnd == NULL)
2187 return FALSE;
2188 _AtlUpdateUIElement e;
2189 e.m_hWnd = hWnd;
2190 e.m_wType = UPDUI_STATUSBAR;
2191 return m_UIElements.Add(e);
2192 }
2193
2194 BOOL UIAddChildWindowContainer(HWND hWnd) // child window
2195 {
2196 if(hWnd == NULL)
2197 return FALSE;
2198 _AtlUpdateUIElement e;
2199 e.m_hWnd = hWnd;
2200 e.m_wType = UPDUI_CHILDWINDOW;
2201 return m_UIElements.Add(e);
2202 }
2203
2204 // Message map for popup menu updates and accelerator blocking
2205 BEGIN_MSG_MAP(CUpdateUIBase)
2206 MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup)
2207 MESSAGE_HANDLER(WM_COMMAND, OnCommand)
2208 END_MSG_MAP()
2209
2210 LRESULT OnInitMenuPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2211 {
2212 bHandled = FALSE;
2213 HMENU hMenu = (HMENU)wParam;
2214 if(hMenu == NULL)
2215 return 1;
2216 _AtlUpdateUIData* pUIData = m_pUIData;
2217 if(pUIData == NULL)
2218 return 1;
2219 const _AtlUpdateUIMap* pMap = m_pUIMap;
2220 while(pMap->m_nID != (WORD)-1)
2221 {
2222 if(pMap->m_wType & UPDUI_MENUPOPUP)
2223 UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMe nu);
2224 pMap++;
2225 pUIData++;
2226 }
2227 return 0;
2228 }
2229
2230 LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
2231 {
2232 bHandled = FALSE;
2233 if(m_bBlockAccelerators && HIWORD(wParam) == 1) // accelerator s only
2234 {
2235 int nID = LOWORD(wParam);
2236 if((UIGetState(nID) & UPDUI_DISABLED) == UPDUI_DISABLED)
2237 {
2238 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIBase::OnCo mmand - blocked disabled command 0x%4.4X\n"), nID);
2239 bHandled = TRUE; // eat the command, UI item i s disabled
2240 }
2241 }
2242 return 0;
2243 }
2244
2245 // methods for setting UI element state
2246 BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE)
2247 {
2248 const _AtlUpdateUIMap* pMap = m_pUIMap;
2249 _AtlUpdateUIData* pUIData = m_pUIData;
2250 if(pUIData == NULL)
2251 return FALSE;
2252
2253 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2254 {
2255 if(nID == (int)pMap->m_nID)
2256 {
2257 if(bEnable)
2258 {
2259 if(pUIData->m_wState & UPDUI_DISABLED)
2260 {
2261 pUIData->m_wState |= pMap->m_wTy pe;
2262 pUIData->m_wState &= ~UPDUI_DISA BLED;
2263 }
2264 }
2265 else
2266 {
2267 if(!(pUIData->m_wState & UPDUI_DISABLED) )
2268 {
2269 pUIData->m_wState |= pMap->m_wTy pe;
2270 pUIData->m_wState |= UPDUI_DISAB LED;
2271 }
2272 }
2273
2274 if(bForceUpdate)
2275 pUIData->m_wState |= pMap->m_wType;
2276 if(pUIData->m_wState & pMap->m_wType)
2277 m_wDirtyType |= pMap->m_wType;
2278
2279 break; // found
2280 }
2281 }
2282
2283 return TRUE;
2284 }
2285
2286 BOOL UISetCheck(int nID, int nCheck, BOOL bForceUpdate = FALSE)
2287 {
2288 const _AtlUpdateUIMap* pMap = m_pUIMap;
2289 _AtlUpdateUIData* pUIData = m_pUIData;
2290 if(pUIData == NULL)
2291 return FALSE;
2292
2293 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2294 {
2295 if(nID == (int)pMap->m_nID)
2296 {
2297 switch(nCheck)
2298 {
2299 case 0:
2300 if((pUIData->m_wState & UPDUI_CHECKED) | | (pUIData->m_wState & UPDUI_CHECKED2))
2301 {
2302 pUIData->m_wState |= pMap->m_wTy pe;
2303 pUIData->m_wState &= ~(UPDUI_CHE CKED | UPDUI_CHECKED2);
2304 }
2305 break;
2306 case 1:
2307 if(!(pUIData->m_wState & UPDUI_CHECKED))
2308 {
2309 pUIData->m_wState |= pMap->m_wTy pe;
2310 pUIData->m_wState &= ~UPDUI_CHEC KED2;
2311 pUIData->m_wState |= UPDUI_CHECK ED;
2312 }
2313 break;
2314 case 2:
2315 if(!(pUIData->m_wState & UPDUI_CHECKED2) )
2316 {
2317 pUIData->m_wState |= pMap->m_wTy pe;
2318 pUIData->m_wState &= ~UPDUI_CHEC KED;
2319 pUIData->m_wState |= UPDUI_CHECK ED2;
2320 }
2321 break;
2322 }
2323
2324 if(bForceUpdate)
2325 pUIData->m_wState |= pMap->m_wType;
2326 if(pUIData->m_wState & pMap->m_wType)
2327 m_wDirtyType |= pMap->m_wType;
2328
2329 break; // found
2330 }
2331 }
2332
2333 return TRUE;
2334 }
2335
2336 // variant that supports bool (checked/not-checked, no intermediate stat e)
2337 BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE)
2338 {
2339 return UISetCheck(nID, bCheck ? 1 : 0, bForceUpdate);
2340 }
2341
2342 BOOL UISetRadio(int nID, BOOL bRadio, BOOL bForceUpdate = FALSE)
2343 {
2344 const _AtlUpdateUIMap* pMap = m_pUIMap;
2345 _AtlUpdateUIData* pUIData = m_pUIData;
2346 if(pUIData == NULL)
2347 return FALSE;
2348
2349 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2350 {
2351 if(nID == (int)pMap->m_nID)
2352 {
2353 if(bRadio)
2354 {
2355 if(!(pUIData->m_wState & UPDUI_RADIO))
2356 {
2357 pUIData->m_wState |= pMap->m_wTy pe;
2358 pUIData->m_wState |= UPDUI_RADIO ;
2359 }
2360 }
2361 else
2362 {
2363 if(pUIData->m_wState & UPDUI_RADIO)
2364 {
2365 pUIData->m_wState |= pMap->m_wTy pe;
2366 pUIData->m_wState &= ~UPDUI_RADI O;
2367 }
2368 }
2369
2370 if(bForceUpdate)
2371 pUIData->m_wState |= pMap->m_wType;
2372 if(pUIData->m_wState & pMap->m_wType)
2373 m_wDirtyType |= pMap->m_wType;
2374
2375 break; // found
2376 }
2377 }
2378
2379 return TRUE;
2380 }
2381
2382 BOOL UISetText(int nID, LPCTSTR lpstrText, BOOL bForceUpdate = FALSE)
2383 {
2384 const _AtlUpdateUIMap* pMap = m_pUIMap;
2385 _AtlUpdateUIData* pUIData = m_pUIData;
2386 if(pUIData == NULL)
2387 return FALSE;
2388 if(lpstrText == NULL)
2389 lpstrText = _T("");
2390
2391 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2392 {
2393 if(nID == (int)pMap->m_nID)
2394 {
2395 if(pUIData->m_lpstrText == NULL || lstrcmp(pUIDa ta->m_lpstrText, lpstrText))
2396 {
2397 delete [] pUIData->m_lpstrText;
2398 pUIData->m_lpstrText = NULL;
2399 int nStrLen = lstrlen(lpstrText);
2400 ATLTRY(pUIData->m_lpstrText = new TCHAR[ nStrLen + 1]);
2401 if(pUIData->m_lpstrText == NULL)
2402 {
2403 ATLTRACE2(atlTraceUI, 0, _T("UIS etText - memory allocation failed\n"));
2404 break;
2405 }
2406 SecureHelper::strcpy_x(pUIData->m_lpstrT ext, nStrLen + 1, lpstrText);
2407 pUIData->m_wState |= (UPDUI_TEXT | pMap- >m_wType);
2408 }
2409
2410 if(bForceUpdate)
2411 pUIData->m_wState |= (UPDUI_TEXT | pMap- >m_wType);
2412 if(pUIData->m_wState & pMap->m_wType)
2413 m_wDirtyType |= pMap->m_wType;
2414
2415 break; // found
2416 }
2417 }
2418
2419 return TRUE;
2420 }
2421
2422 BOOL UISetDefault(int nID, BOOL bDefault, BOOL bForceUpdate = FALSE)
2423 {
2424 const _AtlUpdateUIMap* pMap = m_pUIMap;
2425 _AtlUpdateUIData* pUIData = m_pUIData;
2426 if(pUIData == NULL)
2427 return FALSE;
2428
2429 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2430 {
2431 if(nID == (int)pMap->m_nID)
2432 {
2433 if(bDefault)
2434 {
2435 if((pUIData->m_wState & UPDUI_DEFAULT) = = 0)
2436 {
2437 pUIData->m_wState |= pMap->m_wTy pe;
2438 pUIData->m_wState |= UPDUI_DEFAU LT;
2439 }
2440 }
2441 else
2442 {
2443 if((pUIData->m_wState & UPDUI_DEFAULT) ! = 0)
2444 {
2445 pUIData->m_wState |= pMap->m_wTy pe;
2446 pUIData->m_wState &= ~UPDUI_DEFA ULT;
2447 pUIData->m_wState |= UPDUI_CLEAR DEFAULT;
2448 }
2449 }
2450
2451 if(bForceUpdate)
2452 pUIData->m_wState |= pMap->m_wType;
2453 if(pUIData->m_wState & pMap->m_wType)
2454 m_wDirtyType |= pMap->m_wType;
2455
2456 break; // found
2457 }
2458 }
2459
2460 return TRUE;
2461 }
2462
2463 // methods for complete state set/get
2464 BOOL UISetState(int nID, DWORD dwState)
2465 {
2466 const _AtlUpdateUIMap* pMap = m_pUIMap;
2467 _AtlUpdateUIData* pUIData = m_pUIData;
2468 if(pUIData == NULL)
2469 return FALSE;
2470 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2471 {
2472 if(nID == (int)pMap->m_nID)
2473 {
2474 pUIData->m_wState = (WORD)(dwState | pMap->m_wTy pe);
2475 m_wDirtyType |= pMap->m_wType;
2476 break; // found
2477 }
2478 }
2479 return TRUE;
2480 }
2481
2482 DWORD UIGetState(int nID)
2483 {
2484 const _AtlUpdateUIMap* pMap = m_pUIMap;
2485 _AtlUpdateUIData* pUIData = m_pUIData;
2486 if(pUIData == NULL)
2487 return 0;
2488 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++)
2489 {
2490 if(nID == (int)pMap->m_nID)
2491 return pUIData->m_wState;
2492 }
2493 return 0;
2494 }
2495
2496 // methods for updating UI
2497 #ifndef _WIN32_WCE
2498 BOOL UIUpdateMenuBar(BOOL bForceUpdate = FALSE, BOOL bMainMenu = FALSE)
2499 {
2500 if(!(m_wDirtyType & UPDUI_MENUBAR) && !bForceUpdate)
2501 return TRUE;
2502
2503 const _AtlUpdateUIMap* pMap = m_pUIMap;
2504 _AtlUpdateUIData* pUIData = m_pUIData;
2505 if(pUIData == NULL)
2506 return FALSE;
2507
2508 while(pMap->m_nID != (WORD)-1)
2509 {
2510 for(int i = 0; i < m_UIElements.GetSize(); i++)
2511 {
2512 if(m_UIElements[i].m_wType == UPDUI_MENUBAR)
2513 {
2514 HMENU hMenu = ::GetMenu(m_UIElements[i]. m_hWnd);
2515 if(hMenu != NULL && (pUIData->m_wState & UPDUI_MENUBAR) && (pMap->m_wType & UPDUI_MENUBAR))
2516 UIUpdateMenuBarElement(pMap->m_n ID, pUIData, hMenu);
2517 }
2518 if(bMainMenu)
2519 ::DrawMenuBar(m_UIElements[i].m_hWnd);
2520 }
2521 pMap++;
2522 pUIData->m_wState &= ~UPDUI_MENUBAR;
2523 if(pUIData->m_wState & UPDUI_TEXT)
2524 {
2525 delete [] pUIData->m_lpstrText;
2526 pUIData->m_lpstrText = NULL;
2527 pUIData->m_wState &= ~UPDUI_TEXT;
2528 }
2529 pUIData++;
2530 }
2531
2532 m_wDirtyType &= ~UPDUI_MENUBAR;
2533 return TRUE;
2534 }
2535 #endif // !_WIN32_WCE
2536
2537 BOOL UIUpdateToolBar(BOOL bForceUpdate = FALSE)
2538 {
2539 if(!(m_wDirtyType & UPDUI_TOOLBAR) && !bForceUpdate)
2540 return TRUE;
2541
2542 const _AtlUpdateUIMap* pMap = m_pUIMap;
2543 _AtlUpdateUIData* pUIData = m_pUIData;
2544 if(pUIData == NULL)
2545 return FALSE;
2546
2547 while(pMap->m_nID != (WORD)-1)
2548 {
2549 for(int i = 0; i < m_UIElements.GetSize(); i++)
2550 {
2551 if(m_UIElements[i].m_wType == UPDUI_TOOLBAR)
2552 {
2553 if((pUIData->m_wState & UPDUI_TOOLBAR) & & (pMap->m_wType & UPDUI_TOOLBAR))
2554 UIUpdateToolBarElement(pMap->m_n ID, pUIData, m_UIElements[i].m_hWnd);
2555 }
2556 }
2557 pMap++;
2558 pUIData->m_wState &= ~UPDUI_TOOLBAR;
2559 pUIData++;
2560 }
2561
2562 m_wDirtyType &= ~UPDUI_TOOLBAR;
2563 return TRUE;
2564 }
2565
2566 BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE)
2567 {
2568 if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate)
2569 return TRUE;
2570
2571 const _AtlUpdateUIMap* pMap = m_pUIMap;
2572 _AtlUpdateUIData* pUIData = m_pUIData;
2573 if(pUIData == NULL)
2574 return FALSE;
2575
2576 while(pMap->m_nID != (WORD)-1)
2577 {
2578 for(int i = 0; i < m_UIElements.GetSize(); i++)
2579 {
2580 if(m_UIElements[i].m_wType == UPDUI_STATUSBAR)
2581 {
2582 if((pUIData->m_wState & UPDUI_STATUSBAR) && (pMap->m_wType & UPDUI_STATUSBAR))
2583 UIUpdateStatusBarElement(pMap->m _nID, pUIData, m_UIElements[i].m_hWnd);
2584 }
2585 }
2586 pMap++;
2587 pUIData->m_wState &= ~UPDUI_STATUSBAR;
2588 if(pUIData->m_wState & UPDUI_TEXT)
2589 {
2590 delete [] pUIData->m_lpstrText;
2591 pUIData->m_lpstrText = NULL;
2592 pUIData->m_wState &= ~UPDUI_TEXT;
2593 }
2594 pUIData++;
2595 }
2596
2597 m_wDirtyType &= ~UPDUI_STATUSBAR;
2598 return TRUE;
2599 }
2600
2601 BOOL UIUpdateChildWindows(BOOL bForceUpdate = FALSE)
2602 {
2603 if(!(m_wDirtyType & UPDUI_CHILDWINDOW) && !bForceUpdate)
2604 return TRUE;
2605
2606 const _AtlUpdateUIMap* pMap = m_pUIMap;
2607 _AtlUpdateUIData* pUIData = m_pUIData;
2608 if(pUIData == NULL)
2609 return FALSE;
2610
2611 while(pMap->m_nID != (WORD)-1)
2612 {
2613 for(int i = 0; i < m_UIElements.GetSize(); i++)
2614 {
2615 if(m_UIElements[i].m_wType == UPDUI_CHILDWINDOW)
2616 {
2617 if((pUIData->m_wState & UPDUI_CHILDWINDO W) && (pMap->m_wType & UPDUI_CHILDWINDOW))
2618 UIUpdateChildWindow(pMap->m_nID, pUIData, m_UIElements[i].m_hWnd);
2619 }
2620 }
2621 pMap++;
2622 pUIData->m_wState &= ~UPDUI_CHILDWINDOW;
2623 if(pUIData->m_wState & UPDUI_TEXT)
2624 {
2625 delete [] pUIData->m_lpstrText;
2626 pUIData->m_lpstrText = NULL;
2627 pUIData->m_wState &= ~UPDUI_TEXT;
2628 }
2629 pUIData++;
2630 }
2631
2632 m_wDirtyType &= ~UPDUI_CHILDWINDOW;
2633 return TRUE;
2634 }
2635
2636 // internal element specific methods
2637 static void UIUpdateMenuBarElement(int nID, _AtlUpdateUIData* pUIData, H MENU hMenu)
2638 {
2639 #ifndef _WIN32_WCE
2640 if((pUIData->m_wState & UPDUI_CLEARDEFAULT) != 0)
2641 {
2642 ::SetMenuDefaultItem(hMenu, (UINT)-1, 0);
2643 pUIData->m_wState &= ~UPDUI_CLEARDEFAULT;
2644 }
2645 #endif // !_WIN32_WCE
2646
2647 CMenuItemInfo mii;
2648 mii.fMask = MIIM_STATE;
2649 mii.wID = nID;
2650
2651 #ifndef _WIN32_WCE
2652 if((pUIData->m_wState & UPDUI_DISABLED) != 0)
2653 mii.fState |= MFS_DISABLED | MFS_GRAYED;
2654 else
2655 mii.fState |= MFS_ENABLED;
2656
2657 if((pUIData->m_wState & UPDUI_CHECKED) != 0)
2658 mii.fState |= MFS_CHECKED;
2659 else
2660 mii.fState |= MFS_UNCHECKED;
2661
2662 if((pUIData->m_wState & UPDUI_DEFAULT) != 0)
2663 mii.fState |= MFS_DEFAULT;
2664 #else // CE specific
2665 // ::SetMenuItemInfo() can't disable or check menu items
2666 // on Windows CE, so we have to do that directly
2667 UINT uEnable = MF_BYCOMMAND;
2668 if((pUIData->m_wState & UPDUI_DISABLED) != 0)
2669 uEnable |= MF_GRAYED;
2670 else
2671 uEnable |= MF_ENABLED;
2672 ::EnableMenuItem(hMenu, nID, uEnable);
2673
2674 UINT uCheck = MF_BYCOMMAND;
2675 if((pUIData->m_wState & UPDUI_CHECKED) != 0)
2676 uCheck |= MF_CHECKED;
2677 else
2678 uCheck |= MF_UNCHECKED;
2679 ::CheckMenuItem(hMenu, nID, uCheck);
2680 #endif // _WIN32_WCE
2681
2682 if((pUIData->m_wState & UPDUI_TEXT) != 0)
2683 {
2684 CMenuItemInfo miiNow;
2685 miiNow.fMask = MIIM_TYPE;
2686 miiNow.wID = nID;
2687 if(::GetMenuItemInfo(hMenu, nID, FALSE, &miiNow))
2688 {
2689 mii.fMask |= MIIM_TYPE;
2690 // MFT_BITMAP and MFT_SEPARATOR don't go togethe r with MFT_STRING
2691 #ifndef _WIN32_WCE
2692 mii.fType |= (miiNow.fType & ~(MFT_BITMAP | MFT_ SEPARATOR)) | MFT_STRING;
2693 #else // CE specific
2694 mii.fType |= (miiNow.fType & ~(MFT_SEPARATOR)) | MFT_STRING;
2695 #endif // _WIN32_WCE
2696 mii.dwTypeData = pUIData->m_lpstrText;
2697 }
2698 }
2699
2700 ::SetMenuItemInfo(hMenu, nID, FALSE, &mii);
2701 }
2702
2703 static void UIUpdateToolBarElement(int nID, _AtlUpdateUIData* pUIData, H WND hWndToolBar)
2704 {
2705 // Note: only handles enabled/disabled, checked state, and radio (press)
2706 ::SendMessage(hWndToolBar, TB_ENABLEBUTTON, nID, (LPARAM)(pUIDat a->m_wState & UPDUI_DISABLED) ? FALSE : TRUE);
2707 ::SendMessage(hWndToolBar, TB_CHECKBUTTON, nID, (LPARAM)(pUIData ->m_wState & UPDUI_CHECKED) ? TRUE : FALSE);
2708 ::SendMessage(hWndToolBar, TB_INDETERMINATE, nID, (LPARAM)(pUIDa ta->m_wState & UPDUI_CHECKED2) ? TRUE : FALSE);
2709 ::SendMessage(hWndToolBar, TB_PRESSBUTTON, nID, (LPARAM)(pUIData ->m_wState & UPDUI_RADIO) ? TRUE : FALSE);
2710 }
2711
2712 static void UIUpdateStatusBarElement(int nID, _AtlUpdateUIData* pUIData, HWND hWndStatusBar)
2713 {
2714 // Note: only handles text
2715 if(pUIData->m_wState & UPDUI_TEXT)
2716 ::SendMessage(hWndStatusBar, SB_SETTEXT, nID, (LPARAM)pU IData->m_lpstrText);
2717 }
2718
2719 static void UIUpdateChildWindow(int nID, _AtlUpdateUIData* pUIData, HWND hWnd)
2720 {
2721 HWND hChild = ::GetDlgItem(hWnd, nID);
2722
2723 ::EnableWindow(hChild, (pUIData->m_wState & UPDUI_DISABLED) ? FA LSE : TRUE);
2724 // for check and radio, assume that window is a button
2725 int nCheck = BST_UNCHECKED;
2726 if(pUIData->m_wState & UPDUI_CHECKED || pUIData->m_wState & UPDU I_RADIO)
2727 nCheck = BST_CHECKED;
2728 else if(pUIData->m_wState & UPDUI_CHECKED2)
2729 nCheck = BST_INDETERMINATE;
2730 ::SendMessage(hChild, BM_SETCHECK, nCheck, 0L);
2731 if(pUIData->m_wState & UPDUI_DEFAULT)
2732 {
2733 DWORD dwRet = (DWORD)::SendMessage(hWnd, DM_GETDEFID, 0, 0L);
2734 if(HIWORD(dwRet) == DC_HASDEFID)
2735 {
2736 HWND hOldDef = ::GetDlgItem(hWnd, (int)(short)LO WORD(dwRet));
2737 // remove BS_DEFPUSHBUTTON
2738 ::SendMessage(hOldDef, BM_SETSTYLE, BS_PUSHBUTTO N, MAKELPARAM(TRUE, 0));
2739 }
2740 ::SendMessage(hWnd, DM_SETDEFID, nID, 0L);
2741 }
2742 if(pUIData->m_wState & UPDUI_TEXT)
2743 ::SetWindowText(hChild, pUIData->m_lpstrText);
2744 }
2745 };
2746
2747 template <class T>
2748 class CUpdateUI : public CUpdateUIBase
2749 {
2750 public:
2751 CUpdateUI()
2752 {
2753 T* pT = static_cast<T*>(this);
2754 pT;
2755 const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap();
2756 m_pUIMap = pMap;
2757 ATLASSERT(m_pUIMap != NULL);
2758 int nCount;
2759 for(nCount = 1; pMap->m_nID != (WORD)-1; nCount++)
2760 pMap++;
2761
2762 // check for duplicates (debug only)
2763 #ifdef _DEBUG
2764 for(int i = 0; i < nCount; i++)
2765 {
2766 for(int j = 0; j < nCount; j++)
2767 {
2768 // shouldn't have duplicates in the update UI ma p
2769 if(i != j)
2770 ATLASSERT(m_pUIMap[j].m_nID != m_pUIMap[ i].m_nID);
2771 }
2772 }
2773 #endif // _DEBUG
2774
2775 ATLTRY(m_pUIData = new _AtlUpdateUIData[nCount]);
2776 ATLASSERT(m_pUIData != NULL);
2777
2778 if(m_pUIData != NULL)
2779 memset(m_pUIData, 0, sizeof(_AtlUpdateUIData) * nCount);
2780 }
2781 };
2782
2783
2784 ///////////////////////////////////////////////////////////////////////////////
2785 // CDynamicUpdateUI - allows update elements to dynamically added and removed
2786 // in addition to a static update UI map
2787
2788 template <class T>
2789 class CDynamicUpdateUI : public CUpdateUIBase
2790 {
2791 public:
2792 // Data members
2793 ATL::CSimpleArray<_AtlUpdateUIMap> m_arrUIMap; // copy of the static UI data
2794 ATL::CSimpleArray<_AtlUpdateUIData> m_arrUIData; // instance UI data
2795
2796 // Constructor/destructor
2797 CDynamicUpdateUI()
2798 {
2799 T* pT = static_cast<T*>(this);
2800 pT;
2801 const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap();
2802 ATLASSERT(pMap != NULL);
2803
2804 for(;;)
2805 {
2806 BOOL bRet = m_arrUIMap.Add(*(_AtlUpdateUIMap*)pMap);
2807 ATLASSERT(bRet);
2808
2809 if(bRet != FALSE)
2810 {
2811 _AtlUpdateUIData data = { 0, NULL };
2812 bRet = m_arrUIData.Add(data);
2813 ATLASSERT(bRet);
2814 }
2815
2816 if(pMap->m_nID == (WORD)-1)
2817 break;
2818
2819 pMap++;
2820 }
2821
2822 ATLASSERT(m_arrUIMap.GetSize() == m_arrUIData.GetSize());
2823
2824 #ifdef _DEBUG
2825 // check for duplicates (debug only)
2826 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2827 {
2828 for(int j = 0; j < m_arrUIMap.GetSize(); j++)
2829 {
2830 // shouldn't have duplicates in the update UI ma p
2831 if(i != j)
2832 ATLASSERT(m_arrUIMap[j].m_nID != m_arrUI Map[i].m_nID);
2833 }
2834 }
2835 #endif // _DEBUG
2836
2837 // Set internal data pointers to point to the new data arrays
2838 m_pUIMap = m_arrUIMap.m_aT;
2839 m_pUIData = m_arrUIData.m_aT;
2840 }
2841
2842 ~CDynamicUpdateUI()
2843 {
2844 for(int i = 0; i < m_arrUIData.GetSize(); i++)
2845 {
2846 if((m_arrUIData[i].m_wState & UPDUI_TEXT) != 0)
2847 delete [] m_arrUIData[i].m_lpstrText;
2848 }
2849
2850 // Reset internal data pointers (memory will be released by CSim pleArray d-tor)
2851 m_pUIMap = NULL;
2852 m_pUIData = NULL;
2853 }
2854
2855 // Methods for dynamically adding and removing update elements
2856 bool UIAddUpdateElement(WORD nID, WORD wType)
2857 {
2858 // check for duplicates
2859 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2860 {
2861 // shouldn't have duplicates in the update UI map
2862 ATLASSERT(m_arrUIMap[i].m_nID != nID);
2863 if(m_arrUIMap[i].m_nID == nID)
2864 return false;
2865 }
2866
2867 bool bRetVal = false;
2868
2869 // Add new end element
2870 _AtlUpdateUIMap uumEnd = { (WORD)-1, 0 };
2871 BOOL bRet = m_arrUIMap.Add(uumEnd);
2872 ATLASSERT(bRet);
2873
2874 if(bRet != FALSE)
2875 {
2876 _AtlUpdateUIData uud = { 0, NULL };
2877 bRet = m_arrUIData.Add(uud);
2878 ATLASSERT(bRet);
2879
2880 // Set new data to the previous end element
2881 if(bRet != FALSE)
2882 {
2883 int nSize = m_arrUIMap.GetSize();
2884 _AtlUpdateUIMap uum = { nID, wType };
2885 m_arrUIMap.SetAtIndex(nSize - 2, uum);
2886 m_arrUIData.SetAtIndex(nSize - 2, uud);
2887
2888 // Set internal data pointers again, just in cas e that memory moved
2889 m_pUIMap = m_arrUIMap.m_aT;
2890 m_pUIData = m_arrUIData.m_aT;
2891
2892 bRetVal = true;
2893 }
2894 }
2895
2896 return bRetVal;
2897 }
2898
2899 bool UIRemoveUpdateElement(WORD nID)
2900 {
2901 bool bRetVal = false;
2902
2903 for(int i = 0; i < m_arrUIMap.GetSize(); i++)
2904 {
2905 if(m_arrUIMap[i].m_nID == nID)
2906 {
2907 BOOL bRet = m_arrUIMap.RemoveAt(i);
2908 ATLASSERT(bRet);
2909 bRet = m_arrUIData.RemoveAt(i);
2910 ATLASSERT(bRet);
2911
2912 bRetVal = true;
2913 break;
2914 }
2915 }
2916
2917 return bRetVal;
2918 }
2919 };
2920
2921
2922 ///////////////////////////////////////////////////////////////////////////////
2923 // CDialogResize - provides support for resizing dialog controls
2924 // (works for any window that has child controls)
2925
2926 // Put CDialogResize in the list of base classes for a dialog (or even plain win dow),
2927 // then implement DLGRESIZE map by specifying controls and groups of control
2928 // and using DLSZ_* values to specify how are they supposed to be resized.
2929 //
2930 // Notes:
2931 // - Resizeable border (WS_THICKFRAME style) should be set in the dialog templat e
2932 // for top level dialogs (popup or overlapped), so that users can resize the d ialog.
2933 // - Some flags cannot be combined; for instance DLSZ_CENTER_X overrides DLSZ_SI ZE_X,
2934 // DLSZ_SIZE_X overrides DLSZ_MOVE_X. X and Y flags can be combined.
2935 // - Order of controls is important - group controls are resized and moved based
2936 // on the position of the previous control in a group.
2937
2938 // dialog resize map macros
2939 #define BEGIN_DLGRESIZE_MAP(thisClass) \
2940 static const _AtlDlgResizeMap* GetDlgResizeMap() \
2941 { \
2942 static const _AtlDlgResizeMap theMap[] = \
2943 {
2944
2945 #define END_DLGRESIZE_MAP() \
2946 { -1, 0 }, \
2947 }; \
2948 return theMap; \
2949 }
2950
2951 #define DLGRESIZE_CONTROL(id, flags) \
2952 { id, flags },
2953
2954 #define BEGIN_DLGRESIZE_GROUP() \
2955 { -1, _DLSZ_BEGIN_GROUP },
2956
2957 #define END_DLGRESIZE_GROUP() \
2958 { -1, _DLSZ_END_GROUP },
2959
2960
2961 template <class T>
2962 class CDialogResize
2963 {
2964 public:
2965 // Data declarations and members
2966 enum
2967 {
2968 DLSZ_SIZE_X = 0x00000001,
2969 DLSZ_SIZE_Y = 0x00000002,
2970 DLSZ_MOVE_X = 0x00000004,
2971 DLSZ_MOVE_Y = 0x00000008,
2972 DLSZ_REPAINT = 0x00000010,
2973 DLSZ_CENTER_X = 0x00000020,
2974 DLSZ_CENTER_Y = 0x00000040,
2975
2976 // internal use only
2977 _DLSZ_BEGIN_GROUP = 0x00001000,
2978 _DLSZ_END_GROUP = 0x00002000,
2979 _DLSZ_GRIPPER = 0x00004000
2980 };
2981
2982 struct _AtlDlgResizeMap
2983 {
2984 int m_nCtlID;
2985 DWORD m_dwResizeFlags;
2986 };
2987
2988 struct _AtlDlgResizeData
2989 {
2990 int m_nCtlID;
2991 DWORD m_dwResizeFlags;
2992 RECT m_rect;
2993
2994 int GetGroupCount() const
2995 {
2996 return (int)LOBYTE(HIWORD(m_dwResizeFlags));
2997 }
2998
2999 void SetGroupCount(int nCount)
3000 {
3001 ATLASSERT(nCount > 0 && nCount < 256);
3002 DWORD dwCount = (DWORD)MAKELONG(0, MAKEWORD(nCount, 0));
3003 m_dwResizeFlags &= 0xFF00FFFF;
3004 m_dwResizeFlags |= dwCount;
3005 }
3006
3007 bool operator ==(const _AtlDlgResizeData& r) const
3008 { return (m_nCtlID == r.m_nCtlID && m_dwResizeFlags == r.m_dwRes izeFlags); }
3009 };
3010
3011 ATL::CSimpleArray<_AtlDlgResizeData> m_arrData;
3012 SIZE m_sizeDialog;
3013 POINT m_ptMinTrackSize;
3014 bool m_bGripper;
3015
3016
3017 // Constructor
3018 CDialogResize() : m_bGripper(false)
3019 {
3020 m_sizeDialog.cx = 0;
3021 m_sizeDialog.cy = 0;
3022 m_ptMinTrackSize.x = -1;
3023 m_ptMinTrackSize.y = -1;
3024 }
3025
3026 // Operations
3027 void DlgResize_Init(bool bAddGripper = true, bool bUseMinTrackSize = tru e, DWORD dwForceStyle = WS_CLIPCHILDREN)
3028 {
3029 T* pT = static_cast<T*>(this);
3030 ATLASSERT(::IsWindow(pT->m_hWnd));
3031
3032 DWORD dwStyle = pT->GetStyle();
3033
3034 #ifdef _DEBUG
3035 // Debug only: Check if top level dialogs have a resizeable bord er.
3036 if(((dwStyle & WS_CHILD) == 0) && ((dwStyle & WS_THICKFRAME) == 0))
3037 ATLTRACE2(atlTraceUI, 0, _T("DlgResize_Init - warning: t op level dialog without the WS_THICKFRAME style - user cannot resize it\n"));
3038 #endif // _DEBUG
3039
3040 // Force specified styles (default WS_CLIPCHILDREN reduces flick er)
3041 if((dwStyle & dwForceStyle) != dwForceStyle)
3042 pT->ModifyStyle(0, dwForceStyle);
3043
3044 // Adding this style removes an empty icon that dialogs with WS_ THICKFRAME have.
3045 // Setting icon to NULL is required when XP themes are active.
3046 // Note: This will not prevent adding an icon for the dialog usi ng SetIcon()
3047 if((dwStyle & WS_CHILD) == 0)
3048 {
3049 pT->ModifyStyleEx(0, WS_EX_DLGMODALFRAME);
3050 if(pT->GetIcon(FALSE) == NULL)
3051 pT->SetIcon(NULL, FALSE);
3052 }
3053
3054 // Cleanup in case of multiple initialization
3055 // block: first check for the gripper control, destroy it if nee ded
3056 {
3057 ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_ BAR);
3058 if(wndGripper.IsWindow() && m_arrData.GetSize() > 0 && ( m_arrData[0].m_dwResizeFlags & _DLSZ_GRIPPER) != 0)
3059 wndGripper.DestroyWindow();
3060 }
3061 // clear out everything else
3062 m_arrData.RemoveAll();
3063 m_sizeDialog.cx = 0;
3064 m_sizeDialog.cy = 0;
3065 m_ptMinTrackSize.x = -1;
3066 m_ptMinTrackSize.y = -1;
3067
3068 // Get initial dialog client size
3069 RECT rectDlg = { 0 };
3070 pT->GetClientRect(&rectDlg);
3071 m_sizeDialog.cx = rectDlg.right;
3072 m_sizeDialog.cy = rectDlg.bottom;
3073
3074 #ifndef _WIN32_WCE
3075 // Create gripper if requested
3076 m_bGripper = false;
3077 if(bAddGripper)
3078 {
3079 // shouldn't exist already
3080 ATLASSERT(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR) ));
3081 if(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR)))
3082 {
3083 ATL::CWindow wndGripper;
3084 wndGripper.Create(_T("SCROLLBAR"), pT->m_hWnd, r ectDlg, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEBOX | SBS_SIZEGR IP | SBS_SIZEBOXBOTTOMRIGHTALIGN, 0, ATL_IDW_STATUS_BAR);
3085 ATLASSERT(wndGripper.IsWindow());
3086 if(wndGripper.IsWindow())
3087 {
3088 m_bGripper = true;
3089 RECT rectCtl = { 0 };
3090 wndGripper.GetWindowRect(&rectCtl);
3091 ::MapWindowPoints(NULL, pT->m_hWnd, (LPP OINT)&rectCtl, 2);
3092 _AtlDlgResizeData data = { ATL_IDW_STATU S_BAR, DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | _DLSZ_GRIPPER, { rectCtl.left, rectCtl.top, rectCtl.right, rectCtl.bottom } };
3093 m_arrData.Add(data);
3094 }
3095 }
3096 }
3097 #else // CE specific
3098 bAddGripper; // avoid level 4 warning
3099 #endif // _WIN32_WCE
3100
3101 // Get min track position if requested
3102 if(bUseMinTrackSize)
3103 {
3104 if((dwStyle & WS_CHILD) != 0)
3105 {
3106 RECT rect = { 0 };
3107 pT->GetClientRect(&rect);
3108 m_ptMinTrackSize.x = rect.right - rect.left;
3109 m_ptMinTrackSize.y = rect.bottom - rect.top;
3110 }
3111 else
3112 {
3113 RECT rect = { 0 };
3114 pT->GetWindowRect(&rect);
3115 m_ptMinTrackSize.x = rect.right - rect.left;
3116 m_ptMinTrackSize.y = rect.bottom - rect.top;
3117 }
3118 }
3119
3120 // Walk the map and initialize data
3121 const _AtlDlgResizeMap* pMap = pT->GetDlgResizeMap();
3122 ATLASSERT(pMap != NULL);
3123 int nGroupStart = -1;
3124 for(int nCount = 1; !(pMap->m_nCtlID == -1 && pMap->m_dwResizeFl ags == 0); nCount++, pMap++)
3125 {
3126 if(pMap->m_nCtlID == -1)
3127 {
3128 switch(pMap->m_dwResizeFlags)
3129 {
3130 case _DLSZ_BEGIN_GROUP:
3131 ATLASSERT(nGroupStart == -1);
3132 nGroupStart = m_arrData.GetSize();
3133 break;
3134 case _DLSZ_END_GROUP:
3135 {
3136 ATLASSERT(nGroupStart != -1);
3137 int nGroupCount = m_arrData.GetS ize() - nGroupStart;
3138 m_arrData[nGroupStart].SetGroupC ount(nGroupCount);
3139 nGroupStart = -1;
3140 }
3141 break;
3142 default:
3143 ATLASSERT(FALSE && _T("Invalid DLGRESIZE Map Entry"));
3144 break;
3145 }
3146 }
3147 else
3148 {
3149 // this ID conflicts with the default gripper on e
3150 ATLASSERT(m_bGripper ? (pMap->m_nCtlID != ATL_ID W_STATUS_BAR) : TRUE);
3151
3152 ATL::CWindow ctl = pT->GetDlgItem(pMap->m_nCtlID );
3153 ATLASSERT(ctl.IsWindow());
3154 RECT rectCtl = { 0 };
3155 ctl.GetWindowRect(&rectCtl);
3156 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&re ctCtl, 2);
3157
3158 DWORD dwGroupFlag = (nGroupStart != -1 && m_arrD ata.GetSize() == nGroupStart) ? _DLSZ_BEGIN_GROUP : 0;
3159 _AtlDlgResizeData data = { pMap->m_nCtlID, pMap- >m_dwResizeFlags | dwGroupFlag, { rectCtl.left, rectCtl.top, rectCtl.right, rect Ctl.bottom } };
3160 m_arrData.Add(data);
3161 }
3162 }
3163 ATLASSERT((nGroupStart == -1) && _T("No End Group Entry in the D LGRESIZE Map"));
3164 }
3165
3166 void DlgResize_UpdateLayout(int cxWidth, int cyHeight)
3167 {
3168 T* pT = static_cast<T*>(this);
3169 ATLASSERT(::IsWindow(pT->m_hWnd));
3170
3171 // Restrict minimum size if requested
3172 if(((pT->GetStyle() & WS_CHILD) != 0) && m_ptMinTrackSize.x != - 1 && m_ptMinTrackSize.y != -1)
3173 {
3174 if(cxWidth < m_ptMinTrackSize.x)
3175 cxWidth = m_ptMinTrackSize.x;
3176 if(cyHeight < m_ptMinTrackSize.y)
3177 cyHeight = m_ptMinTrackSize.y;
3178 }
3179
3180 BOOL bVisible = pT->IsWindowVisible();
3181 if(bVisible)
3182 pT->SetRedraw(FALSE);
3183
3184 for(int i = 0; i < m_arrData.GetSize(); i++)
3185 {
3186 if((m_arrData[i].m_dwResizeFlags & _DLSZ_BEGIN_GROUP) != 0) // start of a group
3187 {
3188 int nGroupCount = m_arrData[i].GetGroupCount();
3189 ATLASSERT(nGroupCount > 0 && i + nGroupCount - 1 < m_arrData.GetSize());
3190 RECT rectGroup = m_arrData[i].m_rect;
3191
3192 int j = 1;
3193 for(j = 1; j < nGroupCount; j++)
3194 {
3195 rectGroup.left = __min(rectGroup.left, m _arrData[i + j].m_rect.left);
3196 rectGroup.top = __min(rectGroup.top, m_a rrData[i + j].m_rect.top);
3197 rectGroup.right = __max(rectGroup.right, m_arrData[i + j].m_rect.right);
3198 rectGroup.bottom = __max(rectGroup.botto m, m_arrData[i + j].m_rect.bottom);
3199 }
3200
3201 for(j = 0; j < nGroupCount; j++)
3202 {
3203 _AtlDlgResizeData* pDataPrev = NULL;
3204 if(j > 0)
3205 pDataPrev = &(m_arrData[i + j - 1]);
3206 pT->DlgResize_PositionControl(cxWidth, c yHeight, rectGroup, m_arrData[i + j], true, pDataPrev);
3207 }
3208
3209 i += nGroupCount - 1; // increment to skip all group controls
3210 }
3211 else // one control entry
3212 {
3213 RECT rectGroup = { 0, 0, 0, 0 };
3214 pT->DlgResize_PositionControl(cxWidth, cyHeight, rectGroup, m_arrData[i], false);
3215 }
3216 }
3217
3218 if(bVisible)
3219 pT->SetRedraw(TRUE);
3220
3221 pT->RedrawWindow(NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UP DATENOW | RDW_ALLCHILDREN);
3222 }
3223
3224 // Message map and handlers
3225 BEGIN_MSG_MAP(CDialogResize)
3226 MESSAGE_HANDLER(WM_SIZE, OnSize)
3227 #ifndef _WIN32_WCE
3228 MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
3229 #endif // _WIN32_WCE
3230 END_MSG_MAP()
3231
3232 LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHan dled*/)
3233 {
3234 T* pT = static_cast<T*>(this);
3235 #ifndef _WIN32_WCE
3236 if(m_bGripper)
3237 {
3238 ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_ BAR);
3239 if(wParam == SIZE_MAXIMIZED)
3240 wndGripper.ShowWindow(SW_HIDE);
3241 else if(wParam == SIZE_RESTORED)
3242 wndGripper.ShowWindow(SW_SHOW);
3243 }
3244 #endif // _WIN32_WCE
3245 if(wParam != SIZE_MINIMIZED)
3246 {
3247 ATLASSERT(::IsWindow(pT->m_hWnd));
3248 pT->DlgResize_UpdateLayout(GET_X_LPARAM(lParam), GET_Y_L PARAM(lParam));
3249 }
3250 return 0;
3251 }
3252
3253 #ifndef _WIN32_WCE
3254 LRESULT OnGetMinMaxInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
3255 {
3256 if(m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1)
3257 {
3258 LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam;
3259 lpMMI->ptMinTrackSize = m_ptMinTrackSize;
3260 }
3261 return 0;
3262 }
3263 #endif // _WIN32_WCE
3264
3265 // Implementation
3266 bool DlgResize_PositionControl(int cxWidth, int cyHeight, RECT& rectGrou p, _AtlDlgResizeData& data, bool bGroup,
3267 _AtlDlgResizeData* pDataPrev = NULL)
3268 {
3269 T* pT = static_cast<T*>(this);
3270 ATLASSERT(::IsWindow(pT->m_hWnd));
3271 ATL::CWindow ctl;
3272 RECT rectCtl = { 0 };
3273
3274 ctl = pT->GetDlgItem(data.m_nCtlID);
3275 if(!ctl.GetWindowRect(&rectCtl))
3276 return false;
3277 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2);
3278
3279 if(bGroup)
3280 {
3281 if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0)
3282 {
3283 int cxRight = rectGroup.right + cxWidth - m_size Dialog.cx;
3284 int cxCtl = data.m_rect.right - data.m_rect.left ;
3285 rectCtl.left = rectGroup.left + (cxRight - rectG roup.left - cxCtl) / 2;
3286 rectCtl.right = rectCtl.left + cxCtl;
3287 }
3288 else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE _X)) != 0)
3289 {
3290 rectCtl.left = rectGroup.left + ::MulDiv(data.m_ rect.left - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_size Dialog.cx), rectGroup.right - rectGroup.left);
3291
3292 if((data.m_dwResizeFlags & DLSZ_SIZE_X) != 0)
3293 {
3294 rectCtl.right = rectGroup.left + ::MulDi v(data.m_rect.right - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidt h - m_sizeDialog.cx), rectGroup.right - rectGroup.left);
3295
3296 if(pDataPrev != NULL)
3297 {
3298 ATL::CWindow ctlPrev = pT->GetDl gItem(pDataPrev->m_nCtlID);
3299 RECT rcPrev = { 0 };
3300 ctlPrev.GetWindowRect(&rcPrev);
3301 ::MapWindowPoints(NULL, pT->m_hW nd, (LPPOINT)&rcPrev, 2);
3302 int dxAdjust = (rectCtl.left - r cPrev.right) - (data.m_rect.left - pDataPrev->m_rect.right);
3303 rcPrev.right += dxAdjust;
3304 ctlPrev.SetWindowPos(NULL, &rcPr ev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
3305 }
3306 }
3307 else
3308 {
3309 rectCtl.right = rectCtl.left + (data.m_r ect.right - data.m_rect.left);
3310 }
3311 }
3312
3313 if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0)
3314 {
3315 int cyBottom = rectGroup.bottom + cyHeight - m_s izeDialog.cy;
3316 int cyCtl = data.m_rect.bottom - data.m_rect.top ;
3317 rectCtl.top = rectGroup.top + (cyBottom - rectGr oup.top - cyCtl) / 2;
3318 rectCtl.bottom = rectCtl.top + cyCtl;
3319 }
3320 else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE _Y)) != 0)
3321 {
3322 rectCtl.top = rectGroup.top + ::MulDiv(data.m_re ct.top - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDia log.cy), rectGroup.bottom - rectGroup.top);
3323
3324 if((data.m_dwResizeFlags & DLSZ_SIZE_Y) != 0)
3325 {
3326 rectCtl.bottom = rectGroup.top + ::MulDi v(data.m_rect.bottom - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeig ht - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top);
3327
3328 if(pDataPrev != NULL)
3329 {
3330 ATL::CWindow ctlPrev = pT->GetDl gItem(pDataPrev->m_nCtlID);
3331 RECT rcPrev = { 0 };
3332 ctlPrev.GetWindowRect(&rcPrev);
3333 ::MapWindowPoints(NULL, pT->m_hW nd, (LPPOINT)&rcPrev, 2);
3334 int dxAdjust = (rectCtl.top - rc Prev.bottom) - (data.m_rect.top - pDataPrev->m_rect.bottom);
3335 rcPrev.bottom += dxAdjust;
3336 ctlPrev.SetWindowPos(NULL, &rcPr ev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
3337 }
3338 }
3339 else
3340 {
3341 rectCtl.bottom = rectCtl.top + (data.m_r ect.bottom - data.m_rect.top);
3342 }
3343 }
3344 }
3345 else // no group
3346 {
3347 if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0)
3348 {
3349 int cxCtl = data.m_rect.right - data.m_rect.left ;
3350 rectCtl.left = (cxWidth - cxCtl) / 2;
3351 rectCtl.right = rectCtl.left + cxCtl;
3352 }
3353 else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE _X)) != 0)
3354 {
3355 rectCtl.right = data.m_rect.right + (cxWidth - m _sizeDialog.cx);
3356
3357 if((data.m_dwResizeFlags & DLSZ_MOVE_X) != 0)
3358 rectCtl.left = rectCtl.right - (data.m_r ect.right - data.m_rect.left);
3359 }
3360
3361 if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0)
3362 {
3363 int cyCtl = data.m_rect.bottom - data.m_rect.top ;
3364 rectCtl.top = (cyHeight - cyCtl) / 2;
3365 rectCtl.bottom = rectCtl.top + cyCtl;
3366 }
3367 else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE _Y)) != 0)
3368 {
3369 rectCtl.bottom = data.m_rect.bottom + (cyHeight - m_sizeDialog.cy);
3370
3371 if((data.m_dwResizeFlags & DLSZ_MOVE_Y) != 0)
3372 rectCtl.top = rectCtl.bottom - (data.m_r ect.bottom - data.m_rect.top);
3373 }
3374 }
3375
3376 if((data.m_dwResizeFlags & DLSZ_REPAINT) != 0)
3377 ctl.Invalidate();
3378
3379 if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOV E_X | DLSZ_MOVE_Y | DLSZ_REPAINT | DLSZ_CENTER_X | DLSZ_CENTER_Y)) != 0)
3380 ctl.SetWindowPos(NULL, &rectCtl, SWP_NOZORDER | SWP_NOAC TIVATE);
3381
3382 return true;
3383 }
3384 };
3385
3386
3387 ///////////////////////////////////////////////////////////////////////////////
3388 // CDoubleBufferImpl - Provides double-buffer painting support to any window
3389
3390 template <class T>
3391 class CDoubleBufferImpl
3392 {
3393 public:
3394 // Overrideables
3395 void DoPaint(CDCHandle /*dc*/)
3396 {
3397 // must be implemented in a derived class
3398 ATLASSERT(FALSE);
3399 }
3400
3401 // Message map and handlers
3402 BEGIN_MSG_MAP(CDoubleBufferImpl)
3403 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground)
3404 MESSAGE_HANDLER(WM_PAINT, OnPaint)
3405 #ifndef _WIN32_WCE
3406 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint)
3407 #endif // !_WIN32_WCE
3408 END_MSG_MAP()
3409
3410 LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa ram*/, BOOL& /*bHandled*/)
3411 {
3412 return 1; // no background painting needed
3413 }
3414
3415 LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& / *bHandled*/)
3416 {
3417 T* pT = static_cast<T*>(this);
3418 ATLASSERT(::IsWindow(pT->m_hWnd));
3419
3420 if(wParam != NULL)
3421 {
3422 RECT rect = { 0 };
3423 pT->GetClientRect(&rect);
3424 CMemoryDC dcMem((HDC)wParam, rect);
3425 pT->DoPaint(dcMem.m_hDC);
3426 }
3427 else
3428 {
3429 CPaintDC dc(pT->m_hWnd);
3430 CMemoryDC dcMem(dc.m_hDC, dc.m_ps.rcPaint);
3431 pT->DoPaint(dcMem.m_hDC);
3432 }
3433
3434 return 0;
3435 }
3436 };
3437
3438
3439 ///////////////////////////////////////////////////////////////////////////////
3440 // CDoubleBufferWindowImpl - Implements a double-buffer painting window
3441
3442 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW inTraits>
3443 class ATL_NO_VTABLE CDoubleBufferWindowImpl : public ATL::CWindowImpl< T, TBase, TWinTraits >, public CDoubleBufferImpl< T >
3444 {
3445 public:
3446 BEGIN_MSG_MAP(CDoubleBufferWindowImpl)
3447 CHAIN_MSG_MAP(CDoubleBufferImpl< T >)
3448 END_MSG_MAP()
3449 };
3450
3451
3452 // command bar support
3453 #if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
3454 #undef CBRM_GETMENU
3455 #undef CBRM_TRACKPOPUPMENU
3456 #undef CBRM_GETCMDBAR
3457 #undef CBRPOPUPMENU
3458 #endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE)
3459
3460 }; // namespace WTL
3461
3462 #endif // __ATLFRAME_H__
OLDNEW
« no previous file with comments | « third_party/wtl/include/atlfind.h ('k') | third_party/wtl/include/atlgdi.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698