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