Leaked source code of windows server 2003
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.

255 lines
6.8 KiB

  1. #include "stdafx.h"
  2. #include "WinAPI.h"
  3. #include "DwpEx.h"
  4. /***************************************************************************\
  5. *****************************************************************************
  6. *
  7. * DefWindowProcEx Extensions
  8. *
  9. *****************************************************************************
  10. \***************************************************************************/
  11. //------------------------------------------------------------------------------
  12. struct ExtraInfo
  13. {
  14. HWND hwnd; // For easy reference
  15. WNDPROC pfnOldWndProc; // Original wndproc before subclassing
  16. HWndContainer * pconOwner; // Gadget container for this window
  17. };
  18. //------------------------------------------------------------------------------
  19. ExtraInfo *
  20. RawGetExtraInfo(HWND hwnd)
  21. {
  22. return (ExtraInfo *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
  23. }
  24. LRESULT ExtraInfoWndProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam);
  25. /***************************************************************************\
  26. *
  27. * GetExtraInfo
  28. *
  29. * GetExtraInfo() returns an ExtraInfo block for a given window. If the
  30. * window does not already have an EI block, a new one is allocated, attached
  31. * to the window and subclassed.
  32. *
  33. \***************************************************************************/
  34. ExtraInfo *
  35. GetExtraInfo(HWND hwnd)
  36. {
  37. if (!ValidateHWnd(hwnd)) {
  38. return NULL;
  39. }
  40. // First, check if the info already exists
  41. ExtraInfo * pei = RawGetExtraInfo(hwnd);
  42. if (pei != NULL) {
  43. return pei;
  44. }
  45. pei = ProcessNew(ExtraInfo);
  46. if (pei != NULL) {
  47. pei->hwnd = hwnd;
  48. pei->pfnOldWndProc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
  49. pei->pconOwner = NULL;
  50. SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) pei);
  51. SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) ExtraInfoWndProc);
  52. }
  53. return pei;
  54. }
  55. /***************************************************************************\
  56. *
  57. * RemoveExtraInfo
  58. *
  59. * RemoveExtraInfo() cleans up any objects allocated in a HWND's ExtraInfo data
  60. * block.
  61. *
  62. \***************************************************************************/
  63. void
  64. RemoveExtraInfo(HWND hwnd)
  65. {
  66. if (!ValidateHWnd(hwnd)) {
  67. return;
  68. }
  69. ExtraInfo * pei = RawGetExtraInfo(hwnd);
  70. if (pei == NULL) {
  71. return;
  72. }
  73. if (pei->pconOwner != NULL) {
  74. pei->pconOwner->xwUnlock();
  75. }
  76. SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR) pei->pfnOldWndProc);
  77. SetWindowLongPtrW(hwnd, GWLP_USERDATA, NULL);
  78. ProcessDelete(ExtraInfo, pei);
  79. }
  80. //---------------------------------------------------------------------------
  81. void
  82. DestroyContainer(ExtraInfo * pei)
  83. {
  84. if (pei->pconOwner != NULL) {
  85. pei->pconOwner->xwUnlock();
  86. pei->pconOwner = NULL;
  87. }
  88. }
  89. /***************************************************************************\
  90. *
  91. * ExtraInfoWndProc
  92. *
  93. * ExtraInfoWndProc() provides a TEMPORARY mechanism of adding ExtraInfo into
  94. * an HWND. Eventually, this should be moved into DefWindowProc().
  95. *
  96. \***************************************************************************/
  97. LRESULT
  98. ExtraInfoWndProc(HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  99. {
  100. //
  101. // Check if the window has ExtraInfo (without allocating any if it
  102. // doesn't). If we don't "own" it, just pass on to DefWindowProc().
  103. //
  104. ExtraInfo * pei = RawGetExtraInfo(hwnd);
  105. if (pei == NULL) {
  106. return DefWindowProc(hwnd, nMsg, wParam, lParam);
  107. }
  108. //
  109. // This window has ExtraInfo, so handle as necessary.
  110. //
  111. // Also, grab any info that we will need to call the original windowproc
  112. // later.
  113. //
  114. WNDPROC pfnOldWndProc = pei->pfnOldWndProc;
  115. switch (nMsg)
  116. {
  117. case WM_NCDESTROY:
  118. //
  119. // This is the last message that we will get, so need to clean-up now.
  120. // We need to be very careful since we will detatch ourself from the
  121. // window.
  122. //
  123. RemoveExtraInfo(hwnd);
  124. break;
  125. default:
  126. if (pei->pconOwner != NULL) {
  127. LRESULT r;
  128. if (pei->pconOwner->xdHandleMessage(nMsg, wParam, lParam, &r, 0)) {
  129. return r;
  130. }
  131. }
  132. }
  133. return CallWindowProc(pfnOldWndProc, hwnd, nMsg, wParam, lParam);
  134. }
  135. //**************************************************************************************************
  136. //
  137. // Public Functions
  138. //
  139. //**************************************************************************************************
  140. /***************************************************************************\
  141. *
  142. * GdGetContainer (Public)
  143. *
  144. * GdGetContainer() returns the associated Gadget Container for a given
  145. * window. If the window does not yet have a gadget container, NULL is
  146. * returned.
  147. *
  148. \***************************************************************************/
  149. HWndContainer *
  150. GdGetContainer(HWND hwnd)
  151. {
  152. ExtraInfo * pei = RawGetExtraInfo(hwnd);
  153. if (pei == NULL) {
  154. return NULL;
  155. }
  156. return pei->pconOwner;
  157. }
  158. /***************************************************************************\
  159. *
  160. * GdCreateHwndRootGadget (Public)
  161. *
  162. * GdCreateHwndRootGadget() creates a new RootGadget for an existing HWND. If
  163. * the HWND already has a gadget or container, this function will destroy
  164. * the previous container and gadget and create new instances.
  165. *
  166. \***************************************************************************/
  167. HRESULT
  168. GdCreateHwndRootGadget(
  169. IN HWND hwndContainer, // Window to be hosted inside
  170. IN CREATE_INFO * pci, // Creation information
  171. OUT DuRootGadget ** ppgadNew) // New Gadget
  172. {
  173. HRESULT hr;
  174. ExtraInfo * pei = GetExtraInfo(hwndContainer);
  175. if (pei == NULL) {
  176. return NULL;
  177. }
  178. DestroyContainer(pei);
  179. //
  180. // Build a new container and top gadget
  181. //
  182. HWndContainer * pconNew;
  183. hr = HWndContainer::Build(pei->hwnd, &pconNew);
  184. if (FAILED(hr)) {
  185. return hr;
  186. }
  187. DuRootGadget * pgadNew;
  188. hr = DuRootGadget::Build(pconNew, FALSE, pci, &pgadNew);
  189. if (FAILED(hr)) {
  190. pconNew->xwUnlock();
  191. return hr;
  192. }
  193. pgadNew->SetFill(GetStdColorBrushI(SC_White));
  194. pei->pconOwner = pconNew;
  195. *ppgadNew = pgadNew;
  196. return S_OK;
  197. }
  198. //------------------------------------------------------------------------------
  199. BOOL
  200. GdForwardMessage(DuVisual * pgadRoot, UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT * pr)
  201. {
  202. DuContainer * pcon = pgadRoot->GetContainer();
  203. return pcon->xdHandleMessage(nMsg, wParam, lParam, pr, DuContainer::mfForward);
  204. }