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.

552 lines
14 KiB

  1. /*
  2. * b o d y b a r. c p p
  3. *
  4. * Purpose:
  5. * Implementation of CBodyBar object. Derives from CBody to host the trident
  6. * control.
  7. *
  8. * History
  9. * February '97: erican - created
  10. *
  11. * Copyright (C) Microsoft Corp. 1995, 1996, 1997.
  12. */
  13. #include <pch.hxx>
  14. #include <wininet.h> // INTERNET_MAX_URL_LENGTH
  15. #include <resource.h>
  16. #include "strconst.h"
  17. #include "xpcomm.h"
  18. #include "bodybar.h"
  19. #include "goptions.h"
  20. #include <inpobj.h>
  21. static const TCHAR s_szBodyBarWndClass[] = TEXT("ThorBodyBarWndClass");
  22. CBodyBar::CBodyBar()
  23. {
  24. m_ptbSite = NULL;
  25. m_hwnd = NULL;
  26. m_hwndParent = NULL;
  27. m_cSize = 50;
  28. m_dwBodyBarPos = 0;
  29. m_pszURL = NULL;
  30. m_fFirstPos = TRUE;
  31. m_fDragging = FALSE;
  32. m_pMehost = NULL;
  33. m_cRef = 1;
  34. }
  35. CBodyBar::~CBodyBar()
  36. {
  37. if (m_ptbSite)
  38. m_ptbSite->Release();
  39. MemFree(m_pszURL);
  40. MemFree(m_pMehost);
  41. }
  42. HRESULT CBodyBar::HrInit(LPBOOL pfShow)
  43. {
  44. HKEY hkey;
  45. HRESULT hr = NOERROR;
  46. BOOL fShow = FALSE;
  47. if (AthUserOpenKey(NULL, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS)
  48. {
  49. TCHAR szURL[INTERNET_MAX_URL_LENGTH + 1];
  50. DWORD cbData = sizeof(szURL);
  51. szURL[0] = 0;
  52. if (RegQueryValueEx(hkey, c_szRegBodyBarPath, NULL, NULL, (LPBYTE)szURL, &cbData) == ERROR_SUCCESS && *szURL)
  53. {
  54. m_pszURL = StringDup(szURL);
  55. if (!m_pszURL)
  56. hr = E_OUTOFMEMORY;
  57. else
  58. fShow = TRUE;
  59. }
  60. RegCloseKey(hkey);
  61. }
  62. m_dwBodyBarPos = DwGetOption(OPT_BODYBARPOS);
  63. *pfShow = fShow;
  64. return hr;
  65. }
  66. ////////////////////////////////////////////////////////////////////////
  67. //
  68. // IUnknown
  69. //
  70. ////////////////////////////////////////////////////////////////////////
  71. HRESULT CBodyBar::QueryInterface(REFIID riid, LPVOID FAR *lplpObj)
  72. {
  73. HRESULT hr = S_OK;
  74. if(!lplpObj)
  75. {
  76. hr = E_INVALIDARG;
  77. goto exit;
  78. }
  79. *lplpObj = NULL;
  80. if (IsEqualIID(riid, IID_IDockingWindow))
  81. {
  82. *lplpObj = (IDockingWindow *)this;
  83. AddRef();
  84. }
  85. else if (IsEqualIID(riid, IID_IInputObject))
  86. {
  87. *lplpObj = (IInputObject *)this;
  88. AddRef();
  89. }
  90. else if (IsEqualIID(riid, IID_IObjectWithSite))
  91. {
  92. *lplpObj = (IObjectWithSite *)this;
  93. AddRef();
  94. }
  95. else if (IsEqualIID(riid, IID_IUnknown))
  96. {
  97. *lplpObj = (IDockingWindow *)this;
  98. AddRef();
  99. }
  100. else
  101. {
  102. if (m_pMehost)
  103. hr = m_pMehost->QueryInterface(riid, lplpObj);
  104. else
  105. hr = E_FAIL;
  106. }
  107. exit:
  108. return hr;
  109. }
  110. ULONG CBodyBar::AddRef()
  111. {
  112. return (++m_cRef);
  113. }
  114. ULONG CBodyBar::Release()
  115. {
  116. ULONG ulRet = 0;
  117. --m_cRef;
  118. ulRet = m_cRef;
  119. if (m_cRef == 0)
  120. {
  121. delete this;
  122. }
  123. return ulRet;
  124. }
  125. ////////////////////////////////////////////////////////////////////////
  126. //
  127. // IOleWindow
  128. //
  129. ////////////////////////////////////////////////////////////////////////
  130. HRESULT CBodyBar::GetWindow(HWND *phwnd)
  131. {
  132. HRESULT hr = E_FAIL;
  133. if (m_pMehost)
  134. hr = m_pMehost->GetWindow(phwnd);
  135. return hr;
  136. }
  137. HRESULT CBodyBar::ContextSensitiveHelp(BOOL fEnterMode)
  138. {
  139. HRESULT hr = E_FAIL;
  140. if (m_pMehost)
  141. hr = m_pMehost->ContextSensitiveHelp(fEnterMode);
  142. return hr;
  143. }
  144. ////////////////////////////////////////////////////////////////////////
  145. //
  146. // IDockingWindow
  147. //
  148. ////////////////////////////////////////////////////////////////////////
  149. HRESULT CBodyBar::ShowDW(BOOL fShow)
  150. {
  151. HRESULT hr = S_OK;
  152. // Make sure we have a site pointer first
  153. if (!m_ptbSite)
  154. {
  155. AssertSz(0, _T("CBodyBar::ShowDW() - Can't show without calling SetSite() first."));
  156. hr = E_FAIL;
  157. goto exit;
  158. }
  159. if (m_hwnd==NULL && fShow==FALSE) // noop
  160. {
  161. hr = S_OK;
  162. goto exit;
  163. }
  164. if (!m_hwnd)
  165. {
  166. WNDCLASSEX wc;
  167. wc.cbSize = sizeof(WNDCLASSEX);
  168. if (!GetClassInfoEx(g_hInst, s_szBodyBarWndClass, &wc))
  169. {
  170. // We need to register the class
  171. wc.style = 0;
  172. wc.lpfnWndProc = CBodyBar::ExtBodyBarWndProc;
  173. wc.cbClsExtra = 0;
  174. wc.cbWndExtra = 0;
  175. wc.hInstance = g_hInst;
  176. // If BodyBar is nor resizable then show standard cursor
  177. wc.hCursor = LoadCursor(NULL, IDC_SIZENS);
  178. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  179. wc.lpszMenuName = NULL;
  180. wc.lpszClassName = s_szBodyBarWndClass;
  181. wc.hIcon = NULL;
  182. wc.hIconSm = NULL;
  183. if (RegisterClassEx(&wc) == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
  184. {
  185. hr = E_FAIL;
  186. goto exit;
  187. }
  188. }
  189. // Get the handle of the parent window
  190. IF_FAILEXIT(hr = m_ptbSite->GetWindow(&m_hwndParent));
  191. // Create the window
  192. m_hwnd = CreateWindowEx(0,
  193. s_szBodyBarWndClass,
  194. NULL,
  195. WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
  196. 0,
  197. 0,
  198. 0,
  199. 0,
  200. m_hwndParent,
  201. NULL,
  202. g_hInst,
  203. (LPVOID)this);
  204. if (!m_hwnd)
  205. {
  206. AssertSz(0, _T("CBodyBar::ShowDW() - Failed to create window."));
  207. hr = E_FAIL;
  208. goto exit;
  209. }
  210. }
  211. // Show or hide the window and resize the parent windows accordingly
  212. ShowWindow(m_hwnd, fShow ? SW_SHOW : SW_HIDE);
  213. ResizeBorderDW(NULL, NULL, FALSE);
  214. m_fFirstPos = (fShow ? m_fFirstPos : TRUE);
  215. exit:
  216. return hr;
  217. }
  218. HRESULT CBodyBar::CloseDW(DWORD dwReserved)
  219. {
  220. // save BodyBar position, if BodyBar was not set from Extension
  221. SetOption(OPT_BODYBARPOS, &m_dwBodyBarPos, sizeof(m_dwBodyBarPos), NULL, 0);
  222. if (m_pMehost)
  223. {
  224. m_pMehost->HrUnloadAll(NULL, 0);
  225. m_pMehost->HrClose();
  226. }
  227. return S_OK;
  228. }
  229. HRESULT CBodyBar::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
  230. {
  231. RECT rcRequest = { 0, 0, 0, 0 };
  232. if (!m_ptbSite)
  233. {
  234. AssertSz(0, _T("CBodyBar::ResizeBorderDW() - Can't resize without calling SetSite() first."));
  235. return E_FAIL;
  236. }
  237. if (IsWindow(m_hwnd) && IsWindowVisible(m_hwnd))
  238. {
  239. RECT rcBorder;
  240. int cTop, cBottom;
  241. // Calculate position of BodyBar window
  242. cBottom = GetBodyBar_Bottom();
  243. if (!prcBorder)
  244. {
  245. // Find out how big our parent's border space is
  246. m_ptbSite->GetBorderDW((IDockingWindow*) this, &rcBorder);
  247. prcBorder = &rcBorder;
  248. }
  249. if(!m_fFirstPos || (cBottom <= 0))
  250. {
  251. rcRequest.bottom = min(m_cSize + GetSystemMetrics(SM_CYFRAME), prcBorder->bottom - prcBorder->top);
  252. cTop = prcBorder->bottom - rcRequest.bottom;
  253. cBottom = rcRequest.bottom;
  254. }
  255. else
  256. {
  257. m_cSize = cBottom; // set new value for m_cSize.
  258. cBottom += GetSystemMetrics(SM_CYFRAME);
  259. rcRequest.bottom = min(m_cSize + GetSystemMetrics(SM_CYFRAME), prcBorder->bottom - prcBorder->top);
  260. cTop = prcBorder->bottom - rcRequest.bottom;
  261. }
  262. SetWindowPos(m_hwnd, NULL, prcBorder->left, cTop,
  263. prcBorder->right - prcBorder->left, cBottom,
  264. SWP_NOACTIVATE|SWP_NOZORDER/*|SWP_DRAWFRAME*/);
  265. m_fFirstPos = FALSE; // BodyBar window positioned
  266. // Set new value for BodyBarPos
  267. m_dwBodyBarPos = (DWORD) MAKELONG(cBottom - GetSystemMetrics(SM_CYFRAME), 0);
  268. }
  269. m_ptbSite->SetBorderSpaceDW((IDockingWindow*) this, &rcRequest);
  270. return S_OK;
  271. }
  272. ////////////////////////////////////////////////////////////////////////
  273. //
  274. // IInputObject
  275. //
  276. ////////////////////////////////////////////////////////////////////////
  277. HRESULT CBodyBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
  278. {
  279. HRESULT hr = E_FAIL;
  280. if (m_pMehost)
  281. hr = m_pMehost->HrUIActivate(fActivate);
  282. return hr;
  283. }
  284. HRESULT CBodyBar::HasFocusIO(void)
  285. {
  286. HRESULT hr = E_FAIL;
  287. if (m_pMehost)
  288. hr = m_pMehost->HrHasFocus();
  289. return hr;
  290. }
  291. HRESULT CBodyBar::TranslateAcceleratorIO(LPMSG pMsg)
  292. {
  293. HRESULT hr = E_FAIL;
  294. if (m_pMehost)
  295. hr = m_pMehost->HrTranslateAccelerator(pMsg);
  296. return hr;
  297. }
  298. ////////////////////////////////////////////////////////////////////////
  299. //
  300. // IObjectWithSite
  301. //
  302. ////////////////////////////////////////////////////////////////////////
  303. HRESULT CBodyBar::SetSite(IUnknown* punkSite)
  304. {
  305. // If we already have a site pointer, release it now
  306. if (m_ptbSite)
  307. {
  308. m_ptbSite->Release();
  309. m_ptbSite = NULL;
  310. }
  311. // If the caller provided a new site interface, get the IDockingWindowSite
  312. // and keep a pointer to it.
  313. if (punkSite)
  314. {
  315. if (FAILED(punkSite->QueryInterface(IID_IDockingWindowSite, (void **)&m_ptbSite)))
  316. return E_FAIL;
  317. }
  318. return S_OK;
  319. }
  320. HRESULT CBodyBar::GetSite(REFIID riid, LPVOID *ppvSite)
  321. {
  322. return E_NOTIMPL;
  323. }
  324. ////////////////////////////////////////////////////////////////////////
  325. //
  326. // IOleInPlaceSite
  327. //
  328. ////////////////////////////////////////////////////////////////////////
  329. HRESULT CBodyBar::OnUIActivate()
  330. {
  331. HRESULT hr = E_FAIL;
  332. if (m_ptbSite)
  333. UnkOnFocusChangeIS(m_ptbSite, (IInputObject*)this, TRUE);
  334. if (m_pMehost)
  335. hr = m_pMehost->OnUIActivate();
  336. return hr;
  337. }
  338. HRESULT CBodyBar::GetDropTarget(IDropTarget * pDropTarget, IDropTarget ** ppDropTarget)
  339. {
  340. return (E_FAIL);
  341. }
  342. /////////////////////////////////////////////////////////////////////////////
  343. //
  344. // private routines
  345. //
  346. /////////////////////////////////////////////////////////////////////////////
  347. LRESULT CALLBACK CBodyBar::ExtBodyBarWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
  348. {
  349. CBodyBar *pbb;
  350. if (msg == WM_NCCREATE)
  351. {
  352. pbb = (CBodyBar *)LPCREATESTRUCT(lp)->lpCreateParams;
  353. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)pbb);
  354. }
  355. else
  356. {
  357. pbb = (CBodyBar *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  358. }
  359. Assert(pbb);
  360. return pbb->BodyBarWndProc(hwnd, msg, wp, lp);
  361. }
  362. LRESULT CBodyBar::BodyBarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  363. {
  364. switch (msg)
  365. {
  366. HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
  367. HANDLE_MSG(hwnd, WM_LBUTTONDOWN, OnLButtonDown);
  368. HANDLE_MSG(hwnd, WM_MOUSEMOVE, OnMouseMove);
  369. HANDLE_MSG(hwnd, WM_LBUTTONUP, OnLButtonUp);
  370. HANDLE_MSG(hwnd, WM_SIZE, OnSize);
  371. case WM_NCDESTROY:
  372. SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL);
  373. m_hwnd = NULL;
  374. break;
  375. case WM_SETFOCUS:
  376. {
  377. HWND hwndBody;
  378. if (m_pMehost && SUCCEEDED(m_pMehost->HrGetWindow(&hwndBody)) && hwndBody && ((HWND)wParam) != hwndBody)
  379. SetFocus(hwndBody);
  380. }
  381. return 0;
  382. }
  383. return DefWindowProc(hwnd, msg, wParam, lParam);
  384. }
  385. BOOL CBodyBar::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
  386. {
  387. BOOL fRet = FALSE;
  388. if (!m_pMehost)
  389. m_pMehost = new CMimeEditDocHost;
  390. if (!m_pMehost)
  391. goto exit;
  392. if (FAILED(m_pMehost->HrInit(hwnd, 0, NULL)))
  393. goto exit;
  394. if (FAILED(m_pMehost->HrShow(TRUE)))
  395. goto exit;
  396. if (m_pszURL)
  397. m_pMehost->HrLoadURL(m_pszURL);
  398. fRet = TRUE;
  399. exit:
  400. return fRet;
  401. }
  402. void CBodyBar::OnSize(HWND hwnd, UINT state, int cxClient, int cyClient)
  403. {
  404. RECT rc;
  405. int cyFrame = GetSystemMetrics(SM_CYFRAME);
  406. rc.left = 0;
  407. rc.top = cyFrame;
  408. rc.right = cxClient;
  409. rc.bottom = cyClient;
  410. if (m_pMehost)
  411. m_pMehost->HrSetSize(&rc);
  412. }
  413. void CBodyBar::OnLButtonDown(HWND hwnd,
  414. BOOL fDoubleClick,
  415. int x,
  416. int y,
  417. UINT keyFlags)
  418. {
  419. // Capture the mouse
  420. SetCapture(m_hwnd);
  421. // Start dragging
  422. m_fDragging = TRUE;
  423. }
  424. void CBodyBar::OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
  425. {
  426. POINT pt = {x, y};
  427. RECT rcClient;
  428. // If we're dragging, update the the window sizes
  429. if (m_fDragging)
  430. {
  431. GetClientRect(m_hwnd, &rcClient);
  432. // Make sure the tree is still a little bit visible
  433. if (rcClient.bottom - pt.y > 32)
  434. {
  435. m_cSize = rcClient.bottom - pt.y;
  436. ResizeBorderDW(0, 0, FALSE);
  437. }
  438. }
  439. }
  440. void CBodyBar::OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
  441. {
  442. if (m_fDragging)
  443. {
  444. ReleaseCapture();
  445. m_fDragging = FALSE;
  446. }
  447. }