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.

362 lines
9.5 KiB

  1. #include "stdafx.h"
  2. #include "Lava.h"
  3. #include "NcContainer.h"
  4. #include "MsgHelp.h"
  5. /***************************************************************************\
  6. *****************************************************************************
  7. *
  8. * API Implementation
  9. *
  10. *****************************************************************************
  11. \***************************************************************************/
  12. //------------------------------------------------------------------------------
  13. NcContainer *
  14. GetNcContainer(DuVisual * pgad)
  15. {
  16. DuContainer * pcon = pgad->GetContainer();
  17. AssertReadPtr(pcon);
  18. NcContainer * pconHWND = CastNcContainer(pcon);
  19. return pconHWND;
  20. }
  21. /***************************************************************************\
  22. *
  23. * GdCreateNcRootGadget (Public)
  24. *
  25. * GdCreateNcRootGadget() creates a new RootGadget for an existing HWND's
  26. * non-client area.
  27. *
  28. \***************************************************************************/
  29. HRESULT
  30. GdCreateNcRootGadget(
  31. IN HWND hwndContainer, // Window to be hosted inside
  32. IN CREATE_INFO * pci, // Creation information
  33. OUT DuRootGadget ** ppgadNew) // New Root Gadget
  34. {
  35. HRESULT hr;
  36. //
  37. // Build a new container and top gadget
  38. //
  39. NcContainer * pconNew;
  40. hr = NcContainer::Build(hwndContainer, &pconNew);
  41. if (FAILED(hr)) {
  42. return hr;
  43. }
  44. hr = DuRootGadget::Build(pconNew, FALSE, pci, ppgadNew);
  45. if (FAILED(hr)) {
  46. pconNew->xwUnlock();
  47. return hr;
  48. }
  49. //
  50. // Don't setup an initial brush when using Non-Client
  51. //
  52. return S_OK;
  53. }
  54. /***************************************************************************\
  55. *****************************************************************************
  56. *
  57. * class NcContainer
  58. *
  59. *****************************************************************************
  60. \***************************************************************************/
  61. //------------------------------------------------------------------------------
  62. NcContainer::NcContainer()
  63. {
  64. m_hwndOwner = NULL;
  65. }
  66. //------------------------------------------------------------------------------
  67. NcContainer::~NcContainer()
  68. {
  69. //
  70. // Need to destroy the gadget tree before this class is destructed since
  71. // it may need to make calls to the container during its destruction. If
  72. // we don't do this here, it may end up calling pure-virtual's on the base
  73. // class.
  74. //
  75. xwDestroyGadget();
  76. }
  77. //------------------------------------------------------------------------------
  78. HRESULT
  79. NcContainer::Build(HWND hwnd, NcContainer ** ppconNew)
  80. {
  81. // Check parameters
  82. if (!ValidateHWnd(hwnd)) {
  83. return E_INVALIDARG;
  84. }
  85. // Create a new container
  86. NcContainer * pconNew = ClientNew(NcContainer);
  87. if (pconNew == NULL) {
  88. return E_OUTOFMEMORY;
  89. }
  90. pconNew->m_hwndOwner = hwnd;
  91. RECT rcWin;
  92. GetWindowRect(hwnd, &rcWin);
  93. pconNew->m_sizePxl.cx = rcWin.right - rcWin.left;
  94. pconNew->m_sizePxl.cy = rcWin.bottom - rcWin.top;
  95. *ppconNew = pconNew;
  96. return S_OK;
  97. }
  98. //------------------------------------------------------------------------------
  99. void
  100. NcContainer::OnInvalidate(const RECT * prcInvalidContainerPxl)
  101. {
  102. UNREFERENCED_PARAMETER(prcInvalidContainerPxl);
  103. }
  104. //------------------------------------------------------------------------------
  105. void
  106. NcContainer::OnGetRect(RECT * prcDesktopPxl)
  107. {
  108. GetWindowRect(m_hwndOwner, prcDesktopPxl);
  109. }
  110. //------------------------------------------------------------------------------
  111. void
  112. NcContainer::OnStartCapture()
  113. {
  114. }
  115. //------------------------------------------------------------------------------
  116. void
  117. NcContainer::OnEndCapture()
  118. {
  119. }
  120. //------------------------------------------------------------------------------
  121. BOOL
  122. NcContainer::OnTrackMouseLeave()
  123. {
  124. return FALSE;
  125. }
  126. //------------------------------------------------------------------------------
  127. void
  128. NcContainer::OnSetFocus()
  129. {
  130. if (GetFocus() != m_hwndOwner) {
  131. //
  132. // Setting focus is a little more complicated than pure HWND's. This is
  133. // because Gadgets greatly simplify several things
  134. //
  135. // 1. SetFocus
  136. // 2. Setup caret, if any
  137. //
  138. Trace("NcContainer::OnSetFocus()\n");
  139. SetFocus(m_hwndOwner);
  140. }
  141. }
  142. //------------------------------------------------------------------------------
  143. void
  144. NcContainer::OnRescanMouse(POINT * pptContainerPxl)
  145. {
  146. // Trace("%p OnRescanMouse\n", GetTickCount());
  147. POINT ptCursor;
  148. if (!GetCursorPos(&ptCursor)) {
  149. ptCursor.x = -20000;
  150. ptCursor.y = -20000;
  151. }
  152. ScreenToClient(m_hwndOwner, &ptCursor);
  153. *pptContainerPxl = ptCursor;
  154. }
  155. //------------------------------------------------------------------------------
  156. BOOL
  157. NcContainer::xdHandleMessage(UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT * pr, UINT nMsgFlags)
  158. {
  159. UNREFERENCED_PARAMETER(nMsgFlags);
  160. if (m_pgadRoot == NULL) {
  161. return FALSE; // If don't have a root, there is nothing to handle.
  162. }
  163. POINT ptContainerPxl;
  164. *pr = 0;
  165. Trace("NcContainer::HandleMessage: msg: 0x%x\n", nMsg);
  166. switch (nMsg)
  167. {
  168. case WM_NCLBUTTONDOWN:
  169. case WM_NCRBUTTONDOWN:
  170. case WM_NCMBUTTONDOWN:
  171. case WM_NCLBUTTONDBLCLK:
  172. case WM_NCRBUTTONDBLCLK:
  173. case WM_NCMBUTTONDBLCLK:
  174. case WM_NCLBUTTONUP:
  175. case WM_NCRBUTTONUP:
  176. case WM_NCMBUTTONUP:
  177. ptContainerPxl.x = GET_X_LPARAM(lParam);
  178. ptContainerPxl.y = GET_Y_LPARAM(lParam);
  179. if ((GetCapture() == m_hwndOwner) &&
  180. (ChildWindowFromPointEx(m_hwndOwner, ptContainerPxl, CWP_SKIPINVISIBLE) != m_hwndOwner)) {
  181. ReleaseCapture();
  182. }
  183. {
  184. GMSG_MOUSECLICK msg;
  185. nMsg += WM_LBUTTONDOWN - WM_NCLBUTTONDOWN;
  186. GdConvertMouseClickMessage(&msg, nMsg, wParam);
  187. ContextLock cl;
  188. if (cl.LockNL(ContextLock::edDefer)) {
  189. return m_pgadRoot->xdHandleMouseMessage(&msg, ptContainerPxl);
  190. }
  191. break;
  192. }
  193. case WM_NCMOUSEMOVE:
  194. ptContainerPxl.x = GET_X_LPARAM(lParam);
  195. ptContainerPxl.y = GET_Y_LPARAM(lParam);
  196. if ((GetCapture() == m_hwndOwner) &&
  197. (ChildWindowFromPointEx(m_hwndOwner, ptContainerPxl, CWP_SKIPINVISIBLE) != m_hwndOwner)) {
  198. ReleaseCapture();
  199. }
  200. {
  201. GMSG_MOUSE msg;
  202. nMsg += WM_LBUTTONDOWN - WM_NCLBUTTONDOWN;
  203. GdConvertMouseMessage(&msg, nMsg, wParam);
  204. ContextLock cl;
  205. if (cl.LockNL(ContextLock::edDefer)) {
  206. return m_pgadRoot->xdHandleMouseMessage(&msg, ptContainerPxl);
  207. }
  208. break;
  209. }
  210. case WM_CAPTURECHANGED:
  211. if (m_hwndOwner != (HWND) lParam) {
  212. ContextLock cl;
  213. if (cl.LockNL(ContextLock::edDefer)) {
  214. m_pgadRoot->xdHandleMouseLostCapture();
  215. }
  216. }
  217. break;
  218. case WM_SETFOCUS:
  219. {
  220. ContextLock cl;
  221. if (cl.LockNL(ContextLock::edDefer)) {
  222. return m_pgadRoot->xdHandleKeyboardFocus(GSC_SET);
  223. }
  224. break;
  225. }
  226. case WM_KILLFOCUS:
  227. {
  228. ContextLock cl;
  229. if (cl.LockNL(ContextLock::edDefer)) {
  230. return m_pgadRoot->xdHandleKeyboardFocus(GSC_LOST);
  231. }
  232. break;
  233. }
  234. case WM_CHAR:
  235. case WM_KEYDOWN:
  236. case WM_KEYUP:
  237. case WM_SYSCHAR:
  238. case WM_SYSKEYDOWN:
  239. case WM_SYSKEYUP:
  240. {
  241. Trace("NcContainer::xdHandleMessage(Keyboard=0x%x)\n", nMsg);
  242. }
  243. break;
  244. case WM_NCACTIVATE:
  245. {
  246. ContextLock cl;
  247. if (cl.LockNL(ContextLock::edDefer)) {
  248. m_pgadRoot->xdHandleActivate(wParam ? GSC_LOST : GSC_SET);
  249. }
  250. break;
  251. }
  252. // Fall through to WM_NCPAINT
  253. case WM_NCPAINT:
  254. if ((!m_fManualDraw) && (m_pgadRoot != NULL)) {
  255. // HDC hdc = GetDCEx(m_hwndOwner, (HRGN) wParam, DCX_WINDOW | DCX_INTERSECTRGN);
  256. HDC hdc = GetWindowDC(m_hwndOwner);
  257. RECT rcInvalid;
  258. {
  259. ContextLock cl;
  260. if (cl.LockNL(ContextLock::edNone)) {
  261. m_pgadRoot->GetLogRect(&rcInvalid, SGR_CLIENT);
  262. m_pgadRoot->xrDrawTree(NULL, hdc, &rcInvalid, 0);
  263. }
  264. }
  265. ReleaseDC(m_hwndOwner, hdc);
  266. return TRUE;
  267. }
  268. break;
  269. case WM_WINDOWPOSCHANGED:
  270. {
  271. WINDOWPOS * pwp = (WINDOWPOS *) lParam;
  272. if (!TestFlag(pwp->flags, SWP_NOSIZE)) {
  273. RECT rcWin;
  274. GetWindowRect(m_hwndOwner, &rcWin);
  275. ContextLock cl;
  276. if (cl.LockNL(ContextLock::edDefer)) {
  277. VerifyHR(m_pgadRoot->xdSetLogRect(0, 0, rcWin.right - rcWin.left, rcWin.bottom - rcWin.top, SGR_SIZE));
  278. }
  279. break;
  280. }
  281. }
  282. break;
  283. case WM_GETROOTGADGET:
  284. if (m_pgadRoot != NULL) {
  285. *pr = (LRESULT) m_pgadRoot->GetHandle();
  286. return TRUE;
  287. }
  288. break;
  289. }
  290. return FALSE;
  291. }