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