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.

341 lines
8.1 KiB

  1. /*
  2. * b o d y u t i l . c p p
  3. *
  4. * Purpose:
  5. * utility functions for body
  6. *
  7. * History
  8. * August '96: brettm - created
  9. *
  10. * Copyright (C) Microsoft Corp. 1995, 1996.
  11. */
  12. #include <pch.hxx>
  13. #include "demand.h"
  14. #include <resource.h>
  15. #include "note.h"
  16. #include "htmlstr.h"
  17. #include "bodyutil.h"
  18. #include "mshtmcid.h"
  19. #include "mshtml.h"
  20. #include "mshtmhst.h"
  21. #include "oleutil.h"
  22. #include "shlwapi.h"
  23. #include "error.h"
  24. #include "url.h"
  25. #include "menures.h"
  26. ASSERTDATA
  27. /*
  28. * t y p e d e f s
  29. */
  30. /*
  31. * m a c r o s
  32. */
  33. /*
  34. * c o n s t a n t s
  35. */
  36. /*
  37. * g l o b a l s
  38. */
  39. /*
  40. * p r o t o t y p e s
  41. */
  42. INT_PTR FrameWarnDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  43. /*
  44. * f u n c t i o n s
  45. */
  46. HRESULT HrCmdTgtUpdateToolbar(LPOLECOMMANDTARGET pCmdTarget, HWND hwndToolbar)
  47. {
  48. HRESULT hr;
  49. OLECMD rgEditCmds[]={{OLECMDID_CUT, 0},
  50. {OLECMDID_COPY, 0},
  51. {OLECMDID_COPY, 0},
  52. {OLECMDID_PASTE, 0},
  53. {OLECMDID_SELECTALL, 0},
  54. {OLECMDID_UNDO, 0},
  55. {OLECMDID_REDO, 0}};
  56. int rgids[] ={ ID_CUT,
  57. ID_NOTE_COPY,
  58. ID_COPY,
  59. ID_PASTE,
  60. ID_SELECT_ALL,
  61. ID_UNDO,
  62. ID_REDO};
  63. if (!pCmdTarget || !hwndToolbar)
  64. return E_INVALIDARG;
  65. hr=pCmdTarget->QueryStatus(NULL, sizeof(rgEditCmds)/sizeof(OLECMD), rgEditCmds, NULL);
  66. if (!FAILED(hr))
  67. {
  68. for(int i=0; i<sizeof(rgEditCmds)/sizeof(OLECMD); i++)
  69. SendMessage(hwndToolbar, TB_ENABLEBUTTON, rgids[i], MAKELONG(rgEditCmds[i].cmdf & OLECMDF_ENABLED,0));
  70. }
  71. return hr;
  72. }
  73. HRESULT HrConvertHTMLToPlainText(LPSTREAM pstmHtml, LPSTREAM *ppstm, CLIPFORMAT cf)
  74. {
  75. HRESULT hr;
  76. LPUNKNOWN pUnkTrident=0;
  77. LPSTREAM pstmPlain=0;
  78. if (!ppstm)
  79. return E_INVALIDARG;
  80. hr = MimeEditDocumentFromStream(pstmHtml, IID_IUnknown, (LPVOID *)&pUnkTrident);
  81. if (FAILED(hr))
  82. goto error;
  83. hr = HrGetDataStream(pUnkTrident, cf, &pstmPlain);
  84. if (FAILED(hr))
  85. goto error;
  86. *ppstm = pstmPlain;
  87. pstmPlain->AddRef();
  88. error:
  89. ReleaseObj(pUnkTrident);
  90. ReleaseObj(pstmPlain);
  91. return hr;
  92. }
  93. #define CCHMAX_FRAMESEARCH 4096
  94. HRESULT HrCheckForFramesets(LPMIMEMESSAGE pMsg, BOOL fWarnUser)
  95. {
  96. TCHAR rgchHtml[CCHMAX_FRAMESEARCH + 1];
  97. TCHAR rgchWarn[CCHMAX_STRINGRES];
  98. LPSTREAM pstmHtml=0,
  99. pstmWarning=0;
  100. ULONG cb=0;
  101. HRESULT hr=S_OK;
  102. HBODY hBody;
  103. if (!pMsg) // no work
  104. return S_OK;
  105. pMsg->GetTextBody(TXT_HTML, IET_DECODED, &pstmHtml, &hBody);
  106. if (pstmHtml==NULL)
  107. goto cleanup;
  108. HrRewindStream(pstmHtml);
  109. pstmHtml->Read(rgchHtml, CCHMAX_FRAMESEARCH, &cb);
  110. rgchHtml[cb]=0;
  111. if (!StrStrIA(rgchHtml, _TEXT("<FRAMESET")))
  112. goto cleanup;
  113. if (fWarnUser)
  114. {
  115. // if send current document or forwarding, then we give the user a chance
  116. if (DialogBox(g_hLocRes, MAKEINTRESOURCE(iddFrameWarning), g_hwndInit, FrameWarnDlgProc)==IDOK)
  117. {
  118. hr = S_READONLY;
  119. goto cleanup;
  120. }
  121. }
  122. // if the body contains a frameset tag, let's make this an attachment
  123. // and set the body to some warning
  124. hr = MimeOleCreateVirtualStream(&pstmWarning);
  125. if (FAILED(hr))
  126. goto cleanup;
  127. if (!LoadString(g_hLocRes, idsHtmlNoFrames, rgchWarn, ARRAYSIZE(rgchWarn)))
  128. {
  129. hr = E_OUTOFMEMORY;
  130. goto cleanup;
  131. }
  132. hr = pstmWarning->Write(rgchWarn, lstrlen(rgchWarn), NULL);
  133. if (FAILED(hr))
  134. goto cleanup;
  135. hr = pMsg->SetTextBody(TXT_HTML, IET_DECODED, NULL, pstmWarning, NULL);
  136. if (FAILED(hr))
  137. goto cleanup;
  138. hr = pMsg->AttachObject(IID_IStream, pstmHtml, &hBody);
  139. if (FAILED(hr))
  140. goto cleanup;
  141. hr = MimeOleSetBodyPropA(pMsg, hBody, PIDTOSTR(PID_HDR_CNTTYPE), NOFLAGS, STR_MIME_TEXT_HTML);
  142. if (FAILED(hr))
  143. goto cleanup;
  144. cleanup:
  145. ReleaseObj(pstmHtml);
  146. ReleaseObj(pstmWarning);
  147. return hr;
  148. }
  149. INT_PTR FrameWarnDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  150. {
  151. if (msg == WM_COMMAND)
  152. {
  153. int id = GET_WM_COMMAND_ID(wParam, lParam);
  154. if (id == IDOK || id == IDCANCEL)
  155. {
  156. EndDialog(hwnd, id);
  157. return TRUE;
  158. }
  159. }
  160. return FALSE;
  161. }
  162. static const CHAR c_szStartHTML[] = "StartHTML:";
  163. HRESULT HrStripHTMLClipboardHeader(LPSTREAM pstm, BOOL *pfIsRealCFHTML)
  164. {
  165. CHAR rgch[4096];
  166. LPSTR lpsz;
  167. ULONG cb,
  168. uPosRead,
  169. uPosWrite,
  170. cbNewSize;
  171. ULARGE_INTEGER ui;
  172. HRESULT hr=S_OK;
  173. // scan the first 200 bytes for "StartHTML:" in the pre-block
  174. *rgch=0;
  175. pstm->Read(rgch, 200, &cb);
  176. rgch[cb] = 0;
  177. if (pfIsRealCFHTML)
  178. *pfIsRealCFHTML = FALSE;
  179. HrGetStreamSize(pstm, &cbNewSize);
  180. lpsz = StrStrIA(rgch, c_szStartHTML);
  181. if (!lpsz)
  182. return S_OK;
  183. cb = StrToIntA(lpsz + ARRAYSIZE(c_szStartHTML)-sizeof(CHAR));
  184. if (cb==0 || cb > cbNewSize) // sanity check. Offset can't be bigger than the stream!
  185. return S_OK;
  186. if (pfIsRealCFHTML)
  187. *pfIsRealCFHTML = TRUE;
  188. // cb contains the offset of the HTML. Start shifting the data left
  189. uPosRead = cb;
  190. uPosWrite = 0;
  191. cbNewSize-=cb; // calc new length of stream
  192. while(cb)
  193. {
  194. hr = HrStreamSeekSet(pstm, uPosRead);
  195. if (FAILED(hr))
  196. goto error;
  197. hr = pstm->Read(rgch, ARRAYSIZE(rgch), &cb);
  198. if (FAILED(hr))
  199. goto error;
  200. hr = HrStreamSeekSet(pstm, uPosWrite);
  201. if (FAILED(hr))
  202. goto error;
  203. hr = pstm->Write(rgch, cb, NULL);
  204. if (FAILED(hr))
  205. goto error;
  206. uPosRead+=cb;
  207. uPosWrite+=cb;
  208. }
  209. // force the new stream length
  210. ui.LowPart = cbNewSize;
  211. ui.HighPart = 0;
  212. hr = pstm->SetSize(ui);
  213. if (FAILED(hr))
  214. goto error;
  215. error:
  216. return hr;
  217. }
  218. HRESULT SubstituteURLs(IHTMLDocument2 *pDoc, const URLSUB *rgUrlSub, int cUrlSub)
  219. {
  220. IHTMLElement *pElem;
  221. IHTMLAnchorElement *pAnchor;
  222. BSTR bstr;
  223. TCHAR szURL[INTERNET_MAX_URL_LENGTH];
  224. int i;
  225. HRESULT hr = S_OK;
  226. for (i = 0; i < cUrlSub; i++)
  227. {
  228. if (SUCCEEDED(hr = URLSubLoadStringA(rgUrlSub[i].ids, szURL, ARRAYSIZE(szURL), URLSUB_ALL, NULL)))
  229. {
  230. if (SUCCEEDED(hr = HrLPSZToBSTR(szURL, &bstr)))
  231. {
  232. if (SUCCEEDED(hr = HrGetElementImpl(pDoc, rgUrlSub[i].pszId, &pElem)))
  233. {
  234. if (SUCCEEDED(hr = pElem->QueryInterface(IID_IHTMLAnchorElement, (LPVOID*)&pAnchor)))
  235. {
  236. hr = pAnchor->put_href(bstr);
  237. pAnchor->Release();
  238. }
  239. pElem->Release();
  240. }
  241. SysFreeString(bstr);
  242. }
  243. }
  244. }
  245. return hr;
  246. }
  247. HRESULT HrGetSetCheck(BOOL fSet, IHTMLElement *pElem, VARIANT_BOOL *pfValue)
  248. {
  249. HRESULT hr;
  250. IHTMLOptionButtonElement *pCheck = NULL;
  251. Assert(pfValue);
  252. pElem->QueryInterface(IID_IHTMLOptionButtonElement, (LPVOID*)&pCheck);
  253. if (pCheck)
  254. {
  255. if (fSet)
  256. {
  257. hr = pCheck->put_checked(*pfValue);
  258. }
  259. else
  260. {
  261. hr = pCheck->get_checked(pfValue);
  262. }
  263. pCheck->Release();
  264. }
  265. else
  266. hr = E_FAIL;
  267. return hr;
  268. }