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