b21087012f5123396e545eaed47bf422a652c603
[reactos.git] / sdk / lib / atl / atlwin.h
1 /*
2 * ReactOS ATL
3 *
4 * Copyright 2009 Andrew Hill <ash77@reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #pragma once
22
23 #if defined(__GNUC__) || defined(__clang__)
24 #define GCCU(x) x __attribute__((unused))
25 #define Unused(x)
26 #else
27 #define GCCU(x) (x)
28 #define Unused(x) (x);
29 #endif // __GNUC__
30
31 #ifdef SetWindowLongPtr
32 #undef SetWindowLongPtr
33 inline LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong)
34 {
35 return SetWindowLong(hWnd, nIndex, (LONG)dwNewLong);
36 }
37 #endif
38
39 #ifdef GetWindowLongPtr
40 #undef GetWindowLongPtr
41 inline LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex)
42 {
43 return (LONG_PTR)GetWindowLong(hWnd, nIndex);
44 }
45 #endif
46
47 #pragma push_macro("SubclassWindow")
48 #undef SubclassWindow
49
50 namespace ATL
51 {
52
53 struct _ATL_WNDCLASSINFOW;
54 typedef _ATL_WNDCLASSINFOW CWndClassInfo;
55
56 template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0>
57 class CWinTraits
58 {
59 public:
60 static DWORD GetWndStyle(DWORD dwStyle)
61 {
62 if (dwStyle == 0)
63 return t_dwStyle;
64 return dwStyle;
65 }
66
67 static DWORD GetWndExStyle(DWORD dwExStyle)
68 {
69 if (dwExStyle == 0)
70 return t_dwExStyle;
71 return dwExStyle;
72 }
73 };
74
75 typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0> CControlWinTraits;
76 typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE> CFrameWinTraits;
77 typedef CWinTraits<WS_OVERLAPPEDWINDOW | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_MDICHILD> CMDIChildWinTraits;
78
79 template <DWORD t_dwStyle = 0, DWORD t_dwExStyle = 0, class TWinTraits = CControlWinTraits>
80 class CWinTraitsOR
81 {
82 public:
83 static DWORD GetWndStyle(DWORD dwStyle)
84 {
85 return dwStyle | t_dwStyle | TWinTraits::GetWndStyle(dwStyle);
86 }
87
88 static DWORD GetWndExStyle(DWORD dwExStyle)
89 {
90 return dwExStyle | t_dwExStyle | TWinTraits::GetWndExStyle(dwExStyle);
91 }
92 };
93
94 class _U_MENUorID
95 {
96 public:
97 HMENU m_hMenu;
98 public:
99 _U_MENUorID(HMENU hMenu)
100 {
101 m_hMenu = hMenu;
102 }
103
104 _U_MENUorID(UINT nID)
105 {
106 m_hMenu = (HMENU)(UINT_PTR)nID;
107 }
108 };
109
110 class _U_RECT
111 {
112 public:
113 LPRECT m_lpRect;
114 public:
115 _U_RECT(LPRECT lpRect)
116 {
117 m_lpRect = lpRect;
118 }
119
120 _U_RECT(RECT &rc)
121 {
122 m_lpRect = &rc;
123 }
124 };
125
126 struct _ATL_MSG : public MSG
127 {
128 public:
129 BOOL bHandled;
130 public:
131 _ATL_MSG(HWND hWnd, UINT uMsg, WPARAM wParamIn, LPARAM lParamIn, BOOL bHandledIn = TRUE)
132 {
133 hwnd = hWnd;
134 message = uMsg;
135 wParam = wParamIn;
136 lParam = lParamIn;
137 time = 0;
138 pt.x = 0;
139 pt.y = 0;
140 bHandled = bHandledIn;
141 }
142 };
143
144 #if defined(_M_IX86)
145
146 #pragma pack(push,1)
147 struct thunkCode
148 {
149 DWORD m_mov; /* mov dword ptr [esp+4], m_this */
150 DWORD m_this;
151 BYTE m_jmp; /* jmp relproc */
152 DWORD m_relproc;
153
154 void
155 Init(WNDPROC proc, void *pThis)
156 {
157 m_mov = 0x042444C7;
158 m_this = PtrToUlong(pThis);
159 m_jmp = 0xe9;
160 m_relproc = DWORD(reinterpret_cast<char *>(proc) - (reinterpret_cast<char *>(this) + sizeof(thunkCode)));
161 FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
162 }
163 };
164 #pragma pack(pop)
165
166 #elif defined(_AMD64_)
167
168 #pragma pack(push,1)
169 struct thunkCode
170 {
171 USHORT m_mov_rcx; /* mov rcx, m_this */
172 ULONG64 m_this;
173 USHORT m_mov_rax; /* mov rax, m_proc */
174 ULONG64 m_proc;
175 USHORT m_jmp; /* jmp rax */
176
177 void
178 Init(WNDPROC proc, void *pThis)
179 {
180 m_mov_rcx = 0xb948;
181 m_this = (ULONG64)pThis;
182 m_mov_rax = 0xb848;
183 m_proc = (ULONG64)proc;
184 m_jmp = 0xe0ff;
185 FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
186 }
187 };
188 #pragma pack(pop)
189
190 #elif defined(_M_ARM)
191
192 #pragma pack(push,4)
193 struct thunkCode
194 {
195 DWORD m_mov_r0; /* mov r0, m_this */
196 DWORD m_mov_pc; /* mov pc, m_proc */
197 DWORD m_this;
198 DWORD m_proc;
199
200 void
201 Init(WNDPROC proc, void *pThis)
202 {
203 m_mov_r0 = 0xE59F0000;
204 m_mov_pc = 0xE59FF000;
205 m_this = (DWORD)pThis;
206 m_proc = (DWORD)proc;
207 FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
208 }
209 };
210 #pragma pack(pop)
211
212 #else
213 #error ARCH not supported
214 #endif
215
216 class CWndProcThunk
217 {
218 public:
219 thunkCode *m_pthunk;
220 _AtlCreateWndData cd;
221 public:
222
223 CWndProcThunk()
224 {
225 m_pthunk = (thunkCode*)VirtualAlloc(NULL, sizeof(thunkCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
226 }
227
228 ~CWndProcThunk()
229 {
230 if (m_pthunk != NULL)
231 VirtualFree(m_pthunk, 0, MEM_RELEASE);
232 }
233
234 BOOL Init(WNDPROC proc, void *pThis)
235 {
236 if (m_pthunk == NULL)
237 return FALSE;
238 m_pthunk->Init(proc, pThis);
239 return TRUE;
240 }
241
242 WNDPROC GetWNDPROC()
243 {
244 return reinterpret_cast<WNDPROC>(m_pthunk);
245 }
246 };
247
248 class CMessageMap
249 {
250 public:
251 virtual BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID) = 0;
252 };
253
254 class CWindow
255 {
256 public:
257 HWND m_hWnd;
258 static RECT rcDefault;
259 public:
260 CWindow(HWND hWnd = NULL)
261 {
262 m_hWnd = hWnd;
263 }
264
265 operator HWND() const
266 {
267 return m_hWnd;
268 }
269
270 static LPCTSTR GetWndClassName()
271 {
272 return NULL;
273 }
274
275 UINT ArrangeIconicWindows()
276 {
277 ATLASSERT(::IsWindow(m_hWnd));
278 return ::ArrangeIconicWindows(m_hWnd);
279 }
280
281 void Attach(HWND hWndNew)
282 {
283 m_hWnd = hWndNew;
284 }
285
286 HDC BeginPaint(LPPAINTSTRUCT lpPaint)
287 {
288 ATLASSERT(::IsWindow(m_hWnd));
289 return ::BeginPaint(m_hWnd, lpPaint);
290 }
291
292 BOOL BringWindowToTop()
293 {
294 ATLASSERT(::IsWindow(m_hWnd));
295 return ::BringWindowToTop(m_hWnd);
296 }
297
298 BOOL CenterWindow(HWND hWndCenter = NULL)
299 {
300 ATLASSERT(::IsWindow(m_hWnd));
301 if (hWndCenter == NULL)
302 hWndCenter = ::GetParent(m_hWnd);
303 if (hWndCenter == NULL)
304 return FALSE;
305 RECT wndCenterRect, wndRect;
306 if (!::GetWindowRect(hWndCenter, &wndCenterRect) || !::GetWindowRect(m_hWnd, &wndRect))
307 return FALSE;
308 int wndCenterWidth = wndCenterRect.right - wndCenterRect.left;
309 int wndCenterHeight = wndCenterRect.bottom - wndCenterRect.top;
310 int wndWidth = wndRect.right - wndRect.left;
311 int wndHeight = wndRect.bottom - wndRect.top;
312 return ::MoveWindow(m_hWnd,
313 wndCenterRect.left + ((wndCenterWidth - wndWidth + 1) >> 1),
314 wndCenterRect.top + ((wndCenterHeight - wndHeight + 1) >> 1),
315 wndWidth, wndHeight, TRUE);
316 }
317
318 BOOL ChangeClipboardChain(HWND hWndNewNext)
319 {
320 ATLASSERT(::IsWindow(m_hWnd));
321 return ::ChangeClipboardChain(m_hWnd, hWndNewNext);
322 }
323
324 BOOL CheckDlgButton(int nIDButton, UINT nCheck)
325 {
326 ATLASSERT(::IsWindow(m_hWnd));
327 return ::CheckDlgButton(m_hWnd, nIDButton, nCheck);
328 }
329
330 BOOL CheckRadioButton(int nIDFirstButton, int nIDLastButton, int nIDCheckButton)
331 {
332 ATLASSERT(::IsWindow(m_hWnd));
333 return ::CheckRadioButton(m_hWnd, nIDFirstButton, nIDLastButton, nIDCheckButton);
334 }
335
336 HWND ChildWindowFromPoint(POINT point) const
337 {
338 ATLASSERT(::IsWindow(m_hWnd));
339 return ::ChildWindowFromPoint(m_hWnd, point);
340 }
341
342 HWND ChildWindowFromPointEx(POINT point, UINT uFlags) const
343 {
344 ATLASSERT(::IsWindow(m_hWnd));
345 return ::ChildWindowFromPointEx(m_hWnd, point, uFlags);
346 }
347
348 BOOL ClientToScreen(LPPOINT lpPoint) const
349 {
350 ATLASSERT(::IsWindow(m_hWnd));
351 return ::ClientToScreen(m_hWnd, lpPoint);
352 }
353
354 BOOL ClientToScreen(LPRECT lpRect) const
355 {
356 if (lpRect == NULL)
357 return FALSE;
358 ATLASSERT(::IsWindow(m_hWnd));
359 POINT leftTop = {lpRect->left, lpRect->top};
360 POINT rightBottom = {lpRect->right, lpRect->bottom};
361 BOOL success = ::ClientToScreen(m_hWnd, &leftTop) && ::ClientToScreen(m_hWnd, &rightBottom);
362 if (success)
363 {
364 lpRect->left = leftTop.x;
365 lpRect->top = leftTop.y;
366 lpRect->right = rightBottom.x;
367 lpRect->bottom = rightBottom.y;
368 }
369 return success;
370 }
371
372 HWND Create(LPCTSTR lpstrWndClass, HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
373 {
374 HWND hWnd;
375 ATLASSERT(m_hWnd == NULL);
376 hWnd = ::CreateWindowEx(dwExStyle,
377 lpstrWndClass,
378 szWindowName,
379 dwStyle,
380 rect.m_lpRect->left,
381 rect.m_lpRect->top,
382 rect.m_lpRect->right - rect.m_lpRect->left,
383 rect.m_lpRect->bottom - rect.m_lpRect->top,
384 hWndParent,
385 MenuOrID.m_hMenu,
386 _AtlBaseModule.GetModuleInstance(),
387 lpCreateParam);
388 if (hWnd != NULL)
389 m_hWnd = hWnd;
390 return hWnd;
391 }
392
393 BOOL CreateCaret(HBITMAP pBitmap)
394 {
395 ATLASSERT(::IsWindow(m_hWnd));
396 return ::CreateCaret(m_hWnd, pBitmap, 0, 0);
397 }
398
399 BOOL CreateGrayCaret(int nWidth, int nHeight)
400 {
401 ATLASSERT(::IsWindow(m_hWnd));
402 return ::CreateCaret(m_hWnd, (HBITMAP)1, nWidth, nHeight);
403 }
404
405 BOOL CreateSolidCaret(int nWidth, int nHeight)
406 {
407 ATLASSERT(::IsWindow(m_hWnd));
408 return ::CreateCaret(m_hWnd, (HBITMAP)0, nWidth, nHeight);
409 }
410
411 HDWP DeferWindowPos(HDWP hWinPosInfo, HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT uFlags)
412 {
413 ATLASSERT(::IsWindow(m_hWnd));
414 return ::DeferWindowPos(hWinPosInfo, m_hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
415 }
416
417 BOOL DestroyWindow()
418 {
419 ATLASSERT(::IsWindow(m_hWnd));
420
421 if (!::DestroyWindow(m_hWnd))
422 return FALSE;
423
424 m_hWnd = NULL;
425 return TRUE;
426 }
427
428 HWND Detach()
429 {
430 HWND hWnd = m_hWnd;
431 m_hWnd = NULL;
432 return hWnd;
433 }
434
435 int DlgDirList(LPTSTR lpPathSpec, int nIDListBox, int nIDStaticPath, UINT nFileType)
436 {
437 ATLASSERT(::IsWindow(m_hWnd));
438 return ::DlgDirList(m_hWnd, lpPathSpec, nIDListBox, nIDStaticPath, nFileType);
439 }
440
441 int DlgDirListComboBox(LPTSTR lpPathSpec, int nIDComboBox, int nIDStaticPath, UINT nFileType)
442 {
443 ATLASSERT(::IsWindow(m_hWnd));
444 return ::DlgDirListComboBox(m_hWnd, lpPathSpec, nIDComboBox, nIDStaticPath, nFileType);
445 }
446
447 BOOL DlgDirSelect(LPTSTR lpString, int nCount, int nIDListBox)
448 {
449 ATLASSERT(::IsWindow(m_hWnd));
450 return ::DlgDirSelectEx(m_hWnd, lpString, nCount, nIDListBox);
451 }
452
453 BOOL DlgDirSelectComboBox(LPTSTR lpString, int nCount, int nIDComboBox)
454 {
455 ATLASSERT(::IsWindow(m_hWnd));
456 return ::DlgDirSelectComboBoxEx(m_hWnd, lpString, nCount, nIDComboBox);
457 }
458
459 void DragAcceptFiles(BOOL bAccept = TRUE)
460 {
461 ATLASSERT(::IsWindow(m_hWnd));
462 // FIXME following line requires shellapi.h
463 // ::DragAcceptFiles(m_hWnd, bAccept);
464 }
465
466 BOOL DrawMenuBar()
467 {
468 ATLASSERT(::IsWindow(m_hWnd));
469 return ::DrawMenuBar(m_hWnd);
470 }
471
472 BOOL EnableScrollBar(UINT uSBFlags, UINT uArrowFlags = ESB_ENABLE_BOTH)
473 {
474 ATLASSERT(::IsWindow(m_hWnd));
475 return ::EnableScrollBar(m_hWnd, uSBFlags, uArrowFlags);
476 }
477
478 BOOL EnableWindow(BOOL bEnable = TRUE)
479 {
480 ATLASSERT(::IsWindow(m_hWnd));
481 return ::EnableWindow(m_hWnd, bEnable);
482 }
483
484 void EndPaint(LPPAINTSTRUCT lpPaint)
485 {
486 ATLASSERT(::IsWindow(m_hWnd));
487 ::EndPaint(m_hWnd, lpPaint);
488 }
489
490 BOOL FlashWindow(BOOL bInvert)
491 {
492 ATLASSERT(::IsWindow(m_hWnd));
493 return ::FlashWindow(m_hWnd, bInvert);
494 }
495
496 BOOL GetClientRect(LPRECT lpRect) const
497 {
498 ATLASSERT(::IsWindow(m_hWnd));
499 return ::GetClientRect(m_hWnd, lpRect);
500 }
501
502 HDC GetDC()
503 {
504 ATLASSERT(::IsWindow(m_hWnd));
505 return ::GetDC(m_hWnd);
506 }
507
508 HDC GetDCEx(HRGN hRgnClip, DWORD flags)
509 {
510 ATLASSERT(::IsWindow(m_hWnd));
511 return ::GetDCEx(m_hWnd, hRgnClip, flags);
512 }
513
514 private:
515 typedef struct _IDHWNDPAIR {
516 int nID;
517 HWND hWnd;
518 } IDHWNDPAIR, *PIDHWNDPAIR;
519
520 static BOOL CALLBACK GetDescendantWindowCallback(HWND hWnd, LPARAM lParam)
521 {
522 if (::GetWindowLong(hWnd, GWL_ID) == ((PIDHWNDPAIR)lParam)->nID)
523 {
524 ((PIDHWNDPAIR)lParam)->hWnd = hWnd;
525 return FALSE;
526 }
527 ::EnumChildWindows(hWnd, &GetDescendantWindowCallback, lParam);
528 return (((PIDHWNDPAIR)lParam)->hWnd == NULL);
529 }
530
531 public:
532 HWND GetDescendantWindow(int nID) const
533 {
534 ATLASSERT(::IsWindow(m_hWnd));
535 IDHWNDPAIR idHWndPair;
536 idHWndPair.nID = nID;
537 idHWndPair.hWnd = NULL;
538 ::EnumChildWindows(m_hWnd, &GetDescendantWindowCallback, (LPARAM)&idHWndPair);
539 return idHWndPair.hWnd;
540 }
541
542 HRESULT GetDlgControl(int nID, REFIID iid, void** ppCtrl)
543 {
544 ATLASSERT(::IsWindow(m_hWnd));
545 return E_FAIL;//FIXME stub
546 }
547
548 int GetDlgCtrlID() const
549 {
550 ATLASSERT(::IsWindow(m_hWnd));
551 return ::GetDlgCtrlID(m_hWnd);
552 }
553
554 HRESULT GetDlgHost(int nID, REFIID iid, void** ppHost)
555 {
556 ATLASSERT(::IsWindow(m_hWnd));
557 return E_FAIL;//FIXME stub
558 }
559
560 HWND GetDlgItem(int nID)
561 {
562 ATLASSERT(::IsWindow(m_hWnd));
563 return ::GetDlgItem(m_hWnd, nID);
564 }
565
566 UINT GetDlgItemInt(int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE) const
567 {
568 ATLASSERT(::IsWindow(m_hWnd));
569 return ::GetDlgItemInt(m_hWnd, nID, lpTrans, bSigned);
570 }
571
572 UINT GetDlgItemText(int nID, LPTSTR lpStr, int nMaxCount) const
573 {
574 ATLASSERT(::IsWindow(m_hWnd));
575 return ::GetDlgItemText(m_hWnd, nID, lpStr, nMaxCount);
576 }
577
578 #ifdef __ATLSTR_H__
579 UINT GetDlgItemText(int nID, CSimpleString& string)
580 {
581 HWND item = GetDlgItem(nID);
582 int len = ::GetWindowTextLength(item);
583 len = GetDlgItemText(nID, string.GetBuffer(len+1), len+1);
584 string.ReleaseBuffer(len);
585 return len;
586 }
587 #endif
588
589 BOOL GetDlgItemText(int nID, BSTR& bstrText) const
590 {
591 ATLASSERT(::IsWindow(m_hWnd));
592 return FALSE;//FIXME stub
593 }
594
595 DWORD GetExStyle() const
596 {
597 ATLASSERT(::IsWindow(m_hWnd));
598 return ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
599 }
600
601 HFONT GetFont() const
602 {
603 ATLASSERT(::IsWindow(m_hWnd));
604 return (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0, 0);
605 }
606
607 DWORD GetHotKey() const
608 {
609 ATLASSERT(::IsWindow(m_hWnd));
610 return (DWORD)::SendMessage(m_hWnd, WM_GETHOTKEY, 0, 0);
611 }
612
613 HICON GetIcon(BOOL bBigIcon = TRUE) const
614 {
615 ATLASSERT(::IsWindow(m_hWnd));
616 return (HICON)::SendMessage(m_hWnd, WM_GETICON, (WPARAM)bBigIcon, 0);
617 }
618
619 HWND GetLastActivePopup() const
620 {
621 ATLASSERT(::IsWindow(m_hWnd));
622 return ::GetLastActivePopup(m_hWnd);
623 }
624
625 HMENU GetMenu() const
626 {
627 ATLASSERT(::IsWindow(m_hWnd));
628 return ::GetMenu(m_hWnd);
629 }
630
631 HWND GetNextDlgGroupItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
632 {
633 ATLASSERT(::IsWindow(m_hWnd));
634 return ::GetNextDlgGroupItem(m_hWnd, hWndCtl, bPrevious);
635 }
636
637 HWND GetNextDlgTabItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
638 {
639 ATLASSERT(::IsWindow(m_hWnd));
640 return ::GetNextDlgTabItem(m_hWnd, hWndCtl, bPrevious);
641 }
642
643 CWindow GetParent() const
644 {
645 ATLASSERT(::IsWindow(m_hWnd));
646 return CWindow(::GetParent(m_hWnd));
647 }
648
649 BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
650 {
651 ATLASSERT(::IsWindow(m_hWnd));
652 return ::GetScrollInfo(m_hWnd, nBar, lpScrollInfo);
653 }
654
655 BOOL GetScrollPos(int nBar)
656 {
657 ATLASSERT(::IsWindow(m_hWnd));
658 return ::GetScrollPos(m_hWnd, nBar);
659 }
660
661 BOOL GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
662 {
663 ATLASSERT(::IsWindow(m_hWnd));
664 return ::GetScrollRange(m_hWnd, nBar, lpMinPos, lpMaxPos);
665 }
666
667 DWORD GetStyle() const
668 {
669 ATLASSERT(::IsWindow(m_hWnd));
670 return ::GetWindowLong(m_hWnd, GWL_STYLE);
671 }
672
673 HMENU GetSystemMenu(BOOL bRevert)
674 {
675 ATLASSERT(::IsWindow(m_hWnd));
676 return ::GetSystemMenu(m_hWnd, bRevert);
677 }
678
679 HWND GetTopLevelParent() const
680 {
681 ATLASSERT(::IsWindow(m_hWnd));
682 return NULL;//FIXME stub
683 }
684
685 HWND GetTopLevelWindow() const
686 {
687 ATLASSERT(::IsWindow(m_hWnd));
688 return NULL;//FIXME stub
689 }
690
691 HWND GetTopWindow() const
692 {
693 ATLASSERT(::IsWindow(m_hWnd));
694 return ::GetTopWindow(m_hWnd);
695 }
696
697 BOOL GetUpdateRect(LPRECT lpRect, BOOL bErase = FALSE)
698 {
699 ATLASSERT(::IsWindow(m_hWnd));
700 return ::GetUpdateRect(m_hWnd, lpRect, bErase);
701 }
702
703 int GetUpdateRgn(HRGN hRgn, BOOL bErase = FALSE)
704 {
705 ATLASSERT(::IsWindow(m_hWnd));
706 return :: GetUpdateRgn(m_hWnd, hRgn, bErase);
707 }
708
709 HWND GetWindow(UINT nCmd) const
710 {
711 ATLASSERT(::IsWindow(m_hWnd));
712 return ::GetWindow(m_hWnd, nCmd);
713 }
714
715 DWORD GetWindowContextHelpId() const
716 {
717 ATLASSERT(::IsWindow(m_hWnd));
718 return ::GetWindowContextHelpId(m_hWnd);
719 }
720
721 HDC GetWindowDC()
722 {
723 ATLASSERT(::IsWindow(m_hWnd));
724 return ::GetWindowDC(m_hWnd);
725 }
726
727 LONG GetWindowLong(int nIndex) const
728 {
729 ATLASSERT(::IsWindow(m_hWnd));
730 return ::GetWindowLong(m_hWnd, nIndex);
731 }
732
733 LONG_PTR GetWindowLongPtr(int nIndex) const
734 {
735 ATLASSERT(::IsWindow(m_hWnd));
736 return ::GetWindowLongPtr(m_hWnd, nIndex);
737 }
738
739 BOOL GetWindowPlacement(WINDOWPLACEMENT* lpwndpl) const
740 {
741 ATLASSERT(::IsWindow(m_hWnd));
742 return ::GetWindowPlacement(m_hWnd, lpwndpl);
743 }
744
745 DWORD GetWindowProcessID()
746 {
747 ATLASSERT(::IsWindow(m_hWnd));
748 DWORD processID;
749 ::GetWindowThreadProcessId(m_hWnd, &processID);
750 return processID;
751 }
752
753 BOOL GetWindowRect(LPRECT lpRect) const
754 {
755 ATLASSERT(::IsWindow(m_hWnd));
756 return ::GetWindowRect(m_hWnd, lpRect);
757 }
758
759 int GetWindowRgn(HRGN hRgn)
760 {
761 ATLASSERT(::IsWindow(m_hWnd));
762 return ::GetWindowRgn(m_hWnd, hRgn);
763 }
764
765 int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount) const
766 {
767 ATLASSERT(::IsWindow(m_hWnd));
768 return ::GetWindowText(m_hWnd, lpszStringBuf, nMaxCount);
769 }
770
771 BOOL GetWindowText(BSTR& bstrText)
772 {
773 ATLASSERT(::IsWindow(m_hWnd));
774 int length = ::GetWindowTextLength(m_hWnd);
775 if (!SysReAllocStringLen(&bstrText, NULL, length))
776 return FALSE;
777 ::GetWindowText(m_hWnd, (LPTSTR)&bstrText[2], length);
778 return TRUE;
779 }
780
781 int GetWindowTextLength() const
782 {
783 ATLASSERT(::IsWindow(m_hWnd));
784 return ::GetWindowTextLength(m_hWnd);
785 }
786
787 DWORD GetWindowThreadID()
788 {
789 ATLASSERT(::IsWindow(m_hWnd));
790 return ::GetWindowThreadProcessId(m_hWnd, NULL);
791 }
792
793 WORD GetWindowWord(int nIndex) const
794 {
795 ATLASSERT(::IsWindow(m_hWnd));
796 return (WORD)::GetWindowLong(m_hWnd, nIndex);
797 }
798
799 void GotoDlgCtrl(HWND hWndCtrl) const
800 {
801 ATLASSERT(::IsWindow(m_hWnd));
802 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0);
803 }
804
805 BOOL HideCaret()
806 {
807 ATLASSERT(::IsWindow(m_hWnd));
808 return ::HideCaret(m_hWnd);
809 }
810
811 BOOL HiliteMenuItem(HMENU hMenu, UINT uHiliteItem, UINT uHilite)
812 {
813 ATLASSERT(::IsWindow(m_hWnd));
814 return ::HiliteMenuItem(m_hWnd, hMenu, uHiliteItem, uHilite);
815 }
816
817 BOOL Invalidate(BOOL bErase = TRUE)
818 {
819 ATLASSERT(::IsWindow(m_hWnd));
820 return ::InvalidateRect(m_hWnd, NULL, bErase);
821 }
822
823 BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE)
824 {
825 ATLASSERT(::IsWindow(m_hWnd));
826 return ::InvalidateRect(m_hWnd, lpRect, bErase);
827 }
828
829 void InvalidateRgn(HRGN hRgn, BOOL bErase = TRUE)
830 {
831 ATLASSERT(::IsWindow(m_hWnd));
832 ::InvalidateRgn(m_hWnd, hRgn, bErase);
833 }
834
835 BOOL IsChild(const HWND hWnd) const
836 {
837 ATLASSERT(::IsWindow(m_hWnd));
838 return ::IsChild(m_hWnd, hWnd);
839 }
840
841 BOOL IsDialogMessage(LPMSG lpMsg)
842 {
843 ATLASSERT(::IsWindow(m_hWnd));
844 return ::IsDialogMessage(m_hWnd, lpMsg);
845 }
846
847 UINT IsDlgButtonChecked(int nIDButton) const
848 {
849 ATLASSERT(::IsWindow(m_hWnd));
850 return ::IsDlgButtonChecked(m_hWnd, nIDButton);
851 }
852
853 BOOL IsIconic() const
854 {
855 ATLASSERT(::IsWindow(m_hWnd));
856 return ::IsIconic(m_hWnd);
857 }
858
859 BOOL IsParentDialog()
860 {
861 ATLASSERT(::IsWindow(m_hWnd));
862 TCHAR pszType[10];
863 if (!RealGetWindowClass(::GetParent(m_hWnd), pszType, sizeof(pszType) / sizeof(pszType[0])))
864 return FALSE;
865 return !_tcscmp(pszType, _T("#32770"));
866 }
867
868 BOOL IsWindow() const
869 {
870 return ::IsWindow(m_hWnd);
871 }
872
873 BOOL IsWindowEnabled() const
874 {
875 ATLASSERT(::IsWindow(m_hWnd));
876 return ::IsWindowEnabled(m_hWnd);
877 }
878
879 BOOL IsWindowVisible() const
880 {
881 ATLASSERT(::IsWindow(m_hWnd));
882 return ::IsWindowVisible(m_hWnd);
883 }
884
885 BOOL IsWindowUnicode()
886 {
887 ATLASSERT(::IsWindow(m_hWnd));
888 return ::IsWindowUnicode(m_hWnd);
889 }
890
891 BOOL IsZoomed() const
892 {
893 ATLASSERT(::IsWindow(m_hWnd));
894 return ::IsZoomed(m_hWnd);
895 }
896
897 BOOL KillTimer(UINT_PTR nIDEvent)
898 {
899 ATLASSERT(::IsWindow(m_hWnd));
900 return ::KillTimer(m_hWnd, nIDEvent);
901 }
902
903 BOOL LockWindowUpdate(BOOL bLock = TRUE)
904 {
905 ATLASSERT(::IsWindow(m_hWnd));
906 if (bLock)
907 return ::LockWindowUpdate(m_hWnd);
908 return ::LockWindowUpdate(NULL);
909 }
910
911 int MapWindowPoints(HWND hWndTo, LPPOINT lpPoint, UINT nCount) const
912 {
913 ATLASSERT(::IsWindow(m_hWnd));
914 return ::MapWindowPoints(m_hWnd, hWndTo, lpPoint, nCount);
915 }
916
917 int MapWindowPoints(HWND hWndTo, LPRECT lpRect) const
918 {
919 ATLASSERT(::IsWindow(m_hWnd));
920 return ::MapWindowPoints(m_hWnd, hWndTo, (LPPOINT)lpRect, sizeof(RECT) / sizeof(POINT));
921 }
922
923 int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK)
924 {
925 ATLASSERT(::IsWindow(m_hWnd));
926 return ::MessageBox(m_hWnd, lpszText, lpszCaption, nType);
927 }
928
929 BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
930 {
931 ATLASSERT(::IsWindow(m_hWnd));
932 ::SetWindowLong(m_hWnd, GWL_STYLE, (::GetWindowLong(m_hWnd, GWL_STYLE) & ~dwRemove) | dwAdd);
933 if (nFlags != 0)
934 return ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, nFlags | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
935 return TRUE;
936 }
937
938 BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
939 {
940 ATLASSERT(::IsWindow(m_hWnd));
941 ::SetWindowLong(m_hWnd, GWL_EXSTYLE, (::GetWindowLong(m_hWnd, GWL_EXSTYLE) & ~dwRemove) | dwAdd);
942 if (nFlags != 0)
943 return ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, nFlags | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
944 return TRUE;
945 }
946
947 BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE)
948 {
949 ATLASSERT(::IsWindow(m_hWnd));
950 return ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
951 }
952
953 void NextDlgCtrl() const
954 {
955 ATLASSERT(::IsWindow(m_hWnd));
956 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0);
957 }
958
959 BOOL OpenClipboard()
960 {
961 ATLASSERT(::IsWindow(m_hWnd));
962 return ::OpenClipboard(m_hWnd);
963 }
964
965 BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
966 {
967 ATLASSERT(::IsWindow(m_hWnd));
968 return ::PostMessage(m_hWnd, message, wParam, lParam);
969 }
970
971 void PrevDlgCtrl() const
972 {
973 ATLASSERT(::IsWindow(m_hWnd));
974 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 1, 0);
975 }
976
977 void Print(HDC hDC, DWORD dwFlags) const
978 {
979 ATLASSERT(::IsWindow(m_hWnd));
980 ::SendMessage(m_hWnd, WM_PRINT, (WPARAM)hDC, (LPARAM)dwFlags);
981 }
982
983 void PrintClient(HDC hDC, DWORD dwFlags) const
984 {
985 ATLASSERT(::IsWindow(m_hWnd));
986 ::SendMessage(m_hWnd, WM_PRINTCLIENT, (WPARAM)hDC, (LPARAM)dwFlags);
987 }
988
989 BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL, HRGN hRgnUpdate = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE)
990 {
991 ATLASSERT(::IsWindow(m_hWnd));
992 return ::RedrawWindow(m_hWnd, lpRectUpdate, hRgnUpdate, flags);
993 }
994
995 int ReleaseDC(HDC hDC)
996 {
997 ATLASSERT(::IsWindow(m_hWnd));
998 return ::ReleaseDC(m_hWnd, hDC);
999 }
1000
1001 BOOL ResizeClient(int nWidth, int nHeight, BOOL bRedraw = FALSE)
1002 {
1003 ATLASSERT(::IsWindow(m_hWnd));
1004 RECT clientRect, wndRect;
1005 ::GetClientRect(m_hWnd, &clientRect);
1006 ::GetWindowRect(m_hWnd, &wndRect);
1007 return ::MoveWindow(m_hWnd, wndRect.left, wndRect.top,
1008 nWidth + (wndRect.right - wndRect.left) - (clientRect.right - clientRect.left),
1009 nHeight + (wndRect.bottom - wndRect.top) - (clientRect.bottom - clientRect.top),
1010 bRedraw);
1011 }
1012
1013 BOOL ScreenToClient(LPPOINT lpPoint) const
1014 {
1015 ATLASSERT(::IsWindow(m_hWnd));
1016 return ::ScreenToClient(m_hWnd, lpPoint);
1017 }
1018
1019 BOOL ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL)
1020 {
1021 ATLASSERT(::IsWindow(m_hWnd));
1022 return ::ScrollWindow(m_hWnd, xAmount, yAmount, lpRect, lpClipRect);
1023 }
1024
1025 int ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate, UINT flags)
1026 {
1027 ATLASSERT(::IsWindow(m_hWnd));
1028 return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, flags);
1029 }
1030
1031 LRESULT SendDlgItemMessage(int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
1032 {
1033 ATLASSERT(::IsWindow(m_hWnd));
1034 return ::SendDlgItemMessage(m_hWnd, nID, message, wParam, lParam);
1035 }
1036
1037 LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
1038 {
1039 ATLASSERT(::IsWindow(m_hWnd));
1040 return ::SendMessage(m_hWnd, message, wParam, lParam);
1041 }
1042
1043 static LRESULT SendMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1044 {
1045 ATLASSERT(::IsWindow(hWnd));
1046 return ::SendMessage(hWnd, message, wParam, lParam);
1047 }
1048
1049 private:
1050 static BOOL CALLBACK SendMessageToDescendantsCallback(HWND hWnd, LPARAM lParam)
1051 {
1052 ::SendMessage(hWnd, ((LPMSG)lParam)->message, ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam);
1053 return TRUE;
1054 }
1055
1056 static BOOL CALLBACK SendMessageToDescendantsCallbackDeep(HWND hWnd, LPARAM lParam)
1057 {
1058 ::SendMessage(hWnd, ((LPMSG)lParam)->message, ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam);
1059 ::EnumChildWindows(hWnd, &SendMessageToDescendantsCallbackDeep, lParam);
1060 return TRUE;
1061 }
1062
1063 public:
1064 void SendMessageToDescendants(UINT message, WPARAM wParam = 0, LPARAM lParam = 0, BOOL bDeep = TRUE)
1065 {
1066 ATLASSERT(::IsWindow(m_hWnd));
1067 MSG msg;
1068 msg.message = message;
1069 msg.wParam = wParam;
1070 msg.lParam = lParam;
1071 if (bDeep)
1072 ::EnumChildWindows(m_hWnd, &SendMessageToDescendantsCallback, (LPARAM)&msg);
1073 else
1074 ::EnumChildWindows(m_hWnd, &SendMessageToDescendantsCallbackDeep, (LPARAM)&msg);
1075 }
1076
1077 BOOL SendNotifyMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
1078 {
1079 ATLASSERT(::IsWindow(m_hWnd));
1080 return ::SendNotifyMessage(m_hWnd, message, wParam, lParam);
1081 }
1082
1083 HWND SetActiveWindow()
1084 {
1085 ATLASSERT(::IsWindow(m_hWnd));
1086 return ::SetActiveWindow(m_hWnd);
1087 }
1088
1089 HWND SetCapture()
1090 {
1091 ATLASSERT(::IsWindow(m_hWnd));
1092 return ::SetCapture(m_hWnd);
1093 }
1094
1095 HWND SetClipboardViewer()
1096 {
1097 ATLASSERT(::IsWindow(m_hWnd));
1098 return ::SetClipboardViewer(m_hWnd);
1099 }
1100
1101 int SetDlgCtrlID(int nID)
1102 {
1103 ATLASSERT(::IsWindow(m_hWnd));
1104 return ::SetWindowLong(m_hWnd, GWL_ID, nID);
1105 }
1106
1107 BOOL SetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE)
1108 {
1109 ATLASSERT(::IsWindow(m_hWnd));
1110 return ::SetDlgItemInt(m_hWnd, nID, nValue, bSigned);
1111 }
1112
1113 BOOL SetDlgItemText(int nID, LPCTSTR lpszString)
1114 {
1115 ATLASSERT(::IsWindow(m_hWnd));
1116 return ::SetDlgItemText(m_hWnd, nID, lpszString);
1117 }
1118
1119 HWND SetFocus()
1120 {
1121 ATLASSERT(::IsWindow(m_hWnd));
1122 return ::SetFocus(m_hWnd);
1123 }
1124
1125 void SetFont(HFONT hFont, BOOL bRedraw = TRUE)
1126 {
1127 ATLASSERT(::IsWindow(m_hWnd));
1128 ::SendMessage(m_hWnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)bRedraw);
1129 }
1130
1131 int SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
1132 {
1133 ATLASSERT(::IsWindow(m_hWnd));
1134 return ::SendMessage(m_hWnd, WM_SETHOTKEY, MAKEWPARAM(wVirtualKeyCode, wModifiers), 0);
1135 }
1136
1137 HICON SetIcon(HICON hIcon, BOOL bBigIcon = TRUE)
1138 {
1139 ATLASSERT(::IsWindow(m_hWnd));
1140 return (HICON)::SendMessage(m_hWnd, WM_SETICON, (WPARAM)bBigIcon, (LPARAM)hIcon);
1141 }
1142
1143 BOOL SetMenu(HMENU hMenu)
1144 {
1145 ATLASSERT(::IsWindow(m_hWnd));
1146 return ::SetMenu(m_hWnd, hMenu);
1147 }
1148
1149 HWND SetParent(HWND hWndNewParent)
1150 {
1151 ATLASSERT(::IsWindow(m_hWnd));
1152 return ::SetParent(m_hWnd, hWndNewParent);
1153 }
1154
1155 void SetRedraw(BOOL bRedraw = TRUE)
1156 {
1157 ATLASSERT(::IsWindow(m_hWnd));
1158 ::SendMessage(m_hWnd, WM_SETREDRAW, (WPARAM)bRedraw, 0);
1159 }
1160
1161 int SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
1162 {
1163 ATLASSERT(::IsWindow(m_hWnd));
1164 return ::SetScrollInfo(m_hWnd, nBar, lpScrollInfo, bRedraw);
1165 }
1166
1167 int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
1168 {
1169 ATLASSERT(::IsWindow(m_hWnd));
1170 return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
1171 }
1172
1173 BOOL SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
1174 {
1175 ATLASSERT(::IsWindow(m_hWnd));
1176 return ::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
1177 }
1178
1179 UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void (CALLBACK *lpfnTimer)(HWND, UINT, UINT_PTR, DWORD) = NULL)
1180 {
1181 ATLASSERT(::IsWindow(m_hWnd));
1182 return ::SetTimer(m_hWnd, nIDEvent, nElapse, reinterpret_cast<TIMERPROC>(lpfnTimer));
1183 }
1184
1185 BOOL SetWindowContextHelpId(DWORD dwContextHelpId)
1186 {
1187 ATLASSERT(::IsWindow(m_hWnd));
1188 return ::SetWindowContextHelpId(m_hWnd, dwContextHelpId);
1189 }
1190
1191 LONG SetWindowLong(int nIndex, LONG dwNewLong)
1192 {
1193 ATLASSERT(::IsWindow(m_hWnd));
1194 return ::SetWindowLong(m_hWnd, nIndex, dwNewLong);
1195 }
1196
1197 LONG_PTR SetWindowLongPtr(int nIndex, LONG_PTR dwNewLong)
1198 {
1199 ATLASSERT(::IsWindow(m_hWnd));
1200 return ::SetWindowLongPtr(m_hWnd, nIndex, dwNewLong);
1201 }
1202
1203 BOOL SetWindowPlacement(const WINDOWPLACEMENT* lpwndpl)
1204 {
1205 ATLASSERT(::IsWindow(m_hWnd));
1206 return ::SetWindowPlacement(m_hWnd, lpwndpl);
1207 }
1208
1209 BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
1210 {
1211 ATLASSERT(::IsWindow(m_hWnd));
1212 return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags);
1213 }
1214
1215 int SetWindowRgn(HRGN hRgn, BOOL bRedraw = FALSE)
1216 {
1217 ATLASSERT(::IsWindow(m_hWnd));
1218 return ::SetWindowRgn(m_hWnd, hRgn, bRedraw);
1219 }
1220
1221 BOOL SetWindowText(LPCTSTR lpszString)
1222 {
1223 ATLASSERT(::IsWindow(m_hWnd));
1224 return ::SetWindowText(m_hWnd, lpszString);
1225 }
1226
1227 WORD SetWindowWord(int nIndex, WORD wNewWord)
1228 {
1229 ATLASSERT(::IsWindow(m_hWnd));
1230 if (nIndex >= -4)
1231 return ::SetWindowLong(m_hWnd, nIndex - 2, MAKELONG(LOWORD(::GetWindowLong(m_hWnd, nIndex - 2)), wNewWord));
1232 else
1233 return ::SetWindowLong(m_hWnd, nIndex, MAKELONG(wNewWord, HIWORD(::GetWindowLong(m_hWnd, nIndex))));
1234 }
1235
1236 BOOL ShowCaret()
1237 {
1238 ATLASSERT(::IsWindow(m_hWnd));
1239 return ::ShowCaret(m_hWnd);
1240 }
1241
1242 BOOL ShowOwnedPopups(BOOL bShow = TRUE)
1243 {
1244 ATLASSERT(::IsWindow(m_hWnd));
1245 return ::ShowOwnedPopups(m_hWnd, bShow);
1246 }
1247
1248 BOOL ShowScrollBar(UINT nBar, BOOL bShow = TRUE)
1249 {
1250 ATLASSERT(::IsWindow(m_hWnd));
1251 return ::ShowScrollBar(m_hWnd, nBar, bShow);
1252 }
1253
1254 BOOL ShowWindow(int nCmdShow)
1255 {
1256 ATLASSERT(::IsWindow(m_hWnd));
1257 return ::ShowWindow(m_hWnd, nCmdShow);
1258 }
1259
1260 BOOL ShowWindowAsync(int nCmdShow)
1261 {
1262 ATLASSERT(::IsWindow(m_hWnd));
1263 return ::ShowWindowAsync(m_hWnd, nCmdShow);
1264 }
1265
1266 BOOL UpdateWindow()
1267 {
1268 ATLASSERT(::IsWindow(m_hWnd));
1269 return ::UpdateWindow(m_hWnd);
1270 }
1271
1272 BOOL ValidateRect(LPCRECT lpRect)
1273 {
1274 ATLASSERT(::IsWindow(m_hWnd));
1275 return ::ValidateRect(m_hWnd, lpRect);
1276 }
1277
1278 BOOL ValidateRgn(HRGN hRgn)
1279 {
1280 ATLASSERT(::IsWindow(m_hWnd));
1281 return ::ValidateRgn(m_hWnd, hRgn);
1282 }
1283
1284 BOOL WinHelp(LPCTSTR lpszHelp, UINT nCmd = HELP_CONTEXT, DWORD dwData = 0)
1285 {
1286 ATLASSERT(::IsWindow(m_hWnd));
1287 return ::WinHelp(m_hWnd, lpszHelp, nCmd, dwData);
1288 }
1289 };
1290
1291 __declspec(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 };
1292
1293 template <class TBase = CWindow>
1294 class CWindowImplRoot : public TBase, public CMessageMap
1295 {
1296 public:
1297 enum { WINSTATE_DESTROYED = 0x00000001 };
1298
1299 public:
1300 CWndProcThunk m_thunk;
1301 const _ATL_MSG *m_pCurrentMsg;
1302 DWORD m_dwState;
1303
1304 CWindowImplRoot()
1305 : m_pCurrentMsg(NULL)
1306 , m_dwState(0)
1307 {
1308 }
1309
1310 virtual ~CWindowImplRoot()
1311 {
1312 }
1313 };
1314
1315
1316 template <class TBase = CWindow>
1317 class CDialogImplBaseT : public CWindowImplRoot<TBase>
1318 {
1319 public:
1320 // + Hacks for gcc
1321 using CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
1322 // - Hacks for gcc
1323
1324 virtual ~CDialogImplBaseT()
1325 {
1326 }
1327 virtual DLGPROC GetDialogProc()
1328 {
1329 return DialogProc;
1330 }
1331
1332 static INT_PTR CALLBACK StartDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1333 {
1334 CDialogImplBaseT<TBase> *pThis;
1335 DLGPROC newDlgProc;
1336 DLGPROC GCCU(pOldProc);
1337
1338 pThis = reinterpret_cast<CDialogImplBaseT<TBase>*>(_AtlWinModule.ExtractCreateWndData());
1339 ATLASSERT(pThis != NULL);
1340 if (pThis == NULL)
1341 return 0;
1342 pThis->m_thunk.Init((WNDPROC)pThis->GetDialogProc(), pThis);
1343 newDlgProc = reinterpret_cast<DLGPROC>(pThis->m_thunk.GetWNDPROC());
1344 pOldProc = reinterpret_cast<DLGPROC>(::SetWindowLongPtr(hWnd, DWLP_DLGPROC, reinterpret_cast<LONG_PTR>(newDlgProc)));
1345 Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
1346 pThis->m_hWnd = hWnd;
1347 return newDlgProc(hWnd, uMsg, wParam, lParam);
1348 }
1349
1350 static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1351 {
1352 CDialogImplBaseT<TBase> *pThis = reinterpret_cast<CDialogImplBaseT<TBase>*>(hWnd);
1353 _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1354 LRESULT lResult = 0;
1355 const _ATL_MSG *previousMessage;
1356 BOOL handled;
1357
1358 hWnd = pThis->m_hWnd;
1359 previousMessage = pThis->m_pCurrentMsg;
1360 pThis->m_pCurrentMsg = &msg;
1361
1362 handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
1363 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1364
1365 if (handled)
1366 {
1367 if ((pThis->m_dwState & WINSTATE_DESTROYED) == 0)
1368 {
1369 ::SetWindowLongPtr(pThis->m_hWnd, DWLP_MSGRESULT, lResult);
1370 }
1371 }
1372 else
1373 {
1374 if (uMsg == WM_NCDESTROY)
1375 {
1376 pThis->m_dwState |= WINSTATE_DESTROYED;
1377 }
1378 }
1379
1380 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1381 pThis->m_pCurrentMsg = previousMessage;
1382
1383 if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
1384 {
1385 pThis->m_dwState &= ~WINSTATE_DESTROYED;
1386 pThis->m_hWnd = NULL;
1387 pThis->OnFinalMessage(hWnd);
1388 }
1389 return lResult;
1390 }
1391
1392 virtual void OnFinalMessage(HWND)
1393 {
1394 }
1395 };
1396
1397
1398 template <class T, class TBase = CWindow>
1399 class CDialogImpl : public CDialogImplBaseT< TBase >
1400 {
1401 public:
1402 // + Hacks for gcc
1403 using CWindowImplRoot<TBase>::m_thunk;
1404 using CWindowImplRoot<TBase>::m_hWnd;
1405 // - Hacks for gcc
1406
1407 HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
1408 {
1409 BOOL result;
1410 HWND hWnd;
1411 T* pImpl;
1412
1413 result = m_thunk.Init(NULL, NULL);
1414 if (result == FALSE)
1415 return NULL;
1416
1417 _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
1418
1419 pImpl = static_cast<T*>(this);
1420 hWnd = ::CreateDialogParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(pImpl->IDD), hWndParent, T::StartDialogProc, dwInitParam);
1421 return hWnd;
1422 }
1423
1424 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
1425 {
1426 BOOL result;
1427 T* pImpl;
1428
1429 result = m_thunk.Init(NULL, NULL);
1430 if (result == FALSE)
1431 return -1;
1432
1433 _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
1434
1435 pImpl = static_cast<T*>(this);
1436 return ::DialogBoxParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(pImpl->IDD), hWndParent, T::StartDialogProc, dwInitParam);
1437 }
1438
1439 BOOL EndDialog(_In_ int nRetCode)
1440 {
1441 return ::EndDialog(m_hWnd, nRetCode);
1442 }
1443
1444 BOOL DestroyWindow()
1445 {
1446 return ::DestroyWindow(m_hWnd);
1447 }
1448 };
1449
1450 template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
1451 class CWindowImplBaseT : public CWindowImplRoot<TBase>
1452 {
1453 public:
1454 // + Hacks for gcc
1455 using CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
1456 using CWindowImplRoot<TBase>::m_thunk;
1457 // - Hacks for gcc
1458
1459 WNDPROC m_pfnSuperWindowProc;
1460
1461 public:
1462 CWindowImplBaseT()
1463 {
1464 m_pfnSuperWindowProc = ::DefWindowProc;
1465 }
1466
1467 virtual void OnFinalMessage(HWND /* hWnd */)
1468 {
1469 }
1470
1471 BOOL SubclassWindow(HWND hWnd)
1472 {
1473 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1474 WNDPROC newWindowProc;
1475 WNDPROC oldWindowProc;
1476 BOOL result;
1477
1478 ATLASSERT(m_hWnd == NULL);
1479 ATLASSERT(::IsWindow(hWnd));
1480
1481 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this);
1482
1483 result = m_thunk.Init(GetWindowProc(), this);
1484 if (result == FALSE)
1485 return FALSE;
1486 newWindowProc = m_thunk.GetWNDPROC();
1487 oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1488 if (oldWindowProc == NULL)
1489 return FALSE;
1490 m_pfnSuperWindowProc = oldWindowProc;
1491 pThis->m_hWnd = hWnd;
1492 return TRUE;
1493 }
1494
1495 virtual WNDPROC GetWindowProc()
1496 {
1497 return WindowProc;
1498 }
1499
1500 static DWORD GetWndStyle(DWORD dwStyle)
1501 {
1502 return TWinTraits::GetWndStyle(dwStyle);
1503 }
1504
1505 static DWORD GetWndExStyle(DWORD dwExStyle)
1506 {
1507 return TWinTraits::GetWndExStyle(dwExStyle);
1508 }
1509
1510 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
1511 {
1512 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1513
1514 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(this);
1515 return ::CallWindowProc(m_pfnSuperWindowProc, pThis->m_hWnd, uMsg, wParam, lParam);
1516 }
1517
1518 static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1519 {
1520 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1521 WNDPROC newWindowProc;
1522 WNDPROC GCCU(pOldProc);
1523
1524 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(_AtlWinModule.ExtractCreateWndData());
1525 ATLASSERT(pThis != NULL);
1526 if (pThis == NULL)
1527 return 0;
1528 pThis->m_thunk.Init(pThis->GetWindowProc(), pThis);
1529 newWindowProc = pThis->m_thunk.GetWNDPROC();
1530 pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1531 Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
1532 pThis->m_hWnd = hWnd;
1533 return newWindowProc(hWnd, uMsg, wParam, lParam);
1534 }
1535
1536 static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1537 {
1538 CWindowImplBaseT<TBase, TWinTraits> *pThis = reinterpret_cast<CWindowImplBaseT< TBase, TWinTraits> *>(hWnd);
1539 _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1540 LRESULT lResult;
1541 const _ATL_MSG *previousMessage;
1542 BOOL handled;
1543 LONG_PTR saveWindowProc;
1544
1545 ATLASSERT(pThis != NULL && (pThis->m_dwState & WINSTATE_DESTROYED) == 0 && pThis->m_hWnd != NULL);
1546 if (pThis == NULL || (pThis->m_dwState & WINSTATE_DESTROYED) != 0 || pThis->m_hWnd == NULL)
1547 return 0;
1548
1549 hWnd = pThis->m_hWnd;
1550 previousMessage = pThis->m_pCurrentMsg;
1551 pThis->m_pCurrentMsg = &msg;
1552
1553 handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
1554 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1555
1556 if (handled == FALSE)
1557 {
1558 if (uMsg == WM_NCDESTROY)
1559 {
1560 saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
1561 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1562 if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC))
1563 ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc));
1564 pThis->m_dwState |= WINSTATE_DESTROYED;
1565 }
1566 else
1567 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1568 }
1569 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1570 pThis->m_pCurrentMsg = previousMessage;
1571 if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
1572 {
1573 pThis->m_dwState &= ~WINSTATE_DESTROYED;
1574 pThis->m_hWnd = NULL;
1575 pThis->OnFinalMessage(hWnd);
1576 }
1577 return lResult;
1578 }
1579
1580 HWND Create(HWND hWndParent, _U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle,
1581 _U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam)
1582 {
1583 HWND hWnd;
1584
1585 ATLASSERT(m_hWnd == NULL);
1586 ATLASSERT(atom != 0);
1587 if (atom == 0)
1588 return NULL;
1589 if (m_thunk.Init(NULL, NULL) == FALSE)
1590 {
1591 SetLastError(ERROR_OUTOFMEMORY);
1592 return NULL;
1593 }
1594
1595 _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
1596 if (MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD) != 0)
1597 MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this;
1598 if (rect.m_lpRect == NULL)
1599 rect.m_lpRect = &TBase::rcDefault;
1600 hWnd = ::CreateWindowEx(dwExStyle, reinterpret_cast<LPCWSTR>(MAKEINTATOM(atom)), szWindowName, dwStyle, rect.m_lpRect->left,
1601 rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left, rect.m_lpRect->bottom - rect.m_lpRect->top,
1602 hWndParent, MenuOrID.m_hMenu, _AtlBaseModule.GetModuleInstance(), lpCreateParam);
1603
1604 ATLASSERT(m_hWnd == hWnd);
1605
1606 return hWnd;
1607 }
1608 };
1609
1610
1611 template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
1612 class CWindowImpl : public CWindowImplBaseT<TBase, TWinTraits>
1613 {
1614 public:
1615 static LPCTSTR GetWndCaption()
1616 {
1617 return NULL;
1618 }
1619
1620 HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0,
1621 DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
1622 {
1623 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1624 ATOM atom;
1625
1626 ATLASSERT(m_hWnd == NULL);
1627 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this);
1628
1629 if (T::GetWndClassInfo().m_lpszOrigName == NULL)
1630 T::GetWndClassInfo().m_lpszOrigName = pThis->GetWndClassName();
1631 atom = T::GetWndClassInfo().Register(&pThis->m_pfnSuperWindowProc);
1632
1633 if (szWindowName == NULL)
1634 szWindowName = T::GetWndCaption();
1635 dwStyle = T::GetWndStyle(dwStyle);
1636 dwExStyle = T::GetWndExStyle(dwExStyle);
1637
1638 return CWindowImplBaseT<TBase, TWinTraits>::Create(hWndParent, rect, szWindowName, dwStyle,
1639 dwExStyle, MenuOrID, atom, lpCreateParam);
1640 }
1641 };
1642
1643 template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
1644 class CContainedWindowT : public TBase
1645 {
1646 public:
1647 CWndProcThunk m_thunk;
1648 LPCTSTR m_lpszClassName;
1649 WNDPROC m_pfnSuperWindowProc;
1650 CMessageMap *m_pObject;
1651 DWORD m_dwMsgMapID;
1652 const _ATL_MSG *m_pCurrentMsg;
1653 public:
1654 CContainedWindowT(CMessageMap *pObject, DWORD dwMsgMapID = 0)
1655 {
1656 m_lpszClassName = TBase::GetWndClassName();
1657 m_pfnSuperWindowProc = ::DefWindowProc;
1658 m_pObject = pObject;
1659 m_dwMsgMapID = dwMsgMapID;
1660 m_pCurrentMsg = NULL;
1661 }
1662
1663 CContainedWindowT(LPTSTR lpszClassName, CMessageMap *pObject, DWORD dwMsgMapID = 0)
1664 {
1665 m_lpszClassName = lpszClassName;
1666 m_pfnSuperWindowProc = ::DefWindowProc;
1667 m_pObject = pObject;
1668 m_dwMsgMapID = dwMsgMapID;
1669 m_pCurrentMsg = NULL;
1670 }
1671
1672 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
1673 {
1674 return ::CallWindowProc(m_pfnSuperWindowProc, this->m_hWnd, uMsg, wParam, lParam);
1675 }
1676
1677 BOOL SubclassWindow(HWND hWnd)
1678 {
1679 CContainedWindowT<TBase> *pThis;
1680 WNDPROC newWindowProc;
1681 WNDPROC oldWindowProc;
1682 BOOL result;
1683
1684 ATLASSERT(m_hWnd == NULL);
1685 ATLASSERT(::IsWindow(hWnd));
1686
1687 pThis = reinterpret_cast<CContainedWindowT<TBase> *>(this);
1688
1689 result = m_thunk.Init(WindowProc, pThis);
1690 if (result == FALSE)
1691 return FALSE;
1692 newWindowProc = m_thunk.GetWNDPROC();
1693 oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1694 if (oldWindowProc == NULL)
1695 return FALSE;
1696 m_pfnSuperWindowProc = oldWindowProc;
1697 pThis->m_hWnd = hWnd;
1698 return TRUE;
1699 }
1700
1701 static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1702 {
1703 CContainedWindowT<TBase> *pThis;
1704 WNDPROC newWindowProc;
1705 WNDPROC GCCU(pOldProc);
1706
1707 pThis = reinterpret_cast<CContainedWindowT<TBase> *>(_AtlWinModule.ExtractCreateWndData());
1708 ATLASSERT(pThis != NULL);
1709 if (pThis == NULL)
1710 return 0;
1711 pThis->m_thunk.Init(WindowProc, pThis);
1712 newWindowProc = pThis->m_thunk.GetWNDPROC();
1713 pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1714 Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
1715 pThis->m_hWnd = hWnd;
1716 return newWindowProc(hWnd, uMsg, wParam, lParam);
1717 }
1718
1719 static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1720 {
1721 CContainedWindowT<TBase> *pThis = reinterpret_cast<CContainedWindowT<TBase> *>(hWnd);
1722 _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1723 LRESULT lResult;
1724 const _ATL_MSG *previousMessage;
1725 BOOL handled;
1726 LONG_PTR saveWindowProc;
1727
1728 ATLASSERT(pThis != NULL && pThis->m_hWnd != NULL && pThis->m_pObject != NULL);
1729 if (pThis == NULL || pThis->m_hWnd == NULL || pThis->m_pObject == NULL)
1730 return 0;
1731
1732 hWnd = pThis->m_hWnd;
1733 previousMessage = pThis->m_pCurrentMsg;
1734 pThis->m_pCurrentMsg = &msg;
1735
1736 handled = pThis->m_pObject->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, pThis->m_dwMsgMapID);
1737 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1738
1739 pThis->m_pCurrentMsg = previousMessage;
1740 if (handled == FALSE)
1741 {
1742 if (uMsg == WM_NCDESTROY)
1743 {
1744 saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
1745 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1746 if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC))
1747 ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc));
1748 pThis->m_hWnd = NULL;
1749 }
1750 else
1751 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1752 }
1753 return lResult;
1754 }
1755
1756 };
1757 typedef CContainedWindowT<CWindow> CContainedWindow;
1758
1759 #define BEGIN_MSG_MAP(theClass) \
1760 public: \
1761 BOOL ProcessWindowMessage(HWND GCCU(hWnd), UINT GCCU(uMsg), WPARAM GCCU(wParam), LPARAM GCCU(lParam), LRESULT &GCCU(lResult), DWORD dwMsgMapID = 0) \
1762 { \
1763 BOOL GCCU(bHandled) = TRUE; \
1764 Unused(hWnd); \
1765 Unused(uMsg); \
1766 Unused(wParam); \
1767 Unused(lParam); \
1768 Unused(lResult); \
1769 Unused(bHandled); \
1770 switch(dwMsgMapID) \
1771 { \
1772 case 0:
1773
1774 #define ALT_MSG_MAP(map) \
1775 break; \
1776 case map:
1777
1778 #define END_MSG_MAP() \
1779 break; \
1780 default: \
1781 ATLASSERT(FALSE); \
1782 break; \
1783 } \
1784 return FALSE; \
1785 }
1786
1787 #define MESSAGE_HANDLER(msg, func) \
1788 if (uMsg == msg) \
1789 { \
1790 bHandled = TRUE; \
1791 lResult = func(uMsg, wParam, lParam, bHandled); \
1792 if (bHandled) \
1793 return TRUE; \
1794 }
1795
1796 #define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \
1797 if (uMsg >= msgFirst && uMsg <= msgLast) \
1798 { \
1799 bHandled = TRUE; \
1800 lResult = func(uMsg, wParam, lParam, bHandled); \
1801 if (bHandled) \
1802 return TRUE; \
1803 }
1804
1805 #define COMMAND_ID_HANDLER(id, func) \
1806 if (uMsg == WM_COMMAND && id == LOWORD(wParam)) \
1807 { \
1808 bHandled = TRUE; \
1809 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
1810 if (bHandled) \
1811 return TRUE; \
1812 }
1813
1814 #define COMMAND_CODE_HANDLER(code, func) \
1815 if (uMsg == WM_COMMAND && code == HIWORD(wParam)) \
1816 { \
1817 bHandled = TRUE; \
1818 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
1819 if (bHandled) \
1820 return TRUE; \
1821 }
1822
1823 #define COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
1824 if (uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
1825 { \
1826 bHandled = TRUE; \
1827 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
1828 if (bHandled) \
1829 return TRUE; \
1830 }
1831
1832 #define NOTIFY_CODE_HANDLER(cd, func) \
1833 if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
1834 { \
1835 bHandled = TRUE; \
1836 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
1837 if (bHandled) \
1838 return TRUE; \
1839 }
1840
1841 #define NOTIFY_HANDLER(id, cd, func) \
1842 if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
1843 { \
1844 bHandled = TRUE; \
1845 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
1846 if (bHandled) \
1847 return TRUE; \
1848 }
1849
1850 #define CHAIN_MSG_MAP(theChainClass) \
1851 { \
1852 if (theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
1853 return TRUE; \
1854 }
1855
1856 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
1857 static ATL::CWndClassInfo& GetWndClassInfo() \
1858 { \
1859 static ATL::CWndClassInfo wc = \
1860 { \
1861 { sizeof(WNDCLASSEX), style, StartWindowProc, \
1862 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
1863 NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
1864 }; \
1865 return wc; \
1866 }
1867
1868 struct _ATL_WNDCLASSINFOW
1869 {
1870 WNDCLASSEXW m_wc;
1871 LPCWSTR m_lpszOrigName;
1872 WNDPROC pWndProc;
1873 LPCWSTR m_lpszCursorID;
1874 BOOL m_bSystemCursor;
1875 ATOM m_atom;
1876 WCHAR m_szAutoName[5 + sizeof(void *)];
1877
1878 ATOM Register(WNDPROC *p)
1879 {
1880 if (m_wc.hInstance == NULL)
1881 m_wc.hInstance = _AtlBaseModule.GetModuleInstance();
1882 if (m_atom == 0)
1883 {
1884 if (m_bSystemCursor)
1885 m_wc.hCursor = ::LoadCursor(NULL, m_lpszCursorID);
1886 else
1887 m_wc.hCursor = ::LoadCursor(_AtlBaseModule.GetResourceInstance(), m_lpszCursorID);
1888
1889 m_atom = RegisterClassEx(&m_wc);
1890 }
1891
1892 return m_atom;
1893 }
1894 };
1895
1896 }; // namespace ATL
1897
1898 #pragma pop_macro("SubclassWindow")
1899