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