1 /* 2 * ReactOS ATL 3 * 4 * Copyright 2009 Andrew Hill <ash77@reactos.org> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #pragma once 22 23 #if defined(__GNUC__) || defined(__clang__) 24 #define GCCU(x) x __attribute__((unused)) 25 #define Unused(x) 26 #else 27 #define GCCU(x) (x) 28 #define Unused(x) (x); 29 #endif // __GNUC__ 30 31 #if !defined(_WIN64) 32 #ifdef SetWindowLongPtr 33 #undef SetWindowLongPtr 34 inline LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong) 35 { 36 return SetWindowLong(hWnd, nIndex, (LONG)dwNewLong); 37 } 38 #endif 39 40 #ifdef GetWindowLongPtr 41 #undef GetWindowLongPtr 42 inline LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex) 43 { 44 return (LONG_PTR)GetWindowLong(hWnd, nIndex); 45 } 46 #endif 47 #endif // !_WIN64 48 49 #pragma push_macro("SubclassWindow") 50 #undef SubclassWindow 51 52 #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: 76 static DWORD GetWndStyle(DWORD dwStyle) 77 { 78 if (dwStyle == 0) 79 return t_dwStyle; 80 return dwStyle; 81 } 82 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: 99 static DWORD GetWndStyle(DWORD dwStyle) 100 { 101 return dwStyle | t_dwStyle | TWinTraits::GetWndStyle(dwStyle); 102 } 103 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: 115 _U_MENUorID(HMENU hMenu) 116 { 117 m_hMenu = hMenu; 118 } 119 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: 131 _U_RECT(LPRECT lpRect) 132 { 133 m_lpRect = lpRect; 134 } 135 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 171 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 194 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 217 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: 239 CWndProcThunk() 240 { 241 m_pthunk = (thunkCode*)VirtualAlloc(NULL, sizeof(thunkCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE); 242 } 243 244 ~CWndProcThunk() 245 { 246 if (m_pthunk != NULL) 247 VirtualFree(m_pthunk, 0, MEM_RELEASE); 248 } 249 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 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 282 operator HWND() const 283 { 284 return m_hWnd; 285 } 286 287 static LPCTSTR GetWndClassName() 288 { 289 return NULL; 290 } 291 292 UINT ArrangeIconicWindows() 293 { 294 ATLASSERT(::IsWindow(m_hWnd)); 295 return ::ArrangeIconicWindows(m_hWnd); 296 } 297 298 void Attach(HWND hWndNew) 299 { 300 m_hWnd = hWndNew; 301 } 302 303 HDC BeginPaint(LPPAINTSTRUCT lpPaint) 304 { 305 ATLASSERT(::IsWindow(m_hWnd)); 306 return ::BeginPaint(m_hWnd, lpPaint); 307 } 308 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 363 BOOL ChangeClipboardChain(HWND hWndNewNext) 364 { 365 ATLASSERT(::IsWindow(m_hWnd)); 366 return ::ChangeClipboardChain(m_hWnd, hWndNewNext); 367 } 368 369 BOOL CheckDlgButton(int nIDButton, UINT nCheck) 370 { 371 ATLASSERT(::IsWindow(m_hWnd)); 372 return ::CheckDlgButton(m_hWnd, nIDButton, nCheck); 373 } 374 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 381 HWND ChildWindowFromPoint(POINT point) const 382 { 383 ATLASSERT(::IsWindow(m_hWnd)); 384 return ::ChildWindowFromPoint(m_hWnd, point); 385 } 386 387 HWND ChildWindowFromPointEx(POINT point, UINT uFlags) const 388 { 389 ATLASSERT(::IsWindow(m_hWnd)); 390 return ::ChildWindowFromPointEx(m_hWnd, point, uFlags); 391 } 392 393 BOOL ClientToScreen(LPPOINT lpPoint) const 394 { 395 ATLASSERT(::IsWindow(m_hWnd)); 396 return ::ClientToScreen(m_hWnd, lpPoint); 397 } 398 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 438 BOOL CreateCaret(HBITMAP pBitmap) 439 { 440 ATLASSERT(::IsWindow(m_hWnd)); 441 return ::CreateCaret(m_hWnd, pBitmap, 0, 0); 442 } 443 444 BOOL CreateGrayCaret(int nWidth, int nHeight) 445 { 446 ATLASSERT(::IsWindow(m_hWnd)); 447 return ::CreateCaret(m_hWnd, (HBITMAP)1, nWidth, nHeight); 448 } 449 450 BOOL CreateSolidCaret(int nWidth, int nHeight) 451 { 452 ATLASSERT(::IsWindow(m_hWnd)); 453 return ::CreateCaret(m_hWnd, (HBITMAP)0, nWidth, nHeight); 454 } 455 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 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 473 HWND Detach() 474 { 475 HWND hWnd = m_hWnd; 476 m_hWnd = NULL; 477 return hWnd; 478 } 479 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 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 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 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 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 529 void EndPaint(LPPAINTSTRUCT lpPaint) 530 { 531 ATLASSERT(::IsWindow(m_hWnd)); 532 ::EndPaint(m_hWnd, lpPaint); 533 } 534 535 BOOL FlashWindow(BOOL bInvert) 536 { 537 ATLASSERT(::IsWindow(m_hWnd)); 538 return ::FlashWindow(m_hWnd, bInvert); 539 } 540 541 BOOL GetClientRect(LPRECT lpRect) const 542 { 543 ATLASSERT(::IsWindow(m_hWnd)); 544 return ::GetClientRect(m_hWnd, lpRect); 545 } 546 547 HDC GetDC() 548 { 549 ATLASSERT(::IsWindow(m_hWnd)); 550 return ::GetDC(m_hWnd); 551 } 552 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 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: 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 587 HRESULT GetDlgControl(int nID, REFIID iid, void** ppCtrl) 588 { 589 ATLASSERT(::IsWindow(m_hWnd)); 590 return E_FAIL;//FIXME stub 591 } 592 593 int GetDlgCtrlID() const 594 { 595 ATLASSERT(::IsWindow(m_hWnd)); 596 return ::GetDlgCtrlID(m_hWnd); 597 } 598 599 HRESULT GetDlgHost(int nID, REFIID iid, void** ppHost) 600 { 601 ATLASSERT(::IsWindow(m_hWnd)); 602 return E_FAIL;//FIXME stub 603 } 604 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__ 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 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 652 DWORD GetExStyle() const 653 { 654 ATLASSERT(::IsWindow(m_hWnd)); 655 return ::GetWindowLong(m_hWnd, GWL_EXSTYLE); 656 } 657 658 HFONT GetFont() const 659 { 660 ATLASSERT(::IsWindow(m_hWnd)); 661 return (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0, 0); 662 } 663 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 676 HWND GetLastActivePopup() const 677 { 678 ATLASSERT(::IsWindow(m_hWnd)); 679 return ::GetLastActivePopup(m_hWnd); 680 } 681 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 700 CWindow GetParent() const 701 { 702 ATLASSERT(::IsWindow(m_hWnd)); 703 return CWindow(::GetParent(m_hWnd)); 704 } 705 706 BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo) 707 { 708 ATLASSERT(::IsWindow(m_hWnd)); 709 return ::GetScrollInfo(m_hWnd, nBar, lpScrollInfo); 710 } 711 712 BOOL GetScrollPos(int nBar) 713 { 714 ATLASSERT(::IsWindow(m_hWnd)); 715 return ::GetScrollPos(m_hWnd, nBar); 716 } 717 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 724 DWORD GetStyle() const 725 { 726 ATLASSERT(::IsWindow(m_hWnd)); 727 return ::GetWindowLong(m_hWnd, GWL_STYLE); 728 } 729 730 HMENU GetSystemMenu(BOOL bRevert) 731 { 732 ATLASSERT(::IsWindow(m_hWnd)); 733 return ::GetSystemMenu(m_hWnd, bRevert); 734 } 735 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 748 HWND GetTopLevelWindow() const 749 { 750 ATLASSERT(::IsWindow(m_hWnd)); 751 return NULL;//FIXME stub 752 } 753 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 772 HWND GetWindow(UINT nCmd) const 773 { 774 ATLASSERT(::IsWindow(m_hWnd)); 775 return ::GetWindow(m_hWnd, nCmd); 776 } 777 778 DWORD GetWindowContextHelpId() const 779 { 780 ATLASSERT(::IsWindow(m_hWnd)); 781 return ::GetWindowContextHelpId(m_hWnd); 782 } 783 784 HDC GetWindowDC() 785 { 786 ATLASSERT(::IsWindow(m_hWnd)); 787 return ::GetWindowDC(m_hWnd); 788 } 789 790 LONG GetWindowLong(int nIndex) const 791 { 792 ATLASSERT(::IsWindow(m_hWnd)); 793 return ::GetWindowLong(m_hWnd, nIndex); 794 } 795 796 LONG_PTR GetWindowLongPtr(int nIndex) const 797 { 798 ATLASSERT(::IsWindow(m_hWnd)); 799 return ::GetWindowLongPtr(m_hWnd, nIndex); 800 } 801 802 BOOL GetWindowPlacement(WINDOWPLACEMENT* lpwndpl) const 803 { 804 ATLASSERT(::IsWindow(m_hWnd)); 805 return ::GetWindowPlacement(m_hWnd, lpwndpl); 806 } 807 808 DWORD GetWindowProcessID() 809 { 810 ATLASSERT(::IsWindow(m_hWnd)); 811 DWORD processID; 812 ::GetWindowThreadProcessId(m_hWnd, &processID); 813 return processID; 814 } 815 816 BOOL GetWindowRect(LPRECT lpRect) const 817 { 818 ATLASSERT(::IsWindow(m_hWnd)); 819 return ::GetWindowRect(m_hWnd, lpRect); 820 } 821 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__ 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 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 860 int GetWindowTextLength() const 861 { 862 ATLASSERT(::IsWindow(m_hWnd)); 863 return ::GetWindowTextLength(m_hWnd); 864 } 865 866 DWORD GetWindowThreadID() 867 { 868 ATLASSERT(::IsWindow(m_hWnd)); 869 return ::GetWindowThreadProcessId(m_hWnd, NULL); 870 } 871 872 WORD GetWindowWord(int nIndex) const 873 { 874 ATLASSERT(::IsWindow(m_hWnd)); 875 return (WORD)::GetWindowLong(m_hWnd, nIndex); 876 } 877 878 void GotoDlgCtrl(HWND hWndCtrl) const 879 { 880 ATLASSERT(::IsWindow(m_hWnd)); 881 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0); 882 } 883 884 BOOL HideCaret() 885 { 886 ATLASSERT(::IsWindow(m_hWnd)); 887 return ::HideCaret(m_hWnd); 888 } 889 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 914 BOOL IsChild(const HWND hWnd) const 915 { 916 ATLASSERT(::IsWindow(m_hWnd)); 917 return ::IsChild(m_hWnd, hWnd); 918 } 919 920 BOOL IsDialogMessage(LPMSG lpMsg) 921 { 922 ATLASSERT(::IsWindow(m_hWnd)); 923 return ::IsDialogMessage(m_hWnd, lpMsg); 924 } 925 926 UINT IsDlgButtonChecked(int nIDButton) const 927 { 928 ATLASSERT(::IsWindow(m_hWnd)); 929 return ::IsDlgButtonChecked(m_hWnd, nIDButton); 930 } 931 932 BOOL IsIconic() const 933 { 934 ATLASSERT(::IsWindow(m_hWnd)); 935 return ::IsIconic(m_hWnd); 936 } 937 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 947 BOOL IsWindow() const 948 { 949 return ::IsWindow(m_hWnd); 950 } 951 952 BOOL IsWindowEnabled() const 953 { 954 ATLASSERT(::IsWindow(m_hWnd)); 955 return ::IsWindowEnabled(m_hWnd); 956 } 957 958 BOOL IsWindowVisible() const 959 { 960 ATLASSERT(::IsWindow(m_hWnd)); 961 return ::IsWindowVisible(m_hWnd); 962 } 963 964 BOOL IsWindowUnicode() 965 { 966 ATLASSERT(::IsWindow(m_hWnd)); 967 return ::IsWindowUnicode(m_hWnd); 968 } 969 970 BOOL IsZoomed() const 971 { 972 ATLASSERT(::IsWindow(m_hWnd)); 973 return ::IsZoomed(m_hWnd); 974 } 975 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 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 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 1032 void NextDlgCtrl() const 1033 { 1034 ATLASSERT(::IsWindow(m_hWnd)); 1035 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 0, 0); 1036 } 1037 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 1050 void PrevDlgCtrl() const 1051 { 1052 ATLASSERT(::IsWindow(m_hWnd)); 1053 ::SendMessage(m_hWnd, WM_NEXTDLGCTL, 1, 0); 1054 } 1055 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 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 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 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 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 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: 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 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 1162 HWND SetActiveWindow() 1163 { 1164 ATLASSERT(::IsWindow(m_hWnd)); 1165 return ::SetActiveWindow(m_hWnd); 1166 } 1167 1168 HWND SetCapture() 1169 { 1170 ATLASSERT(::IsWindow(m_hWnd)); 1171 return ::SetCapture(m_hWnd); 1172 } 1173 1174 HWND SetClipboardViewer() 1175 { 1176 ATLASSERT(::IsWindow(m_hWnd)); 1177 return ::SetClipboardViewer(m_hWnd); 1178 } 1179 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 1192 BOOL SetDlgItemText(int nID, LPCTSTR lpszString) 1193 { 1194 ATLASSERT(::IsWindow(m_hWnd)); 1195 return ::SetDlgItemText(m_hWnd, nID, lpszString); 1196 } 1197 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 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 1222 BOOL SetMenu(HMENU hMenu) 1223 { 1224 ATLASSERT(::IsWindow(m_hWnd)); 1225 return ::SetMenu(m_hWnd, hMenu); 1226 } 1227 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 1264 BOOL SetWindowContextHelpId(DWORD dwContextHelpId) 1265 { 1266 ATLASSERT(::IsWindow(m_hWnd)); 1267 return ::SetWindowContextHelpId(m_hWnd, dwContextHelpId); 1268 } 1269 1270 LONG SetWindowLong(int nIndex, LONG dwNewLong) 1271 { 1272 ATLASSERT(::IsWindow(m_hWnd)); 1273 return ::SetWindowLong(m_hWnd, nIndex, dwNewLong); 1274 } 1275 1276 LONG_PTR SetWindowLongPtr(int nIndex, LONG_PTR dwNewLong) 1277 { 1278 ATLASSERT(::IsWindow(m_hWnd)); 1279 return ::SetWindowLongPtr(m_hWnd, nIndex, dwNewLong); 1280 } 1281 1282 BOOL SetWindowPlacement(const WINDOWPLACEMENT* lpwndpl) 1283 { 1284 ATLASSERT(::IsWindow(m_hWnd)); 1285 return ::SetWindowPlacement(m_hWnd, lpwndpl); 1286 } 1287 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 1300 BOOL SetWindowText(LPCTSTR lpszString) 1301 { 1302 ATLASSERT(::IsWindow(m_hWnd)); 1303 return ::SetWindowText(m_hWnd, lpszString); 1304 } 1305 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 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 1333 BOOL ShowWindow(int nCmdShow) 1334 { 1335 ATLASSERT(::IsWindow(m_hWnd)); 1336 return ::ShowWindow(m_hWnd, nCmdShow); 1337 } 1338 1339 BOOL ShowWindowAsync(int nCmdShow) 1340 { 1341 ATLASSERT(::IsWindow(m_hWnd)); 1342 return ::ShowWindowAsync(m_hWnd, nCmdShow); 1343 } 1344 1345 BOOL UpdateWindow() 1346 { 1347 ATLASSERT(::IsWindow(m_hWnd)); 1348 return ::UpdateWindow(m_hWnd); 1349 } 1350 1351 BOOL ValidateRect(LPCRECT lpRect) 1352 { 1353 ATLASSERT(::IsWindow(m_hWnd)); 1354 return ::ValidateRect(m_hWnd, lpRect); 1355 } 1356 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 1383 CWindowImplRoot() 1384 : m_pCurrentMsg(NULL) 1385 , m_dwState(0) 1386 { 1387 } 1388 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 1403 virtual ~CDialogImplBaseT() 1404 { 1405 } 1406 virtual DLGPROC GetDialogProc() 1407 { 1408 return DialogProc; 1409 } 1410 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 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 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 1519 BOOL EndDialog(_In_ int nRetCode) 1520 { 1521 return ::EndDialog(m_hWnd, nRetCode); 1522 } 1523 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: 1543 CWindowImplBaseT() 1544 { 1545 m_pfnSuperWindowProc = ::DefWindowProc; 1546 } 1547 1548 virtual void OnFinalMessage(HWND /* hWnd */) 1549 { 1550 } 1551 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 1597 virtual WNDPROC GetWindowProc() 1598 { 1599 return WindowProc; 1600 } 1601 1602 static DWORD GetWndStyle(DWORD dwStyle) 1603 { 1604 return TWinTraits::GetWndStyle(dwStyle); 1605 } 1606 1607 static DWORD GetWndExStyle(DWORD dwExStyle) 1608 { 1609 return TWinTraits::GetWndExStyle(dwExStyle); 1610 } 1611 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 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 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 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 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 1791 LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) 1792 { 1793 return ::CallWindowProc(m_pfnSuperWindowProc, this->m_hWnd, uMsg, wParam, lParam); 1794 } 1795 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 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 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 2026 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