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