3f68348a4ee834f66a78984343631470bd61d816
[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 #ifdef __GNUC__
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 BOOL GetDlgItemText(int nID, BSTR& bstrText) const
579 {
580 ATLASSERT(::IsWindow(m_hWnd));
581 return FALSE;//FIXME stub
582 }
583
584 DWORD GetExStyle() const
585 {
586 ATLASSERT(::IsWindow(m_hWnd));
587 return ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
588 }
589
590 HFONT GetFont() const
591 {
592 ATLASSERT(::IsWindow(m_hWnd));
593 return (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0, 0);
594 }
595
596 DWORD GetHotKey() const
597 {
598 ATLASSERT(::IsWindow(m_hWnd));
599 return (DWORD)::SendMessage(m_hWnd, WM_GETHOTKEY, 0, 0);
600 }
601
602 HICON GetIcon(BOOL bBigIcon = TRUE) const
603 {
604 ATLASSERT(::IsWindow(m_hWnd));
605 return (HICON)::SendMessage(m_hWnd, WM_GETICON, (WPARAM)bBigIcon, 0);
606 }
607
608 HWND GetLastActivePopup() const
609 {
610 ATLASSERT(::IsWindow(m_hWnd));
611 return ::GetLastActivePopup(m_hWnd);
612 }
613
614 HMENU GetMenu() const
615 {
616 ATLASSERT(::IsWindow(m_hWnd));
617 return ::GetMenu(m_hWnd);
618 }
619
620 HWND GetNextDlgGroupItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
621 {
622 ATLASSERT(::IsWindow(m_hWnd));
623 return ::GetNextDlgGroupItem(m_hWnd, hWndCtl, bPrevious);
624 }
625
626 HWND GetNextDlgTabItem(HWND hWndCtl, BOOL bPrevious = FALSE) const
627 {
628 ATLASSERT(::IsWindow(m_hWnd));
629 return ::GetNextDlgTabItem(m_hWnd, hWndCtl, bPrevious);
630 }
631
632 CWindow GetParent() const
633 {
634 ATLASSERT(::IsWindow(m_hWnd));
635 return CWindow(::GetParent(m_hWnd));
636 }
637
638 BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo)
639 {
640 ATLASSERT(::IsWindow(m_hWnd));
641 return ::GetScrollInfo(m_hWnd, nBar, lpScrollInfo);
642 }
643
644 BOOL GetScrollPos(int nBar)
645 {
646 ATLASSERT(::IsWindow(m_hWnd));
647 return ::GetScrollPos(m_hWnd, nBar);
648 }
649
650 BOOL GetScrollRange(int nBar, LPINT lpMinPos, LPINT lpMaxPos) const
651 {
652 ATLASSERT(::IsWindow(m_hWnd));
653 return ::GetScrollRange(m_hWnd, nBar, lpMinPos, lpMaxPos);
654 }
655
656 DWORD GetStyle() const
657 {
658 ATLASSERT(::IsWindow(m_hWnd));
659 return ::GetWindowLong(m_hWnd, GWL_STYLE);
660 }
661
662 HMENU GetSystemMenu(BOOL bRevert)
663 {
664 ATLASSERT(::IsWindow(m_hWnd));
665 return ::GetSystemMenu(m_hWnd, bRevert);
666 }
667
668 HWND GetTopLevelParent() const
669 {
670 ATLASSERT(::IsWindow(m_hWnd));
671 return NULL;//FIXME stub
672 }
673
674 HWND GetTopLevelWindow() const
675 {
676 ATLASSERT(::IsWindow(m_hWnd));
677 return NULL;//FIXME stub
678 }
679
680 HWND GetTopWindow() const
681 {
682 ATLASSERT(::IsWindow(m_hWnd));
683 return ::GetTopWindow(m_hWnd);
684 }
685
686 BOOL GetUpdateRect(LPRECT lpRect, BOOL bErase = FALSE)
687 {
688 ATLASSERT(::IsWindow(m_hWnd));
689 return ::GetUpdateRect(m_hWnd, lpRect, bErase);
690 }
691
692 int GetUpdateRgn(HRGN hRgn, BOOL bErase = FALSE)
693 {
694 ATLASSERT(::IsWindow(m_hWnd));
695 return :: GetUpdateRgn(m_hWnd, hRgn, bErase);
696 }
697
698 HWND GetWindow(UINT nCmd) const
699 {
700 ATLASSERT(::IsWindow(m_hWnd));
701 return ::GetWindow(m_hWnd, nCmd);
702 }
703
704 DWORD GetWindowContextHelpId() const
705 {
706 ATLASSERT(::IsWindow(m_hWnd));
707 return ::GetWindowContextHelpId(m_hWnd);
708 }
709
710 HDC GetWindowDC()
711 {
712 ATLASSERT(::IsWindow(m_hWnd));
713 return ::GetWindowDC(m_hWnd);
714 }
715
716 LONG GetWindowLong(int nIndex) const
717 {
718 ATLASSERT(::IsWindow(m_hWnd));
719 return ::GetWindowLong(m_hWnd, nIndex);
720 }
721
722 LONG_PTR GetWindowLongPtr(int nIndex) const
723 {
724 ATLASSERT(::IsWindow(m_hWnd));
725 return ::GetWindowLongPtr(m_hWnd, nIndex);
726 }
727
728 BOOL GetWindowPlacement(WINDOWPLACEMENT* lpwndpl) const
729 {
730 ATLASSERT(::IsWindow(m_hWnd));
731 return ::GetWindowPlacement(m_hWnd, lpwndpl);
732 }
733
734 DWORD GetWindowProcessID()
735 {
736 ATLASSERT(::IsWindow(m_hWnd));
737 DWORD processID;
738 ::GetWindowThreadProcessId(m_hWnd, &processID);
739 return processID;
740 }
741
742 BOOL GetWindowRect(LPRECT lpRect) const
743 {
744 ATLASSERT(::IsWindow(m_hWnd));
745 return ::GetWindowRect(m_hWnd, lpRect);
746 }
747
748 int GetWindowRgn(HRGN hRgn)
749 {
750 ATLASSERT(::IsWindow(m_hWnd));
751 return ::GetWindowRgn(m_hWnd, hRgn);
752 }
753
754 int GetWindowText(LPTSTR lpszStringBuf, int nMaxCount) const
755 {
756 ATLASSERT(::IsWindow(m_hWnd));
757 return ::GetWindowText(m_hWnd, lpszStringBuf, nMaxCount);
758 }
759
760 BOOL GetWindowText(BSTR& bstrText)
761 {
762 ATLASSERT(::IsWindow(m_hWnd));
763 int length = ::GetWindowTextLength(m_hWnd);
764 if (!SysReAllocStringLen(&bstrText, NULL, length))
765 return FALSE;
766 ::GetWindowText(m_hWnd, (LPTSTR)&bstrText[2], length);
767 return TRUE;
768 }
769
770 int GetWindowTextLength() const
771 {
772 ATLASSERT(::IsWindow(m_hWnd));
773 return ::GetWindowTextLength(m_hWnd);
774 }
775
776 DWORD GetWindowThreadID()
777 {
778 ATLASSERT(::IsWindow(m_hWnd));
779 return ::GetWindowThreadProcessId(m_hWnd, NULL);
780 }
781
782 WORD GetWindowWord(int nIndex) const
783 {
784 ATLASSERT(::IsWindow(m_hWnd));
785 return (WORD)::GetWindowLong(m_hWnd, nIndex);
786 }
787
788 void GotoDlgCtrl(HWND hWndCtrl) const
789 {
790 ATLASSERT(::IsWindow(m_hWnd));
791 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0);
792 }
793
794 BOOL HideCaret()
795 {
796 ATLASSERT(::IsWindow(m_hWnd));
797 return ::HideCaret(m_hWnd);
798 }
799
800 BOOL HiliteMenuItem(HMENU hMenu, UINT uHiliteItem, UINT uHilite)
801 {
802 ATLASSERT(::IsWindow(m_hWnd));
803 return ::HiliteMenuItem(m_hWnd, hMenu, uHiliteItem, uHilite);
804 }
805
806 BOOL Invalidate(BOOL bErase = TRUE)
807 {
808 ATLASSERT(::IsWindow(m_hWnd));
809 return ::InvalidateRect(m_hWnd, NULL, bErase);
810 }
811
812 BOOL InvalidateRect(LPCRECT lpRect, BOOL bErase = TRUE)
813 {
814 ATLASSERT(::IsWindow(m_hWnd));
815 return ::InvalidateRect(m_hWnd, lpRect, bErase);
816 }
817
818 void InvalidateRgn(HRGN hRgn, BOOL bErase = TRUE)
819 {
820 ATLASSERT(::IsWindow(m_hWnd));
821 ::InvalidateRgn(m_hWnd, hRgn, bErase);
822 }
823
824 BOOL IsChild(const HWND hWnd) const
825 {
826 ATLASSERT(::IsWindow(m_hWnd));
827 return ::IsChild(m_hWnd, hWnd);
828 }
829
830 BOOL IsDialogMessage(LPMSG lpMsg)
831 {
832 ATLASSERT(::IsWindow(m_hWnd));
833 return ::IsDialogMessage(m_hWnd, lpMsg);
834 }
835
836 UINT IsDlgButtonChecked(int nIDButton) const
837 {
838 ATLASSERT(::IsWindow(m_hWnd));
839 return ::IsDlgButtonChecked(m_hWnd, nIDButton);
840 }
841
842 BOOL IsIconic() const
843 {
844 ATLASSERT(::IsWindow(m_hWnd));
845 return ::IsIconic(m_hWnd);
846 }
847
848 BOOL IsParentDialog()
849 {
850 ATLASSERT(::IsWindow(m_hWnd));
851 TCHAR pszType[10];
852 if (!RealGetWindowClass(::GetParent(m_hWnd), pszType, sizeof(pszType) / sizeof(pszType[0])))
853 return FALSE;
854 return !_tcscmp(pszType, _T("#32770"));
855 }
856
857 BOOL IsWindow() const
858 {
859 return ::IsWindow(m_hWnd);
860 }
861
862 BOOL IsWindowEnabled() const
863 {
864 ATLASSERT(::IsWindow(m_hWnd));
865 return ::IsWindowEnabled(m_hWnd);
866 }
867
868 BOOL IsWindowVisible() const
869 {
870 ATLASSERT(::IsWindow(m_hWnd));
871 return ::IsWindowVisible(m_hWnd);
872 }
873
874 BOOL IsWindowUnicode()
875 {
876 ATLASSERT(::IsWindow(m_hWnd));
877 return ::IsWindowUnicode(m_hWnd);
878 }
879
880 BOOL IsZoomed() const
881 {
882 ATLASSERT(::IsWindow(m_hWnd));
883 return ::IsZoomed(m_hWnd);
884 }
885
886 BOOL KillTimer(UINT_PTR nIDEvent)
887 {
888 ATLASSERT(::IsWindow(m_hWnd));
889 return ::KillTimer(m_hWnd, nIDEvent);
890 }
891
892 BOOL LockWindowUpdate(BOOL bLock = TRUE)
893 {
894 ATLASSERT(::IsWindow(m_hWnd));
895 if (bLock)
896 return ::LockWindowUpdate(m_hWnd);
897 return ::LockWindowUpdate(NULL);
898 }
899
900 int MapWindowPoints(HWND hWndTo, LPPOINT lpPoint, UINT nCount) const
901 {
902 ATLASSERT(::IsWindow(m_hWnd));
903 return ::MapWindowPoints(m_hWnd, hWndTo, lpPoint, nCount);
904 }
905
906 int MapWindowPoints(HWND hWndTo, LPRECT lpRect) const
907 {
908 ATLASSERT(::IsWindow(m_hWnd));
909 return ::MapWindowPoints(m_hWnd, hWndTo, (LPPOINT)lpRect, sizeof(RECT) / sizeof(POINT));
910 }
911
912 int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK)
913 {
914 ATLASSERT(::IsWindow(m_hWnd));
915 return ::MessageBox(m_hWnd, lpszText, lpszCaption, nType);
916 }
917
918 BOOL ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
919 {
920 ATLASSERT(::IsWindow(m_hWnd));
921 ::SetWindowLong(m_hWnd, GWL_STYLE, (::GetWindowLong(m_hWnd, GWL_STYLE) & ~dwRemove) | dwAdd);
922 if (nFlags != 0)
923 return ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, nFlags | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
924 return TRUE;
925 }
926
927 BOOL ModifyStyleEx(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0)
928 {
929 ATLASSERT(::IsWindow(m_hWnd));
930 ::SetWindowLong(m_hWnd, GWL_EXSTYLE, (::GetWindowLong(m_hWnd, GWL_EXSTYLE) & ~dwRemove) | dwAdd);
931 if (nFlags != 0)
932 return ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, nFlags | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
933 return TRUE;
934 }
935
936 BOOL MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint = TRUE)
937 {
938 ATLASSERT(::IsWindow(m_hWnd));
939 return ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint);
940 }
941
942 void NextDlgCtrl() const
943 {
944 ATLASSERT(::IsWindow(m_hWnd));
945 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0);
946 }
947
948 BOOL OpenClipboard()
949 {
950 ATLASSERT(::IsWindow(m_hWnd));
951 return ::OpenClipboard(m_hWnd);
952 }
953
954 BOOL PostMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
955 {
956 ATLASSERT(::IsWindow(m_hWnd));
957 return ::PostMessage(m_hWnd, message, wParam, lParam);
958 }
959
960 void PrevDlgCtrl() const
961 {
962 ATLASSERT(::IsWindow(m_hWnd));
963 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 1, 0);
964 }
965
966 void Print(HDC hDC, DWORD dwFlags) const
967 {
968 ATLASSERT(::IsWindow(m_hWnd));
969 ::SendMessage(m_hWnd, WM_PRINT, (WPARAM)hDC, (LPARAM)dwFlags);
970 }
971
972 void PrintClient(HDC hDC, DWORD dwFlags) const
973 {
974 ATLASSERT(::IsWindow(m_hWnd));
975 ::SendMessage(m_hWnd, WM_PRINTCLIENT, (WPARAM)hDC, (LPARAM)dwFlags);
976 }
977
978 BOOL RedrawWindow(LPCRECT lpRectUpdate = NULL, HRGN hRgnUpdate = NULL, UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE)
979 {
980 ATLASSERT(::IsWindow(m_hWnd));
981 return ::RedrawWindow(m_hWnd, lpRectUpdate, hRgnUpdate, flags);
982 }
983
984 int ReleaseDC(HDC hDC)
985 {
986 ATLASSERT(::IsWindow(m_hWnd));
987 return ::ReleaseDC(m_hWnd, hDC);
988 }
989
990 BOOL ResizeClient(int nWidth, int nHeight, BOOL bRedraw = FALSE)
991 {
992 ATLASSERT(::IsWindow(m_hWnd));
993 RECT clientRect, wndRect;
994 ::GetClientRect(m_hWnd, &clientRect);
995 ::GetWindowRect(m_hWnd, &wndRect);
996 return ::MoveWindow(m_hWnd, wndRect.left, wndRect.top,
997 nWidth + (wndRect.right - wndRect.left) - (clientRect.right - clientRect.left),
998 nHeight + (wndRect.bottom - wndRect.top) - (clientRect.bottom - clientRect.top),
999 bRedraw);
1000 }
1001
1002 BOOL ScreenToClient(LPPOINT lpPoint) const
1003 {
1004 ATLASSERT(::IsWindow(m_hWnd));
1005 return ::ScreenToClient(m_hWnd, lpPoint);
1006 }
1007
1008 BOOL ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL)
1009 {
1010 ATLASSERT(::IsWindow(m_hWnd));
1011 return ::ScrollWindow(m_hWnd, xAmount, yAmount, lpRect, lpClipRect);
1012 }
1013
1014 int ScrollWindowEx(int dx, int dy, LPCRECT lpRectScroll, LPCRECT lpRectClip, HRGN hRgnUpdate, LPRECT lpRectUpdate, UINT flags)
1015 {
1016 ATLASSERT(::IsWindow(m_hWnd));
1017 return ::ScrollWindowEx(m_hWnd, dx, dy, lpRectScroll, lpRectClip, hRgnUpdate, lpRectUpdate, flags);
1018 }
1019
1020 LRESULT SendDlgItemMessage(int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
1021 {
1022 ATLASSERT(::IsWindow(m_hWnd));
1023 return ::SendDlgItemMessage(m_hWnd, nID, message, wParam, lParam);
1024 }
1025
1026 LRESULT SendMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
1027 {
1028 ATLASSERT(::IsWindow(m_hWnd));
1029 return ::SendMessage(m_hWnd, message, wParam, lParam);
1030 }
1031
1032 static LRESULT SendMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1033 {
1034 ATLASSERT(::IsWindow(hWnd));
1035 return ::SendMessage(hWnd, message, wParam, lParam);
1036 }
1037
1038 private:
1039 static BOOL CALLBACK SendMessageToDescendantsCallback(HWND hWnd, LPARAM lParam)
1040 {
1041 ::SendMessage(hWnd, ((LPMSG)lParam)->message, ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam);
1042 return TRUE;
1043 }
1044
1045 static BOOL CALLBACK SendMessageToDescendantsCallbackDeep(HWND hWnd, LPARAM lParam)
1046 {
1047 ::SendMessage(hWnd, ((LPMSG)lParam)->message, ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam);
1048 ::EnumChildWindows(hWnd, &SendMessageToDescendantsCallbackDeep, lParam);
1049 return TRUE;
1050 }
1051
1052 public:
1053 void SendMessageToDescendants(UINT message, WPARAM wParam = 0, LPARAM lParam = 0, BOOL bDeep = TRUE)
1054 {
1055 ATLASSERT(::IsWindow(m_hWnd));
1056 MSG msg;
1057 msg.message = message;
1058 msg.wParam = wParam;
1059 msg.lParam = lParam;
1060 if (bDeep)
1061 ::EnumChildWindows(m_hWnd, &SendMessageToDescendantsCallback, (LPARAM)&msg);
1062 else
1063 ::EnumChildWindows(m_hWnd, &SendMessageToDescendantsCallbackDeep, (LPARAM)&msg);
1064 }
1065
1066 BOOL SendNotifyMessage(UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
1067 {
1068 ATLASSERT(::IsWindow(m_hWnd));
1069 return ::SendNotifyMessage(m_hWnd, message, wParam, lParam);
1070 }
1071
1072 HWND SetActiveWindow()
1073 {
1074 ATLASSERT(::IsWindow(m_hWnd));
1075 return ::SetActiveWindow(m_hWnd);
1076 }
1077
1078 HWND SetCapture()
1079 {
1080 ATLASSERT(::IsWindow(m_hWnd));
1081 return ::SetCapture(m_hWnd);
1082 }
1083
1084 HWND SetClipboardViewer()
1085 {
1086 ATLASSERT(::IsWindow(m_hWnd));
1087 return ::SetClipboardViewer(m_hWnd);
1088 }
1089
1090 int SetDlgCtrlID(int nID)
1091 {
1092 ATLASSERT(::IsWindow(m_hWnd));
1093 return ::SetWindowLong(m_hWnd, GWL_ID, nID);
1094 }
1095
1096 BOOL SetDlgItemInt(int nID, UINT nValue, BOOL bSigned = TRUE)
1097 {
1098 ATLASSERT(::IsWindow(m_hWnd));
1099 return ::SetDlgItemInt(m_hWnd, nID, nValue, bSigned);
1100 }
1101
1102 BOOL SetDlgItemText(int nID, LPCTSTR lpszString)
1103 {
1104 ATLASSERT(::IsWindow(m_hWnd));
1105 return ::SetDlgItemText(m_hWnd, nID, lpszString);
1106 }
1107
1108 HWND SetFocus()
1109 {
1110 ATLASSERT(::IsWindow(m_hWnd));
1111 return ::SetFocus(m_hWnd);
1112 }
1113
1114 void SetFont(HFONT hFont, BOOL bRedraw = TRUE)
1115 {
1116 ATLASSERT(::IsWindow(m_hWnd));
1117 ::SendMessage(m_hWnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)bRedraw);
1118 }
1119
1120 int SetHotKey(WORD wVirtualKeyCode, WORD wModifiers)
1121 {
1122 ATLASSERT(::IsWindow(m_hWnd));
1123 return ::SendMessage(m_hWnd, WM_SETHOTKEY, MAKEWPARAM(wVirtualKeyCode, wModifiers), 0);
1124 }
1125
1126 HICON SetIcon(HICON hIcon, BOOL bBigIcon = TRUE)
1127 {
1128 ATLASSERT(::IsWindow(m_hWnd));
1129 return (HICON)::SendMessage(m_hWnd, WM_SETICON, (WPARAM)bBigIcon, (LPARAM)hIcon);
1130 }
1131
1132 BOOL SetMenu(HMENU hMenu)
1133 {
1134 ATLASSERT(::IsWindow(m_hWnd));
1135 return ::SetMenu(m_hWnd, hMenu);
1136 }
1137
1138 HWND SetParent(HWND hWndNewParent)
1139 {
1140 ATLASSERT(::IsWindow(m_hWnd));
1141 return ::SetParent(m_hWnd, hWndNewParent);
1142 }
1143
1144 void SetRedraw(BOOL bRedraw = TRUE)
1145 {
1146 ATLASSERT(::IsWindow(m_hWnd));
1147 ::SendMessage(m_hWnd, WM_SETREDRAW, (WPARAM)bRedraw, 0);
1148 }
1149
1150 int SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE)
1151 {
1152 ATLASSERT(::IsWindow(m_hWnd));
1153 return ::SetScrollInfo(m_hWnd, nBar, lpScrollInfo, bRedraw);
1154 }
1155
1156 int SetScrollPos(int nBar, int nPos, BOOL bRedraw = TRUE)
1157 {
1158 ATLASSERT(::IsWindow(m_hWnd));
1159 return ::SetScrollPos(m_hWnd, nBar, nPos, bRedraw);
1160 }
1161
1162 BOOL SetScrollRange(int nBar, int nMinPos, int nMaxPos, BOOL bRedraw = TRUE)
1163 {
1164 ATLASSERT(::IsWindow(m_hWnd));
1165 return ::SetScrollRange(m_hWnd, nBar, nMinPos, nMaxPos, bRedraw);
1166 }
1167
1168 UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT nElapse, void (CALLBACK *lpfnTimer)(HWND, UINT, UINT_PTR, DWORD) = NULL)
1169 {
1170 ATLASSERT(::IsWindow(m_hWnd));
1171 return ::SetTimer(m_hWnd, nIDEvent, nElapse, reinterpret_cast<TIMERPROC>(lpfnTimer));
1172 }
1173
1174 BOOL SetWindowContextHelpId(DWORD dwContextHelpId)
1175 {
1176 ATLASSERT(::IsWindow(m_hWnd));
1177 return ::SetWindowContextHelpId(m_hWnd, dwContextHelpId);
1178 }
1179
1180 LONG SetWindowLong(int nIndex, LONG dwNewLong)
1181 {
1182 ATLASSERT(::IsWindow(m_hWnd));
1183 return ::SetWindowLong(m_hWnd, nIndex, dwNewLong);
1184 }
1185
1186 LONG_PTR SetWindowLongPtr(int nIndex, LONG_PTR dwNewLong)
1187 {
1188 ATLASSERT(::IsWindow(m_hWnd));
1189 return ::SetWindowLongPtr(m_hWnd, nIndex, dwNewLong);
1190 }
1191
1192 BOOL SetWindowPlacement(const WINDOWPLACEMENT* lpwndpl)
1193 {
1194 ATLASSERT(::IsWindow(m_hWnd));
1195 return ::SetWindowPlacement(m_hWnd, lpwndpl);
1196 }
1197
1198 BOOL SetWindowPos(HWND hWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags)
1199 {
1200 ATLASSERT(::IsWindow(m_hWnd));
1201 return ::SetWindowPos(m_hWnd, hWndInsertAfter, x, y, cx, cy, nFlags);
1202 }
1203
1204 int SetWindowRgn(HRGN hRgn, BOOL bRedraw = FALSE)
1205 {
1206 ATLASSERT(::IsWindow(m_hWnd));
1207 return ::SetWindowRgn(m_hWnd, hRgn, bRedraw);
1208 }
1209
1210 BOOL SetWindowText(LPCTSTR lpszString)
1211 {
1212 ATLASSERT(::IsWindow(m_hWnd));
1213 return ::SetWindowText(m_hWnd, lpszString);
1214 }
1215
1216 WORD SetWindowWord(int nIndex, WORD wNewWord)
1217 {
1218 ATLASSERT(::IsWindow(m_hWnd));
1219 if (nIndex >= -4)
1220 return ::SetWindowLong(m_hWnd, nIndex - 2, MAKELONG(LOWORD(::GetWindowLong(m_hWnd, nIndex - 2)), wNewWord));
1221 else
1222 return ::SetWindowLong(m_hWnd, nIndex, MAKELONG(wNewWord, HIWORD(::GetWindowLong(m_hWnd, nIndex))));
1223 }
1224
1225 BOOL ShowCaret()
1226 {
1227 ATLASSERT(::IsWindow(m_hWnd));
1228 return ::ShowCaret(m_hWnd);
1229 }
1230
1231 BOOL ShowOwnedPopups(BOOL bShow = TRUE)
1232 {
1233 ATLASSERT(::IsWindow(m_hWnd));
1234 return ::ShowOwnedPopups(m_hWnd, bShow);
1235 }
1236
1237 BOOL ShowScrollBar(UINT nBar, BOOL bShow = TRUE)
1238 {
1239 ATLASSERT(::IsWindow(m_hWnd));
1240 return ::ShowScrollBar(m_hWnd, nBar, bShow);
1241 }
1242
1243 BOOL ShowWindow(int nCmdShow)
1244 {
1245 ATLASSERT(::IsWindow(m_hWnd));
1246 return ::ShowWindow(m_hWnd, nCmdShow);
1247 }
1248
1249 BOOL ShowWindowAsync(int nCmdShow)
1250 {
1251 ATLASSERT(::IsWindow(m_hWnd));
1252 return ::ShowWindowAsync(m_hWnd, nCmdShow);
1253 }
1254
1255 BOOL UpdateWindow()
1256 {
1257 ATLASSERT(::IsWindow(m_hWnd));
1258 return ::UpdateWindow(m_hWnd);
1259 }
1260
1261 BOOL ValidateRect(LPCRECT lpRect)
1262 {
1263 ATLASSERT(::IsWindow(m_hWnd));
1264 return ::ValidateRect(m_hWnd, lpRect);
1265 }
1266
1267 BOOL ValidateRgn(HRGN hRgn)
1268 {
1269 ATLASSERT(::IsWindow(m_hWnd));
1270 return ::ValidateRgn(m_hWnd, hRgn);
1271 }
1272
1273 BOOL WinHelp(LPCTSTR lpszHelp, UINT nCmd = HELP_CONTEXT, DWORD dwData = 0)
1274 {
1275 ATLASSERT(::IsWindow(m_hWnd));
1276 return ::WinHelp(m_hWnd, lpszHelp, nCmd, dwData);
1277 }
1278 };
1279
1280 __declspec(selectany) RECT CWindow::rcDefault = { CW_USEDEFAULT, CW_USEDEFAULT, 0, 0 };
1281
1282 template <class TBase = CWindow>
1283 class CWindowImplRoot : public TBase, public CMessageMap
1284 {
1285 public:
1286 enum { WINSTATE_DESTROYED = 0x00000001 };
1287
1288 public:
1289 CWndProcThunk m_thunk;
1290 const _ATL_MSG *m_pCurrentMsg;
1291 DWORD m_dwState;
1292
1293 CWindowImplRoot()
1294 : m_pCurrentMsg(NULL)
1295 , m_dwState(0)
1296 {
1297 }
1298
1299 virtual ~CWindowImplRoot()
1300 {
1301 }
1302 };
1303
1304
1305 template <class TBase = CWindow>
1306 class CDialogImplBaseT : public CWindowImplRoot<TBase>
1307 {
1308 public:
1309 // + Hacks for gcc
1310 using CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
1311 // - Hacks for gcc
1312
1313 virtual ~CDialogImplBaseT()
1314 {
1315 }
1316 virtual DLGPROC GetDialogProc()
1317 {
1318 return DialogProc;
1319 }
1320
1321 static INT_PTR CALLBACK StartDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1322 {
1323 CDialogImplBaseT<TBase> *pThis;
1324 DLGPROC newDlgProc;
1325 DLGPROC GCCU(pOldProc);
1326
1327 pThis = reinterpret_cast<CDialogImplBaseT<TBase>*>(_AtlWinModule.ExtractCreateWndData());
1328 ATLASSERT(pThis != NULL);
1329 if (pThis == NULL)
1330 return 0;
1331 pThis->m_thunk.Init((WNDPROC)pThis->GetDialogProc(), pThis);
1332 newDlgProc = reinterpret_cast<DLGPROC>(pThis->m_thunk.GetWNDPROC());
1333 pOldProc = reinterpret_cast<DLGPROC>(::SetWindowLongPtr(hWnd, DWLP_DLGPROC, reinterpret_cast<LONG_PTR>(newDlgProc)));
1334 Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
1335 pThis->m_hWnd = hWnd;
1336 return newDlgProc(hWnd, uMsg, wParam, lParam);
1337 }
1338
1339 static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1340 {
1341 CDialogImplBaseT<TBase> *pThis = reinterpret_cast<CDialogImplBaseT<TBase>*>(hWnd);
1342 _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1343 LRESULT lResult = 0;
1344 const _ATL_MSG *previousMessage;
1345 BOOL handled;
1346
1347 hWnd = pThis->m_hWnd;
1348 previousMessage = pThis->m_pCurrentMsg;
1349 pThis->m_pCurrentMsg = &msg;
1350
1351 handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
1352 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1353
1354 if (handled)
1355 {
1356 if ((pThis->m_dwState & WINSTATE_DESTROYED) == 0)
1357 {
1358 ::SetWindowLongPtr(pThis->m_hWnd, DWLP_MSGRESULT, lResult);
1359 }
1360 }
1361 else
1362 {
1363 if (uMsg == WM_NCDESTROY)
1364 {
1365 pThis->m_dwState |= WINSTATE_DESTROYED;
1366 }
1367 }
1368
1369 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1370 pThis->m_pCurrentMsg = previousMessage;
1371
1372 if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
1373 {
1374 pThis->m_dwState &= ~WINSTATE_DESTROYED;
1375 pThis->m_hWnd = NULL;
1376 pThis->OnFinalMessage(hWnd);
1377 }
1378 return lResult;
1379 }
1380
1381 virtual void OnFinalMessage(HWND)
1382 {
1383 }
1384 };
1385
1386
1387 template <class T, class TBase = CWindow>
1388 class CDialogImpl : public CDialogImplBaseT< TBase >
1389 {
1390 public:
1391 // + Hacks for gcc
1392 using CWindowImplRoot<TBase>::m_thunk;
1393 using CWindowImplRoot<TBase>::m_hWnd;
1394 // - Hacks for gcc
1395
1396 HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
1397 {
1398 BOOL result;
1399 HWND hWnd;
1400 T* pImpl;
1401
1402 result = m_thunk.Init(NULL, NULL);
1403 if (result == FALSE)
1404 return NULL;
1405
1406 _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
1407
1408 pImpl = static_cast<T*>(this);
1409 hWnd = ::CreateDialogParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(pImpl->IDD), hWndParent, T::StartDialogProc, dwInitParam);
1410 return hWnd;
1411 }
1412
1413 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
1414 {
1415 BOOL result;
1416 T* pImpl;
1417
1418 result = m_thunk.Init(NULL, NULL);
1419 if (result == FALSE)
1420 return -1;
1421
1422 _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
1423
1424 pImpl = static_cast<T*>(this);
1425 return ::DialogBoxParam(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(pImpl->IDD), hWndParent, T::StartDialogProc, dwInitParam);
1426 }
1427
1428 BOOL EndDialog(_In_ int nRetCode)
1429 {
1430 return ::EndDialog(m_hWnd, nRetCode);
1431 }
1432
1433 BOOL DestroyWindow()
1434 {
1435 return ::DestroyWindow(m_hWnd);
1436 }
1437 };
1438
1439 template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
1440 class CWindowImplBaseT : public CWindowImplRoot<TBase>
1441 {
1442 public:
1443 // + Hacks for gcc
1444 using CWindowImplRoot<TBase>::WINSTATE_DESTROYED;
1445 using CWindowImplRoot<TBase>::m_thunk;
1446 // - Hacks for gcc
1447
1448 WNDPROC m_pfnSuperWindowProc;
1449
1450 public:
1451 CWindowImplBaseT()
1452 {
1453 m_pfnSuperWindowProc = ::DefWindowProc;
1454 }
1455
1456 virtual void OnFinalMessage(HWND /* hWnd */)
1457 {
1458 }
1459
1460 BOOL SubclassWindow(HWND hWnd)
1461 {
1462 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1463 WNDPROC newWindowProc;
1464 WNDPROC oldWindowProc;
1465 BOOL result;
1466
1467 ATLASSERT(m_hWnd == NULL);
1468 ATLASSERT(::IsWindow(hWnd));
1469
1470 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this);
1471
1472 result = m_thunk.Init(GetWindowProc(), this);
1473 if (result == FALSE)
1474 return FALSE;
1475 newWindowProc = m_thunk.GetWNDPROC();
1476 oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1477 if (oldWindowProc == NULL)
1478 return FALSE;
1479 m_pfnSuperWindowProc = oldWindowProc;
1480 pThis->m_hWnd = hWnd;
1481 return TRUE;
1482 }
1483
1484 virtual WNDPROC GetWindowProc()
1485 {
1486 return WindowProc;
1487 }
1488
1489 static DWORD GetWndStyle(DWORD dwStyle)
1490 {
1491 return TWinTraits::GetWndStyle(dwStyle);
1492 }
1493
1494 static DWORD GetWndExStyle(DWORD dwExStyle)
1495 {
1496 return TWinTraits::GetWndExStyle(dwExStyle);
1497 }
1498
1499 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
1500 {
1501 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1502
1503 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(this);
1504 return ::CallWindowProc(m_pfnSuperWindowProc, pThis->m_hWnd, uMsg, wParam, lParam);
1505 }
1506
1507 static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1508 {
1509 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1510 WNDPROC newWindowProc;
1511 WNDPROC GCCU(pOldProc);
1512
1513 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits> *>(_AtlWinModule.ExtractCreateWndData());
1514 ATLASSERT(pThis != NULL);
1515 if (pThis == NULL)
1516 return 0;
1517 pThis->m_thunk.Init(pThis->GetWindowProc(), pThis);
1518 newWindowProc = pThis->m_thunk.GetWNDPROC();
1519 pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1520 Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
1521 pThis->m_hWnd = hWnd;
1522 return newWindowProc(hWnd, uMsg, wParam, lParam);
1523 }
1524
1525 static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1526 {
1527 CWindowImplBaseT<TBase, TWinTraits> *pThis = reinterpret_cast<CWindowImplBaseT< TBase, TWinTraits> *>(hWnd);
1528 _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1529 LRESULT lResult;
1530 const _ATL_MSG *previousMessage;
1531 BOOL handled;
1532 LONG_PTR saveWindowProc;
1533
1534 ATLASSERT(pThis != NULL && (pThis->m_dwState & WINSTATE_DESTROYED) == 0 && pThis->m_hWnd != NULL);
1535 if (pThis == NULL || (pThis->m_dwState & WINSTATE_DESTROYED) != 0 || pThis->m_hWnd == NULL)
1536 return 0;
1537
1538 hWnd = pThis->m_hWnd;
1539 previousMessage = pThis->m_pCurrentMsg;
1540 pThis->m_pCurrentMsg = &msg;
1541
1542 handled = pThis->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, 0);
1543 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1544
1545 if (handled == FALSE)
1546 {
1547 if (uMsg == WM_NCDESTROY)
1548 {
1549 saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
1550 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1551 if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC))
1552 ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc));
1553 pThis->m_dwState |= WINSTATE_DESTROYED;
1554 }
1555 else
1556 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1557 }
1558 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1559 pThis->m_pCurrentMsg = previousMessage;
1560 if (previousMessage == NULL && (pThis->m_dwState & WINSTATE_DESTROYED) != 0)
1561 {
1562 pThis->m_dwState &= ~WINSTATE_DESTROYED;
1563 pThis->m_hWnd = NULL;
1564 pThis->OnFinalMessage(hWnd);
1565 }
1566 return lResult;
1567 }
1568
1569 HWND Create(HWND hWndParent, _U_RECT rect, LPCTSTR szWindowName, DWORD dwStyle, DWORD dwExStyle,
1570 _U_MENUorID MenuOrID, ATOM atom, LPVOID lpCreateParam)
1571 {
1572 HWND hWnd;
1573
1574 ATLASSERT(m_hWnd == NULL);
1575 ATLASSERT(atom != 0);
1576 if (atom == 0)
1577 return NULL;
1578 if (m_thunk.Init(NULL, NULL) == FALSE)
1579 {
1580 SetLastError(ERROR_OUTOFMEMORY);
1581 return NULL;
1582 }
1583
1584 _AtlWinModule.AddCreateWndData(&m_thunk.cd, this);
1585 if (MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD) != 0)
1586 MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this;
1587 if (rect.m_lpRect == NULL)
1588 rect.m_lpRect = &TBase::rcDefault;
1589 hWnd = ::CreateWindowEx(dwExStyle, reinterpret_cast<LPCWSTR>(MAKEINTATOM(atom)), szWindowName, dwStyle, rect.m_lpRect->left,
1590 rect.m_lpRect->top, rect.m_lpRect->right - rect.m_lpRect->left, rect.m_lpRect->bottom - rect.m_lpRect->top,
1591 hWndParent, MenuOrID.m_hMenu, _AtlBaseModule.GetModuleInstance(), lpCreateParam);
1592
1593 ATLASSERT(m_hWnd == hWnd);
1594
1595 return hWnd;
1596 }
1597 };
1598
1599
1600 template <class T, class TBase = CWindow, class TWinTraits = CControlWinTraits>
1601 class CWindowImpl : public CWindowImplBaseT<TBase, TWinTraits>
1602 {
1603 public:
1604 static LPCTSTR GetWndCaption()
1605 {
1606 return NULL;
1607 }
1608
1609 HWND Create(HWND hWndParent, _U_RECT rect = NULL, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0,
1610 DWORD dwExStyle = 0, _U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
1611 {
1612 CWindowImplBaseT<TBase, TWinTraits> *pThis;
1613 ATOM atom;
1614
1615 ATLASSERT(m_hWnd == NULL);
1616 pThis = reinterpret_cast<CWindowImplBaseT<TBase, TWinTraits>*>(this);
1617
1618 if (T::GetWndClassInfo().m_lpszOrigName == NULL)
1619 T::GetWndClassInfo().m_lpszOrigName = pThis->GetWndClassName();
1620 atom = T::GetWndClassInfo().Register(&pThis->m_pfnSuperWindowProc);
1621
1622 if (szWindowName == NULL)
1623 szWindowName = T::GetWndCaption();
1624 dwStyle = T::GetWndStyle(dwStyle);
1625 dwExStyle = T::GetWndExStyle(dwExStyle);
1626
1627 return CWindowImplBaseT<TBase, TWinTraits>::Create(hWndParent, rect, szWindowName, dwStyle,
1628 dwExStyle, MenuOrID, atom, lpCreateParam);
1629 }
1630 };
1631
1632 template <class TBase = CWindow, class TWinTraits = CControlWinTraits>
1633 class CContainedWindowT : public TBase
1634 {
1635 public:
1636 CWndProcThunk m_thunk;
1637 LPCTSTR m_lpszClassName;
1638 WNDPROC m_pfnSuperWindowProc;
1639 CMessageMap *m_pObject;
1640 DWORD m_dwMsgMapID;
1641 const _ATL_MSG *m_pCurrentMsg;
1642 public:
1643 CContainedWindowT(CMessageMap *pObject, DWORD dwMsgMapID = 0)
1644 {
1645 m_lpszClassName = TBase::GetWndClassName();
1646 m_pfnSuperWindowProc = ::DefWindowProc;
1647 m_pObject = pObject;
1648 m_dwMsgMapID = dwMsgMapID;
1649 m_pCurrentMsg = NULL;
1650 }
1651
1652 CContainedWindowT(LPTSTR lpszClassName, CMessageMap *pObject, DWORD dwMsgMapID = 0)
1653 {
1654 m_lpszClassName = lpszClassName;
1655 m_pfnSuperWindowProc = ::DefWindowProc;
1656 m_pObject = pObject;
1657 m_dwMsgMapID = dwMsgMapID;
1658 m_pCurrentMsg = NULL;
1659 }
1660
1661 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
1662 {
1663 return ::CallWindowProc(m_pfnSuperWindowProc, this->m_hWnd, uMsg, wParam, lParam);
1664 }
1665
1666 BOOL SubclassWindow(HWND hWnd)
1667 {
1668 CContainedWindowT<TBase> *pThis;
1669 WNDPROC newWindowProc;
1670 WNDPROC oldWindowProc;
1671 BOOL result;
1672
1673 ATLASSERT(m_hWnd == NULL);
1674 ATLASSERT(::IsWindow(hWnd));
1675
1676 pThis = reinterpret_cast<CContainedWindowT<TBase> *>(this);
1677
1678 result = m_thunk.Init(WindowProc, pThis);
1679 if (result == FALSE)
1680 return FALSE;
1681 newWindowProc = m_thunk.GetWNDPROC();
1682 oldWindowProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1683 if (oldWindowProc == NULL)
1684 return FALSE;
1685 m_pfnSuperWindowProc = oldWindowProc;
1686 pThis->m_hWnd = hWnd;
1687 return TRUE;
1688 }
1689
1690 static LRESULT CALLBACK StartWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1691 {
1692 CContainedWindowT<TBase> *pThis;
1693 WNDPROC newWindowProc;
1694 WNDPROC GCCU(pOldProc);
1695
1696 pThis = reinterpret_cast<CContainedWindowT<TBase> *>(_AtlWinModule.ExtractCreateWndData());
1697 ATLASSERT(pThis != NULL);
1698 if (pThis == NULL)
1699 return 0;
1700 pThis->m_thunk.Init(WindowProc, pThis);
1701 newWindowProc = pThis->m_thunk.GetWNDPROC();
1702 pOldProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(newWindowProc)));
1703 Unused(pOldProc); // TODO: should generate trace message if overwriting another subclass
1704 pThis->m_hWnd = hWnd;
1705 return newWindowProc(hWnd, uMsg, wParam, lParam);
1706 }
1707
1708 static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1709 {
1710 CContainedWindowT<TBase> *pThis = reinterpret_cast<CContainedWindowT<TBase> *>(hWnd);
1711 _ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam);
1712 LRESULT lResult;
1713 const _ATL_MSG *previousMessage;
1714 BOOL handled;
1715 LONG_PTR saveWindowProc;
1716
1717 ATLASSERT(pThis != NULL && pThis->m_hWnd != NULL && pThis->m_pObject != NULL);
1718 if (pThis == NULL || pThis->m_hWnd == NULL || pThis->m_pObject == NULL)
1719 return 0;
1720
1721 hWnd = pThis->m_hWnd;
1722 previousMessage = pThis->m_pCurrentMsg;
1723 pThis->m_pCurrentMsg = &msg;
1724
1725 handled = pThis->m_pObject->ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, pThis->m_dwMsgMapID);
1726 ATLASSERT(pThis->m_pCurrentMsg == &msg);
1727
1728 pThis->m_pCurrentMsg = previousMessage;
1729 if (handled == FALSE)
1730 {
1731 if (uMsg == WM_NCDESTROY)
1732 {
1733 saveWindowProc = ::GetWindowLongPtr(hWnd, GWLP_WNDPROC);
1734 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1735 if (pThis->m_pfnSuperWindowProc != ::DefWindowProc && saveWindowProc == ::GetWindowLongPtr(hWnd, GWLP_WNDPROC))
1736 ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(pThis->m_pfnSuperWindowProc));
1737 pThis->m_hWnd = NULL;
1738 }
1739 else
1740 lResult = pThis->DefWindowProc(uMsg, wParam, lParam);
1741 }
1742 return lResult;
1743 }
1744
1745 };
1746 typedef CContainedWindowT<CWindow> CContainedWindow;
1747
1748 #define BEGIN_MSG_MAP(theClass) \
1749 public: \
1750 BOOL ProcessWindowMessage(HWND GCCU(hWnd), UINT GCCU(uMsg), WPARAM GCCU(wParam), LPARAM GCCU(lParam), LRESULT &GCCU(lResult), DWORD dwMsgMapID = 0) \
1751 { \
1752 BOOL GCCU(bHandled) = TRUE; \
1753 Unused(hWnd); \
1754 Unused(uMsg); \
1755 Unused(wParam); \
1756 Unused(lParam); \
1757 Unused(lResult); \
1758 Unused(bHandled); \
1759 switch(dwMsgMapID) \
1760 { \
1761 case 0:
1762
1763 #define ALT_MSG_MAP(map) \
1764 break; \
1765 case map:
1766
1767 #define END_MSG_MAP() \
1768 break; \
1769 default: \
1770 ATLASSERT(FALSE); \
1771 break; \
1772 } \
1773 return FALSE; \
1774 }
1775
1776 #define MESSAGE_HANDLER(msg, func) \
1777 if (uMsg == msg) \
1778 { \
1779 bHandled = TRUE; \
1780 lResult = func(uMsg, wParam, lParam, bHandled); \
1781 if (bHandled) \
1782 return TRUE; \
1783 }
1784
1785 #define MESSAGE_RANGE_HANDLER(msgFirst, msgLast, func) \
1786 if (uMsg >= msgFirst && uMsg <= msgLast) \
1787 { \
1788 bHandled = TRUE; \
1789 lResult = func(uMsg, wParam, lParam, bHandled); \
1790 if (bHandled) \
1791 return TRUE; \
1792 }
1793
1794 #define COMMAND_ID_HANDLER(id, func) \
1795 if (uMsg == WM_COMMAND && id == LOWORD(wParam)) \
1796 { \
1797 bHandled = TRUE; \
1798 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
1799 if (bHandled) \
1800 return TRUE; \
1801 }
1802
1803 #define COMMAND_RANGE_HANDLER(idFirst, idLast, func) \
1804 if (uMsg == WM_COMMAND && LOWORD(wParam) >= idFirst && LOWORD(wParam) <= idLast) \
1805 { \
1806 bHandled = TRUE; \
1807 lResult = func(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled); \
1808 if (bHandled) \
1809 return TRUE; \
1810 }
1811
1812 #define NOTIFY_CODE_HANDLER(cd, func) \
1813 if(uMsg == WM_NOTIFY && cd == ((LPNMHDR)lParam)->code) \
1814 { \
1815 bHandled = TRUE; \
1816 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
1817 if (bHandled) \
1818 return TRUE; \
1819 }
1820
1821 #define NOTIFY_HANDLER(id, cd, func) \
1822 if(uMsg == WM_NOTIFY && id == ((LPNMHDR)lParam)->idFrom && cd == ((LPNMHDR)lParam)->code) \
1823 { \
1824 bHandled = TRUE; \
1825 lResult = func((int)wParam, (LPNMHDR)lParam, bHandled); \
1826 if (bHandled) \
1827 return TRUE; \
1828 }
1829
1830 #define CHAIN_MSG_MAP(theChainClass) \
1831 { \
1832 if (theChainClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult)) \
1833 return TRUE; \
1834 }
1835
1836 #define DECLARE_WND_CLASS_EX(WndClassName, style, bkgnd) \
1837 static ATL::CWndClassInfo& GetWndClassInfo() \
1838 { \
1839 static ATL::CWndClassInfo wc = \
1840 { \
1841 { sizeof(WNDCLASSEX), style, StartWindowProc, \
1842 0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassName, NULL }, \
1843 NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
1844 }; \
1845 return wc; \
1846 }
1847
1848 struct _ATL_WNDCLASSINFOW
1849 {
1850 WNDCLASSEXW m_wc;
1851 LPCWSTR m_lpszOrigName;
1852 WNDPROC pWndProc;
1853 LPCWSTR m_lpszCursorID;
1854 BOOL m_bSystemCursor;
1855 ATOM m_atom;
1856 WCHAR m_szAutoName[5 + sizeof(void *)];
1857
1858 ATOM Register(WNDPROC *p)
1859 {
1860 if (m_wc.hInstance == NULL)
1861 m_wc.hInstance = _AtlBaseModule.GetModuleInstance();
1862 if (m_atom == 0)
1863 {
1864 if (m_bSystemCursor)
1865 m_wc.hCursor = ::LoadCursor(NULL, m_lpszCursorID);
1866 else
1867 m_wc.hCursor = ::LoadCursor(_AtlBaseModule.GetResourceInstance(), m_lpszCursorID);
1868
1869 m_atom = RegisterClassEx(&m_wc);
1870 }
1871
1872 return m_atom;
1873 }
1874 };
1875
1876 }; // namespace ATL
1877
1878 #pragma pop_macro("SubclassWindow")
1879