Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.5 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: w32utils.inl
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: LazarI
  10. *
  11. * DATE: 23-Dec-2000
  12. *
  13. * DESCRIPTION: Win32 templates & utilities (Impl.)
  14. *
  15. *****************************************************************************/
  16. ////////////////////////////////////////////////
  17. //
  18. // class CSimpleWndSubclass
  19. //
  20. // class implementing simple window subclassing
  21. // (Windows specific classes)
  22. //
  23. template <class inheritorClass>
  24. inline BOOL CSimpleWndSubclass<inheritorClass>::IsAttached() const
  25. {
  26. return (NULL != m_hwnd);
  27. }
  28. template <class inheritorClass>
  29. BOOL CSimpleWndSubclass<inheritorClass>::Attach(HWND hwnd)
  30. {
  31. if( hwnd )
  32. {
  33. // make sure we are not attached and nobody is using
  34. // GWLP_USERDATA for something else already.
  35. ASSERT(NULL == m_hwnd);
  36. ASSERT(NULL == m_wndDefProc);
  37. ASSERT(NULL == GetWindowLongPtr(hwnd, GWLP_USERDATA));
  38. // attach to this window
  39. m_hwnd = hwnd;
  40. m_wndDefProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(m_hwnd, GWLP_WNDPROC));
  41. // thunk the window proc
  42. SetWindowLongPtr(m_hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
  43. SetWindowLongPtr(m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(_ThunkWndProc));
  44. return TRUE;
  45. }
  46. return FALSE;
  47. }
  48. template <class inheritorClass>
  49. BOOL CSimpleWndSubclass<inheritorClass>::Detach()
  50. {
  51. if( m_hwnd )
  52. {
  53. // unthunk the window proc
  54. SetWindowLongPtr(m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_wndDefProc));
  55. SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
  56. // clear out our data
  57. m_wndDefProc = NULL;
  58. m_hwnd = NULL;
  59. return TRUE;
  60. }
  61. return FALSE;
  62. }
  63. template <class inheritorClass>
  64. LRESULT CALLBACK CSimpleWndSubclass<inheritorClass>::_ThunkWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  65. {
  66. // get the pThis ptr from GWLP_USERDATA
  67. CSimpleWndSubclass<inheritorClass> *pThis =
  68. reinterpret_cast<CSimpleWndSubclass<inheritorClass>*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
  69. // must be attached
  70. ASSERT(pThis->IsAttached());
  71. // static cast pThis to inheritorClass
  72. inheritorClass *pTarget = static_cast<inheritorClass*>(pThis);
  73. // messsage processing is here
  74. if( WM_NCDESTROY == uMsg )
  75. {
  76. // this window is about to go away - detach.
  77. LRESULT lResult = pTarget->WindowProc(hwnd, uMsg, wParam, lParam);
  78. pThis->Detach();
  79. return lResult;
  80. }
  81. else
  82. {
  83. // invoke the inheritorClass WindowProc (should be defined)
  84. return pTarget->WindowProc(hwnd, uMsg, wParam, lParam);
  85. }
  86. }
  87. template <class inheritorClass>
  88. inline LRESULT CSimpleWndSubclass<inheritorClass>::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  89. {
  90. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  91. }
  92. template <class inheritorClass>
  93. inline LRESULT CSimpleWndSubclass<inheritorClass>::DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  94. {
  95. if( m_wndDefProc )
  96. {
  97. return CallWindowProc(m_wndDefProc, hwnd, uMsg, wParam, lParam);
  98. }
  99. return ::DefWindowProc(hwnd, uMsg, wParam, lParam);
  100. }
  101. template <class inheritorClass>
  102. inline LRESULT CSimpleWndSubclass<inheritorClass>::DefDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  103. {
  104. if( m_wndDefProc )
  105. {
  106. return CallWindowProc(m_wndDefProc, hwnd, uMsg, wParam, lParam);
  107. }
  108. return ::DefDlgProc(hwnd, uMsg, wParam, lParam);
  109. }