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