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.

636 lines
15 KiB

  1. /*
  2. * a d b a r. c p p
  3. *
  4. * Purpose:
  5. * Implementation of CAdBar object. Derives from CBody to host the trident
  6. * control.
  7. *
  8. * History
  9. * May '99: shaheedp - created
  10. *
  11. * Copyright (C) Microsoft Corp. 1995, 1996, 1997, 1998, 1999.
  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 "adbar.h"
  19. #include "goptions.h"
  20. #include <inpobj.h>
  21. static const TCHAR s_szAdBarWndClass[] = TEXT("ThorAdBarWndClass");
  22. CAdBar::CAdBar()
  23. {
  24. m_ptbSite = NULL;
  25. m_hwnd = NULL;
  26. m_hwndParent = NULL;
  27. m_cSize = 65;
  28. m_dwAdBarPos = 0;
  29. m_pszUrl = NULL;
  30. m_fFirstPos = TRUE;
  31. m_fDragging = FALSE;
  32. m_cRef = 1;
  33. m_pMehost = NULL;
  34. }
  35. CAdBar::~CAdBar()
  36. {
  37. if (m_ptbSite)
  38. m_ptbSite->Release();
  39. MemFree(m_pszUrl);
  40. if(m_pMehost)
  41. delete m_pMehost;
  42. }
  43. HRESULT CAdBar::HrInit(BSTR bstr)
  44. {
  45. HRESULT hr = S_OK;
  46. IF_FAILEXIT(hr = HrBSTRToLPSZ(CP_ACP, bstr, &m_pszUrl));
  47. exit:
  48. return hr;
  49. }
  50. ////////////////////////////////////////////////////////////////////////
  51. //
  52. // IUnknown
  53. //
  54. ////////////////////////////////////////////////////////////////////////
  55. HRESULT CAdBar::QueryInterface(REFIID riid, LPVOID FAR *lplpObj)
  56. {
  57. HRESULT hr = S_OK;
  58. if(!lplpObj)
  59. {
  60. hr = E_INVALIDARG;
  61. goto exit;
  62. }
  63. *lplpObj = NULL;
  64. if (IsEqualIID(riid, IID_IDockingWindow))
  65. {
  66. *lplpObj = (IDockingWindow *)this;
  67. AddRef();
  68. }
  69. else if (IsEqualIID(riid, IID_IInputObject))
  70. {
  71. *lplpObj = (IInputObject *)this;
  72. AddRef();
  73. }
  74. else if (IsEqualIID(riid, IID_IObjectWithSite))
  75. {
  76. *lplpObj = (IObjectWithSite *)this;
  77. AddRef();
  78. }
  79. else if (IsEqualIID(riid, IID_IUnknown))
  80. {
  81. *lplpObj = (IDockingWindow *)this;
  82. AddRef();
  83. }
  84. else
  85. {
  86. if (m_pMehost)
  87. {
  88. hr = m_pMehost->QueryInterface(riid, lplpObj);
  89. }
  90. else
  91. {
  92. hr = E_FAIL;
  93. }
  94. }
  95. exit:
  96. return hr;
  97. }
  98. ULONG CAdBar::AddRef()
  99. {
  100. return (++m_cRef);
  101. }
  102. ULONG CAdBar::Release()
  103. {
  104. ULONG ulRet = 0;
  105. --m_cRef;
  106. ulRet = m_cRef;
  107. if (m_cRef == 0)
  108. {
  109. delete this;
  110. }
  111. return ulRet;
  112. }
  113. ////////////////////////////////////////////////////////////////////////
  114. //
  115. // IOleWindow
  116. //
  117. ////////////////////////////////////////////////////////////////////////
  118. HRESULT CAdBar::GetWindow(HWND *phwnd)
  119. {
  120. HRESULT hr = E_FAIL;
  121. if (m_pMehost)
  122. hr = m_pMehost->GetWindow(phwnd);
  123. return hr;
  124. }
  125. HRESULT CAdBar::ContextSensitiveHelp(BOOL fEnterMode)
  126. {
  127. HRESULT hr = E_FAIL;
  128. if (m_pMehost)
  129. hr = m_pMehost->ContextSensitiveHelp(fEnterMode);
  130. return hr;
  131. }
  132. ////////////////////////////////////////////////////////////////////////
  133. //
  134. // IDockingWindow
  135. //
  136. ////////////////////////////////////////////////////////////////////////
  137. HRESULT CAdBar::ShowDW(BOOL fShow)
  138. {
  139. // Make sure we have a site pointer first
  140. if (!m_ptbSite)
  141. {
  142. AssertSz(0, _T("CAdBar::ShowDW() - Can't show without calling SetSite() first."));
  143. return E_FAIL;
  144. }
  145. if (m_hwnd==NULL && fShow==FALSE) // noop
  146. return S_OK;
  147. if (!m_hwnd)
  148. {
  149. WNDCLASSEX wc;
  150. wc.cbSize = sizeof(WNDCLASSEX);
  151. if (!GetClassInfoEx(g_hInst, s_szAdBarWndClass, &wc))
  152. {
  153. // We need to register the class
  154. wc.style = 0;
  155. wc.lpfnWndProc = CAdBar::ExtAdBarWndProc;
  156. wc.cbClsExtra = 0;
  157. wc.cbWndExtra = 0;
  158. wc.hInstance = g_hInst;
  159. // If AdBar is nor resizable then show standard cursor
  160. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  161. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  162. wc.lpszMenuName = NULL;
  163. wc.lpszClassName = s_szAdBarWndClass;
  164. wc.hIcon = NULL;
  165. wc.hIconSm = NULL;
  166. if (RegisterClassEx(&wc) == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
  167. return E_FAIL;
  168. }
  169. // Get the handle of the parent window
  170. if (FAILED(m_ptbSite->GetWindow(&m_hwndParent)))
  171. return E_FAIL;
  172. // Create the window
  173. m_hwnd = CreateWindowEx(0,
  174. s_szAdBarWndClass,
  175. NULL,
  176. WS_VISIBLE|WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
  177. 0,
  178. 0,
  179. 0,
  180. 0,
  181. m_hwndParent,
  182. NULL,
  183. g_hInst,
  184. (LPVOID)this);
  185. if (!m_hwnd)
  186. {
  187. AssertSz(0, _T("CAdBar::ShowDW() - Failed to create window."));
  188. return E_FAIL;
  189. }
  190. }
  191. // Show or hide the window and resize the parent windows accordingly
  192. ShowWindow(m_hwnd, fShow ? SW_SHOW : SW_HIDE);
  193. ResizeBorderDW(NULL, NULL, FALSE);
  194. m_fFirstPos = (fShow ? m_fFirstPos : TRUE);
  195. return S_OK;
  196. }
  197. HRESULT CAdBar::CloseDW(DWORD dwReserved)
  198. {
  199. if (m_pMehost)
  200. {
  201. m_pMehost->HrUnloadAll(NULL, 0);
  202. m_pMehost->HrClose();
  203. }
  204. return S_OK;
  205. }
  206. HRESULT CAdBar::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
  207. {
  208. RECT rcRequest = { 0, 0, 0, 0 };
  209. if (!m_ptbSite)
  210. {
  211. AssertSz(0, _T("CAdBar::ResizeBorderDW() - Can't resize without calling SetSite() first."));
  212. return E_FAIL;
  213. }
  214. if (IsWindow(m_hwnd) && IsWindowVisible(m_hwnd))
  215. {
  216. RECT rcBorder;
  217. int cTop, cBottom;
  218. // Calculate position of AdBar window
  219. cBottom = GetAdBar_Bottom();
  220. if (!prcBorder)
  221. {
  222. // Find out how big our parent's border space is
  223. m_ptbSite->GetBorderDW((IDockingWindow*) this, &rcBorder);
  224. prcBorder = &rcBorder;
  225. }
  226. if(!m_fFirstPos || (cBottom <= 0))
  227. {
  228. rcRequest.bottom = min(m_cSize + GetSystemMetrics(SM_CYFRAME), prcBorder->bottom - prcBorder->top);
  229. cTop = prcBorder->bottom - rcRequest.bottom;
  230. cBottom = rcRequest.bottom;
  231. }
  232. else
  233. {
  234. m_cSize = cBottom; // set new value for m_cSize.
  235. cBottom += GetSystemMetrics(SM_CYFRAME);
  236. rcRequest.bottom = min(m_cSize + GetSystemMetrics(SM_CYFRAME), prcBorder->bottom - prcBorder->top);
  237. cTop = prcBorder->bottom - rcRequest.bottom;
  238. }
  239. SetWindowPos(m_hwnd, NULL, prcBorder->left, cTop,
  240. prcBorder->right - prcBorder->left, cBottom,
  241. SWP_NOACTIVATE|SWP_NOZORDER);
  242. m_fFirstPos = FALSE; // AdBar window positioned
  243. // Set new value for AdBarPos
  244. m_dwAdBarPos = (DWORD) MAKELONG(cBottom - GetSystemMetrics(SM_CYFRAME), 0);
  245. }
  246. m_ptbSite->SetBorderSpaceDW((IDockingWindow*) this, &rcRequest);
  247. return S_OK;
  248. }
  249. ////////////////////////////////////////////////////////////////////////
  250. //
  251. // IInputObject
  252. //
  253. ////////////////////////////////////////////////////////////////////////
  254. HRESULT CAdBar::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
  255. {
  256. HRESULT hr = E_FAIL;
  257. if (m_pMehost)
  258. hr = m_pMehost->HrUIActivate(fActivate);
  259. return hr;
  260. }
  261. HRESULT CAdBar::HasFocusIO(void)
  262. {
  263. HRESULT hr = E_FAIL;
  264. if (m_pMehost)
  265. hr = m_pMehost->HrHasFocus();
  266. return hr;
  267. }
  268. HRESULT CAdBar::TranslateAcceleratorIO(LPMSG pMsg)
  269. {
  270. HRESULT hr = E_FAIL;
  271. if (m_pMehost)
  272. hr = m_pMehost->HrTranslateAccelerator(pMsg);
  273. return hr;
  274. }
  275. ////////////////////////////////////////////////////////////////////////
  276. //
  277. // IObjectWithSite
  278. //
  279. ////////////////////////////////////////////////////////////////////////
  280. HRESULT CAdBar::SetSite(IUnknown* punkSite)
  281. {
  282. // If we already have a site pointer, release it now
  283. if (m_ptbSite)
  284. {
  285. m_ptbSite->Release();
  286. m_ptbSite = NULL;
  287. }
  288. // If the caller provided a new site interface, get the IDockingWindowSite
  289. // and keep a pointer to it.
  290. if (punkSite)
  291. {
  292. if (FAILED(punkSite->QueryInterface(IID_IDockingWindowSite, (void **)&m_ptbSite)))
  293. return E_FAIL;
  294. }
  295. return S_OK;
  296. }
  297. HRESULT CAdBar::GetSite(REFIID riid, LPVOID *ppvSite)
  298. {
  299. return E_NOTIMPL;
  300. }
  301. ////////////////////////////////////////////////////////////////////////
  302. //
  303. // IOleInPlaceSite
  304. //
  305. ////////////////////////////////////////////////////////////////////////
  306. HRESULT CAdBar::OnUIActivate()
  307. {
  308. HRESULT hr = E_FAIL;
  309. if (m_ptbSite)
  310. UnkOnFocusChangeIS(m_ptbSite, (IInputObject*)this, TRUE);
  311. if (m_pMehost)
  312. hr = m_pMehost->OnUIActivate();
  313. return hr;
  314. }
  315. HRESULT CAdBar::GetDropTarget(IDropTarget * pDropTarget, IDropTarget ** ppDropTarget)
  316. {
  317. return (E_FAIL);
  318. }
  319. /////////////////////////////////////////////////////////////////////////////
  320. //
  321. // private routines
  322. //
  323. /////////////////////////////////////////////////////////////////////////////
  324. LRESULT CALLBACK CAdBar::ExtAdBarWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
  325. {
  326. CAdBar *pbb;
  327. if (msg == WM_NCCREATE)
  328. {
  329. pbb = (CAdBar *)LPCREATESTRUCT(lp)->lpCreateParams;
  330. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LPARAM)pbb);
  331. }
  332. else
  333. {
  334. pbb = (CAdBar *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  335. }
  336. Assert(pbb);
  337. return pbb->AdBarWndProc(hwnd, msg, wp, lp);
  338. }
  339. LRESULT CAdBar::AdBarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  340. {
  341. switch (msg)
  342. {
  343. HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
  344. HANDLE_MSG(hwnd, WM_SIZE, OnSize);
  345. case WM_NCDESTROY:
  346. SetWindowLongPtr(hwnd, GWLP_USERDATA, NULL);
  347. m_hwnd = NULL;
  348. break;
  349. case WM_SETFOCUS:
  350. {
  351. HWND hwndBody;
  352. if (m_pMehost && SUCCEEDED(m_pMehost->HrGetWindow(&hwndBody)) && hwndBody && ((HWND)wParam) != hwndBody)
  353. SetFocus(hwndBody);
  354. }
  355. return 0;
  356. }
  357. return DefWindowProc(hwnd, msg, wParam, lParam);
  358. }
  359. BOOL CAdBar::OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
  360. {
  361. BOOL fRet = FALSE;
  362. if (!m_pMehost)
  363. m_pMehost = new CMimeEditDocHost;
  364. if (!m_pMehost)
  365. goto exit;
  366. if (FAILED(m_pMehost->HrInit(hwnd, 0, NULL)))
  367. goto exit;
  368. // We don't care if this fails.
  369. // TraceResult(m_pMehost->HrEnableScrollBars(FALSE));
  370. if (FAILED(m_pMehost->HrShow(TRUE)))
  371. goto exit;
  372. if (m_pszUrl)
  373. m_pMehost->HrLoadURL(m_pszUrl);
  374. fRet = TRUE;
  375. exit:
  376. return fRet;
  377. }
  378. void CAdBar::OnSize(HWND hwnd, UINT state, int cxClient, int cyClient)
  379. {
  380. RECT rc;
  381. int cyFrame = GetSystemMetrics(SM_CYFRAME);
  382. rc.left = 0;
  383. rc.top = cyFrame;
  384. rc.right = cxClient;
  385. rc.bottom = cyClient;
  386. if (m_pMehost)
  387. m_pMehost->HrSetSize(&rc);
  388. }
  389. HRESULT CAdBar::SetUrl(LPSTR pszUrl)
  390. {
  391. HRESULT hr = S_OK;
  392. LPSTR pszUrlBackup = m_pszUrl;
  393. if (pszUrl && *pszUrl)
  394. {
  395. IF_NULLEXIT(m_pszUrl = PszDupA(pszUrl));
  396. if (m_pMehost)
  397. IF_FAILEXIT(hr = m_pMehost->HrLoadURL(m_pszUrl));
  398. }
  399. else
  400. hr = E_INVALIDARG;
  401. exit:
  402. if (FAILED(hr))
  403. {
  404. m_pszUrl = pszUrlBackup;
  405. }
  406. else
  407. {
  408. MemFree(pszUrlBackup);
  409. }
  410. return hr;
  411. }
  412. BOOL CAdBar::fValidUrl()
  413. {
  414. BOOL fRet = FALSE;
  415. if (m_pszUrl && *m_pszUrl)
  416. fRet = TRUE;
  417. return fRet;
  418. }
  419. HRESULT HrProcessAdTokens(LPSTR pszAdInfo, LPCSTR pszToken,
  420. LPSTR pszretval, DWORD cch,
  421. DWORD *pcchCount)
  422. {
  423. LPSTR lpSubString = NULL;
  424. LPSTR lpSubString1 = NULL;
  425. HRESULT hr = S_OK;
  426. DWORD dwCount = 0;
  427. *pszretval = 0;
  428. lpSubString = StrStr(pszAdInfo, pszToken);
  429. if (!lpSubString)
  430. IF_FAILEXIT(hr = E_FAIL);
  431. lpSubString = StrChr(lpSubString, '=');
  432. if (!lpSubString)
  433. IF_FAILEXIT(hr = E_FAIL);
  434. //Skip the equal sign
  435. ++lpSubString;
  436. SkipWhitespace(lpSubString, &dwCount);
  437. lpSubString += dwCount;
  438. lpSubString1 = lpSubString;
  439. lpSubString = StrChr(lpSubString, '*');
  440. if (!lpSubString)
  441. {
  442. //If we cannot find a * in it, we assume that this is the last token
  443. //and copy the entire field in it.
  444. lpSubString = lpSubString1 + strlen(lpSubString1) + 1;
  445. }
  446. if (((DWORD)(lpSubString - lpSubString1 + 1)) > cch)
  447. {
  448. IF_FAILEXIT(hr = E_FAIL);
  449. }
  450. *pcchCount = 0;
  451. while(lpSubString1 < lpSubString)
  452. {
  453. *pszretval++ = *lpSubString1++;
  454. (*pcchCount)++;
  455. }
  456. *pszretval = '\0';
  457. (*pcchCount)++; //To account for null
  458. exit:
  459. return hr;
  460. }
  461. HRESULT HrEscapeOtherAdToken(LPSTR pszAdOther, LPSTR pszEncodedString, DWORD cch, DWORD *cchRetCount)
  462. {
  463. CHAR tempchar;
  464. DWORD dwTempCount = 1; //Initializing with a null
  465. LPCSTR pszTemp = pszAdOther;
  466. HRESULT hr = S_OK;
  467. *cchRetCount = 0;
  468. while (tempchar = *pszTemp)
  469. {
  470. if ((tempchar == '=') || (tempchar == ' ') || (tempchar == '&'))
  471. dwTempCount += 3;
  472. else
  473. dwTempCount++;
  474. pszTemp++;
  475. }
  476. if (dwTempCount > cch)
  477. {
  478. IF_FAILEXIT(hr = E_FAIL);
  479. }
  480. //We have enough space
  481. while (tempchar = *pszAdOther)
  482. {
  483. if ((tempchar == '=') || (tempchar == '&') || (tempchar == ' '))
  484. {
  485. if (tempchar == '=')
  486. {
  487. pszTemp = c_szEqualSign;
  488. }
  489. else if (tempchar == '&')
  490. {
  491. pszTemp = c_szAmpersandSign;
  492. }
  493. else if (tempchar == ' ')
  494. {
  495. pszTemp = c_szSpaceSign;
  496. }
  497. StrCpyN(pszEncodedString, pszTemp, cch);
  498. pszEncodedString += 3;
  499. }
  500. else
  501. {
  502. *pszEncodedString++ = tempchar;
  503. }
  504. pszAdOther++;
  505. }
  506. *cchRetCount = dwTempCount;
  507. *pszEncodedString = 0;
  508. exit:
  509. return hr;
  510. }