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.

1228 lines
37 KiB

  1. #include "pch.hxx"
  2. #include "globals.h"
  3. #include "resource.h"
  4. #include "util.h"
  5. #include "mehost.h"
  6. #include "demand.h"
  7. #define SetMenuItem(_hmenu, _id, _fOn) EnableMenuItem(_hmenu, _id, (_fOn)?MF_ENABLED:MF_DISABLED|MF_GRAYED)
  8. extern BOOL
  9. g_fHTML,
  10. g_fIncludeMsg,
  11. g_fQuote,
  12. g_fSlideShow,
  13. g_fAutoInline,
  14. g_fSendImages,
  15. g_fComposeFont,
  16. g_fBlockQuote,
  17. g_fAutoSig,
  18. g_fSigHtml;
  19. extern CHAR g_chQuote;
  20. extern CHAR g_szComposeFont[MAX_PATH];
  21. extern CHAR g_szSig[MAX_PATH];
  22. extern LONG g_lHeaderType;
  23. INT_PTR CALLBACK MhtmlDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  24. HRESULT SetEncodingOptions(IMimeMessage *pMsg, HCHARSET hCharset);
  25. HRESULT IPersistMimeLoad(IUnknown *pUnk, IMimeMessage *pMsg);
  26. CMeHost::CMeHost()
  27. {
  28. m_fEditMode=FALSE;
  29. m_fHTMLMode=TRUE;
  30. *m_szFileW=0;
  31. *m_szFmt = 0;
  32. m_pMsg=NULL;
  33. m_pIntl=NULL;
  34. }
  35. CMeHost::~CMeHost()
  36. {
  37. SafeRelease(m_pIntl);
  38. SafeRelease(m_pMsg);
  39. }
  40. ULONG CMeHost::AddRef()
  41. {
  42. return CDocHost::AddRef();
  43. }
  44. ULONG CMeHost::Release()
  45. {
  46. return CDocHost::Release();
  47. }
  48. HRESULT CMeHost::HrInit(HWND hwndMDIClient, IOleInPlaceFrame *pFrame)
  49. {
  50. HRESULT hr=E_FAIL;
  51. IMimeMessage *pMsg=0;
  52. if (pFrame==NULL)
  53. return E_INVALIDARG;
  54. hr=CDocHost::HrInit(hwndMDIClient, 99, dhbHost);
  55. if (FAILED(hr))
  56. goto error;
  57. ReplaceInterface(m_pInPlaceFrame, pFrame);
  58. hr=CDocHost::HrCreateDocObj((LPCLSID)&CLSID_MimeEdit);
  59. if (FAILED(hr))
  60. goto error;
  61. hr=CDocHost::HrShow();
  62. if (FAILED(hr))
  63. goto error;
  64. // need to init MimeEdit with a blank message
  65. hr = CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&pMsg);
  66. if (FAILED(hr))
  67. goto error;
  68. hr = pMsg->InitNew();
  69. if (FAILED(hr))
  70. goto error;
  71. hr = IPersistMimeLoad(m_lpOleObj, pMsg);
  72. // need to init MimeEdit with a blank message
  73. hr = CoCreateInstance(CLSID_IMimeInternational, NULL, CLSCTX_INPROC_SERVER, IID_IMimeInternational, (LPVOID *)&m_pIntl);
  74. if (FAILED(hr))
  75. goto error;
  76. error:
  77. ReleaseObj(pMsg);
  78. return hr;
  79. }
  80. static char c_szFilter[] = "Rfc 822 Messages (*.eml)\0*.eml\0\0";
  81. HRESULT CMeHost::HrOpen(HWND hwnd)
  82. {
  83. OPENFILENAME ofn;
  84. TCHAR szFile[MAX_PATH];
  85. TCHAR szTitle[MAX_PATH];
  86. TCHAR szDefExt[30];
  87. if (!m_lpOleObj)
  88. return E_FAIL;
  89. lstrcpy(szFile, "c:\\*.eml");
  90. lstrcpy(szDefExt, ".eml");
  91. lstrcpy(szTitle, "Browse for message...");
  92. ZeroMemory (&ofn, sizeof (ofn));
  93. ofn.lStructSize = sizeof (ofn);
  94. ofn.hwndOwner = hwnd;
  95. ofn.lpstrFilter = c_szFilter;
  96. ofn.nFilterIndex = 1;
  97. ofn.lpstrFile = szFile;
  98. ofn.nMaxFile = sizeof (szFile);
  99. ofn.lpstrTitle = szTitle;
  100. ofn.lpstrDefExt = szDefExt;
  101. ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  102. // Show OpenFile Dialog
  103. if (!GetOpenFileName(&ofn))
  104. return E_OUTOFMEMORY;
  105. return HrLoadFile(szFile);
  106. }
  107. HRESULT CMeHost::OnCommand(HWND hwnd, int id, WORD wCmd)
  108. {
  109. VARIANTARG va;
  110. ULONG uCmd=0,
  111. uCmdMimeEdit,
  112. uPrompt = OLECMDEXECOPT_DODEFAULT;
  113. VARIANTARG *pvaOut=0,
  114. *pvaIn=0;
  115. BSTR bstrFree=0;
  116. CHAR rgch[MAX_PATH];
  117. WCHAR rgchW[MAX_PATH];
  118. switch (id)
  119. {
  120. case idmBackground:
  121. return BackgroundPicture();
  122. case idmTestBackRed:
  123. return BackRed();
  124. case idmTestForeRed:
  125. return ForeRed();
  126. case idmInsertFile:
  127. uCmdMimeEdit = MECMDID_INSERTTEXTFILE;
  128. // if shift it down prompt ourselves to test the other codepath
  129. if (GetKeyState(VK_SHIFT)&0x8000)
  130. {
  131. lstrcpy(rgch, "c:\\foo.txt");
  132. if (GenericPrompt(hwnd, "Insert File...", "pick a filename", rgch, MAX_PATH)!=S_OK)
  133. return S_FALSE;
  134. MultiByteToWideChar(CP_ACP, 0, rgch, -1, rgchW, MAX_PATH);
  135. bstrFree = SysAllocString(rgchW);
  136. va.vt = VT_BSTR;
  137. va.bstrVal = bstrFree;
  138. pvaIn = &va;
  139. }
  140. break;
  141. case idmFont:
  142. uCmdMimeEdit = MECMDID_FORMATFONT;
  143. break;
  144. case idmSetText:
  145. uCmdMimeEdit = MECMDID_SETTEXT;
  146. va.vt = VT_BSTR;
  147. va.bstrVal = SysAllocString(L"This is a sample text string. <BR> It <b><i>can</b></i> be HTML.");
  148. bstrFree = va.bstrVal;
  149. pvaIn = &va;
  150. break;
  151. case idmSaveAsStationery:
  152. SaveAsStationery();
  153. break;
  154. case idmSaveAsMHTML:
  155. SaveAsMhtmlTest();
  156. break;
  157. case idmLang:
  158. DialogBoxParam(g_hInst, MAKEINTRESOURCE(iddLang), m_hwnd, ExtLangDlgProc, (LPARAM)this);
  159. break;
  160. case idmFmtPreview:
  161. DialogBoxParam(g_hInst, MAKEINTRESOURCE(iddFmt), m_hwnd, ExtFmtDlgProc, (LPARAM)this);
  162. break;
  163. case idmNoHeader:
  164. uCmdMimeEdit = MECMDID_STYLE;
  165. va.vt = VT_I4;
  166. va.lVal = MESTYLE_NOHEADER;
  167. pvaIn = &va;
  168. break;
  169. case idmPreview:
  170. uCmdMimeEdit = MECMDID_STYLE;
  171. va.vt = VT_I4;
  172. va.lVal = MESTYLE_PREVIEW;
  173. pvaIn = &va;
  174. break;
  175. case idmMiniHeader:
  176. uCmdMimeEdit = MECMDID_STYLE;
  177. va.vt = VT_I4;
  178. va.lVal = MESTYLE_MINIHEADER;
  179. pvaIn = &va;
  180. break;
  181. case idmFormatBar:
  182. uCmdMimeEdit = MECMDID_STYLE;
  183. va.vt = VT_I4;
  184. va.lVal = MESTYLE_FORMATBAR;
  185. pvaIn = &va;
  186. break;
  187. case idmViewSource:
  188. case idmViewMsgSource:
  189. uCmdMimeEdit = MECMDID_VIEWSOURCE;
  190. va.vt = VT_I4;
  191. va.lVal = (id == idmViewSource ? MECMD_VS_HTML : MECMD_VS_MESSAGE);
  192. pvaIn = &va;
  193. break;
  194. case idmCut:
  195. uCmd=OLECMDID_CUT;
  196. break;
  197. case idmCopy:
  198. uCmd=OLECMDID_COPY;
  199. break;
  200. case idmPaste:
  201. uCmd=OLECMDID_PASTE;
  202. break;
  203. case idmUndo:
  204. uCmd=OLECMDID_UNDO;
  205. break;
  206. case idmRedo:
  207. uCmd=OLECMDID_REDO;
  208. break;
  209. case idmSelectAll:
  210. uCmd=OLECMDID_SELECTALL;
  211. break;
  212. case idmOpen:
  213. HrOpen(hwnd);
  214. return S_OK;
  215. case idmHTMLMode:
  216. m_fHTMLMode = !m_fHTMLMode;
  217. va.vt = VT_BOOL;
  218. va.boolVal = m_fHTMLMode ? VARIANT_TRUE : VARIANT_FALSE;
  219. pvaIn = &va;
  220. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_EDITHTML, OLECMDEXECOPT_DODEFAULT, &va, NULL);
  221. if (!m_fHTMLMode &&
  222. m_pCmdTarget &&
  223. MessageBox(m_hwnd, "You are going from HTML to plaintext. Do you want to downgrade the document?", "MeHost", MB_YESNO)==IDYES)
  224. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_DOWNGRADEPLAINTEXT, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
  225. return S_OK;
  226. case idmEditDocument:
  227. m_fEditMode = !m_fEditMode;
  228. uCmdMimeEdit = MECMDID_EDITMODE;
  229. va.vt = VT_BOOL;
  230. va.boolVal = m_fEditMode ? VARIANT_TRUE : VARIANT_FALSE;
  231. pvaIn = &va;
  232. break;
  233. case idmRot13:
  234. uCmdMimeEdit = MECMDID_ROT13;
  235. break;
  236. case idmFind:
  237. uCmd = OLECMDID_FIND;
  238. break;
  239. case idmSpelling:
  240. uCmd = OLECMDID_SPELL;
  241. break;
  242. case idmPrint:
  243. uCmd = OLECMDID_PRINT;
  244. break;
  245. case idmSaveAs:
  246. SaveAs();
  247. return 0;
  248. }
  249. if (m_pCmdTarget)
  250. {
  251. if (uCmd)
  252. m_pCmdTarget->Exec(NULL, uCmd, uPrompt, pvaIn, pvaOut);
  253. if (uCmdMimeEdit)
  254. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, uCmdMimeEdit, uPrompt, pvaIn, pvaOut);
  255. }
  256. SysFreeString(bstrFree);
  257. return S_OK;
  258. }
  259. LRESULT CMeHost::OnInitMenuPopup(HWND hwnd, HMENU hmenuPopup, UINT uPos)
  260. {
  261. MENUITEMINFO mii;
  262. HMENU hmenuMain;
  263. OLECMD rgMimeEditCmds[]= {{MECMDID_EDITMODE, 0},
  264. {MECMDID_ROT13, 0},
  265. {MECMDID_EDITHTML, 0}};
  266. OLECMD rgStdCmds[]= {{OLECMDID_CUT, 0},
  267. {OLECMDID_COPY, 0},
  268. {OLECMDID_PASTE, 0},
  269. {OLECMDID_SELECTALL, 0},
  270. {OLECMDID_UNDO, 0},
  271. {OLECMDID_REDO, 0},
  272. {OLECMDID_FIND, 0}};
  273. int rgidsStd[]= {idmCut,
  274. idmCopy,
  275. idmPaste,
  276. idmSelectAll,
  277. idmUndo,
  278. idmRedo,
  279. idmFind};
  280. int rgidsMimeEdit[]= {idmEditDocument,
  281. idmRot13,
  282. idmHTMLMode};
  283. int i,
  284. idm;
  285. VARIANTARG va;
  286. ULONG u;
  287. hmenuMain = GetMenu(hwnd);
  288. mii.cbSize = sizeof(MENUITEMINFO);
  289. mii.fMask = MIIM_ID | MIIM_SUBMENU;
  290. GetMenuItemInfo(hmenuMain, uPos, TRUE, &mii);
  291. switch (mii.wID)
  292. {
  293. case idmPopupFile:
  294. EnableMenuItem(hmenuPopup, idmOpen, MF_BYCOMMAND|MF_ENABLED);
  295. EnableMenuItem(hmenuPopup, idmPrint, MF_BYCOMMAND|MF_ENABLED);
  296. EnableMenuItem(hmenuPopup, idmSaveAs, MF_BYCOMMAND|MF_ENABLED);
  297. break;
  298. case idmPopupEdit:
  299. if (m_pCmdTarget)
  300. {
  301. if (m_pCmdTarget->QueryStatus(NULL, sizeof(rgStdCmds)/sizeof(OLECMD), rgStdCmds, NULL)==S_OK)
  302. for(i=0; i<sizeof(rgStdCmds)/sizeof(OLECMD); i++)
  303. SetMenuItem(hmenuPopup, rgidsStd[i], rgStdCmds[i].cmdf & OLECMDF_ENABLED);
  304. if (m_pCmdTarget->QueryStatus(&CMDSETID_MimeEdit, sizeof(rgMimeEditCmds)/sizeof(OLECMD), rgMimeEditCmds, NULL)==S_OK)
  305. for(i=0; i<sizeof(rgMimeEditCmds)/sizeof(OLECMD); i++)
  306. {
  307. SetMenuItem(hmenuPopup, rgidsMimeEdit[i], rgMimeEditCmds[i].cmdf & OLECMDF_ENABLED);
  308. CheckMenuItem(hmenuPopup, rgidsMimeEdit[i], MF_BYCOMMAND|(rgMimeEditCmds[i].cmdf & OLECMDF_LATCHED ? MF_CHECKED: MF_UNCHECKED));
  309. }
  310. }
  311. break;
  312. case idmPopupView:
  313. u = MESTYLE_NOHEADER;
  314. if (m_pCmdTarget &&
  315. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_STYLE, OLECMDEXECOPT_DODEFAULT, NULL, &va)==S_OK)
  316. u = va.lVal;
  317. switch(u)
  318. {
  319. case MESTYLE_NOHEADER:
  320. idm = idmNoHeader;
  321. break;
  322. case MESTYLE_MINIHEADER:
  323. idm = idmMiniHeader;
  324. break;
  325. case MESTYLE_PREVIEW:
  326. idm = idmPreview;
  327. break;
  328. case MESTYLE_FORMATBAR:
  329. idm = idmFormatBar;
  330. break;
  331. }
  332. CheckMenuRadioItem(hmenuPopup, idmNoHeader, idmFormatBar, idm, MF_BYCOMMAND|MF_ENABLED);
  333. SetMenuItem(hmenuPopup, idmNoHeader, TRUE);
  334. SetMenuItem(hmenuPopup, idmMiniHeader, TRUE);
  335. SetMenuItem(hmenuPopup, idmPreview, TRUE);
  336. SetMenuItem(hmenuPopup, idmFormatBar, TRUE);
  337. break;
  338. case idmPopupTools:
  339. {
  340. OLECMD CmdSpell = {OLECMDID_SPELL, 0};
  341. SetMenuItem(hmenuPopup, idmFmtPreview, TRUE);
  342. if (m_pCmdTarget)
  343. m_pCmdTarget->QueryStatus(NULL, 1, &CmdSpell, NULL);
  344. SetMenuItem(hmenuPopup, idmSpelling, CmdSpell.cmdf & OLECMDF_ENABLED);
  345. }
  346. break;
  347. }
  348. return 0;
  349. }
  350. HRESULT CMeHost::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[], OLECMDTEXT *pCmdText)
  351. {
  352. ULONG uCmd;
  353. HRESULT hr;
  354. if (pguidCmdGroup &&
  355. IsEqualGUID(*pguidCmdGroup, CMDSETID_MimeEditHost))
  356. {
  357. for (uCmd=0; uCmd < cCmds; uCmd++)
  358. rgCmds[uCmd].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
  359. return S_OK;
  360. }
  361. hr = CDocHost::QueryStatus(pguidCmdGroup, cCmds, rgCmds, pCmdText);
  362. if (pguidCmdGroup==NULL)
  363. {
  364. for (uCmd=0; uCmd < cCmds; uCmd++)
  365. {
  366. switch(rgCmds[uCmd].cmdID)
  367. {
  368. case OLECMDID_PROPERTIES:
  369. rgCmds[uCmd].cmdf = OLECMDF_SUPPORTED|OLECMDF_ENABLED;
  370. break;
  371. }
  372. }
  373. }
  374. return hr;
  375. }
  376. HRESULT CMeHost::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
  377. {
  378. CHAR rgch[MAX_PATH];
  379. WCHAR rgchW[MAX_PATH];
  380. if (pguidCmdGroup &&
  381. IsEqualGUID(*pguidCmdGroup, CMDSETID_MimeEditHost))
  382. {
  383. switch (nCmdID)
  384. {
  385. case MEHOSTCMDID_BORDERFLAGS:
  386. if (pvaOut)
  387. {
  388. pvaOut->vt = VT_I4;
  389. pvaOut->lVal = MEBF_OUTERCLIENTEDGE|MEBF_FORMATBARSEP;
  390. return S_OK;
  391. }
  392. else
  393. return E_INVALIDARG;
  394. case MEHOSTCMDID_SIGNATURE:
  395. if (pvaOut)
  396. {
  397. MultiByteToWideChar(CP_ACP, 0, g_szSig, -1, rgchW, MAX_PATH);
  398. pvaOut->vt = VT_BSTR;
  399. pvaOut->bstrVal = SysAllocString(rgchW);
  400. return S_OK;
  401. }
  402. else
  403. return E_INVALIDARG;
  404. case MEHOSTCMDID_SIGNATURE_OPTIONS:
  405. if (pvaOut)
  406. {
  407. pvaOut->vt = VT_I4;
  408. pvaOut->lVal = MESIGOPT_TOP|(g_fSigHtml?MESIGOPT_HTML:MESIGOPT_PLAIN);
  409. return S_OK;
  410. }
  411. else
  412. return E_INVALIDARG;
  413. case MEHOSTCMDID_SIGNATURE_ENABLED:
  414. if (pvaIn)
  415. {
  416. if (pvaIn->lVal == MESIG_AUTO && !g_fAutoSig)
  417. return S_FALSE;
  418. else
  419. return S_OK;
  420. }
  421. else
  422. return E_INVALIDARG;
  423. case MEHOSTCMDID_REPLY_TICK_COLOR:
  424. if (pvaOut)
  425. {
  426. pvaOut->vt = VT_I4;
  427. pvaOut->lVal = RGB(255,0,0);
  428. return S_OK;
  429. }
  430. else
  431. return E_INVALIDARG;
  432. case MEHOSTCMDID_HEADER_TYPE:
  433. if (pvaOut)
  434. {
  435. pvaOut->vt = VT_I4;
  436. pvaOut->lVal = g_lHeaderType;
  437. return S_OK;
  438. }
  439. else
  440. return E_INVALIDARG;
  441. case MEHOSTCMDID_QUOTE_CHAR:
  442. if (pvaOut)
  443. {
  444. pvaOut->vt = VT_I4; // apply quoteing to plain-text stream
  445. pvaOut->lVal = g_fQuote?g_chQuote:NULL;
  446. return S_OK;
  447. }
  448. else
  449. return E_INVALIDARG;
  450. case MEHOSTCMDID_SLIDESHOW_DELAY:
  451. if (pvaOut)
  452. {
  453. pvaOut->vt = VT_I4;
  454. pvaOut->lVal = 5;
  455. return S_OK;
  456. }
  457. else
  458. return E_INVALIDARG;
  459. case MEHOSTCMDID_COMPOSE_FONT:
  460. if (pvaOut && g_fComposeFont)
  461. {
  462. MultiByteToWideChar(CP_ACP, 0, g_szComposeFont, -1, rgchW, MAX_PATH);
  463. pvaOut->vt = VT_BSTR;
  464. pvaOut->bstrVal = SysAllocString(rgchW);
  465. }
  466. return g_fComposeFont?S_OK:S_FALSE;
  467. case MEHOSTCMDID_FLAGS:
  468. if (pvaOut)
  469. {
  470. pvaOut->vt = VT_I4;
  471. pvaOut->lVal = 0;
  472. if (g_fAutoSig)
  473. pvaOut->lVal |= MEO_FLAGS_AUTOTEXT;
  474. if (g_fHTML && m_fHTMLMode)
  475. pvaOut->lVal |= MEO_FLAGS_HTML;
  476. if (g_fAutoInline)
  477. pvaOut->lVal |= MEO_FLAGS_AUTOINLINE;
  478. if (g_fSlideShow)
  479. pvaOut->lVal |= MEO_FLAGS_SLIDESHOW;
  480. if (g_fIncludeMsg)
  481. pvaOut->lVal |= MEO_FLAGS_INCLUDEMSG;
  482. if (g_fSendImages)
  483. pvaOut->lVal |= MEO_FLAGS_SENDIMAGES;
  484. if (g_fBlockQuote)
  485. pvaOut->lVal |= MEO_FLAGS_BLOCKQUOTE;
  486. return S_OK;
  487. }
  488. else
  489. return E_INVALIDARG;
  490. case MEHOSTCMDID_ADD_TO_ADDRESSBOOK:
  491. case MEHOSTCMDID_ADD_TO_FAVORITES:
  492. if (pvaIn &&
  493. pvaIn->vt == VT_BSTR &&
  494. pvaIn->bstrVal != NULL)
  495. {
  496. WideCharToMultiByte(CP_ACP, 0, pvaIn->bstrVal, -1, rgch, MAX_PATH, NULL, NULL);
  497. MessageBox(m_hwnd, rgch, nCmdID == MEHOSTCMDID_ADD_TO_FAVORITES ?
  498. "CMeHost - AddToFavorites" :
  499. "CMeHost - AddToAddressBook", MB_OK);
  500. return S_OK;
  501. }
  502. else
  503. return E_INVALIDARG;
  504. }
  505. return OLECMDERR_E_NOTSUPPORTED;
  506. }
  507. if (pguidCmdGroup==NULL)
  508. {
  509. switch (nCmdID)
  510. {
  511. case OLECMDID_PROPERTIES:
  512. MessageBox(m_hwnd, "This is a place holder for the note properties dialog", "MePad", MB_OK);
  513. return S_OK;
  514. }
  515. }
  516. return CDocHost::Exec(pguidCmdGroup, nCmdID, nCmdExecOpt, pvaIn, pvaOut);
  517. }
  518. INT_PTR CALLBACK MhtmlDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  519. {
  520. DWORD dwFlags;
  521. switch (msg)
  522. {
  523. case WM_INITDIALOG:
  524. CheckDlgButton(hwnd, idcHTML, BST_CHECKED);
  525. CheckDlgButton(hwnd, idcPlain, BST_CHECKED);
  526. CheckDlgButton(hwnd, idcImages, BST_CHECKED);
  527. CheckDlgButton(hwnd, idcFiles, BST_CHECKED);
  528. break;
  529. case WM_COMMAND:
  530. switch (LOWORD(wParam))
  531. {
  532. case IDOK:
  533. dwFlags = 0;
  534. if (IsDlgButtonChecked(hwnd, idcImages))
  535. dwFlags |= MECD_ENCODEIMAGES;
  536. if (IsDlgButtonChecked(hwnd, idcPlain))
  537. dwFlags |= MECD_PLAINTEXT;
  538. if (IsDlgButtonChecked(hwnd, idcHTML))
  539. dwFlags |= MECD_HTML;
  540. if (IsDlgButtonChecked(hwnd, idcFiles))
  541. dwFlags |= MECD_ENCODEFILEURLSONLY;
  542. EndDialog(hwnd, dwFlags);
  543. return TRUE;
  544. case IDCANCEL:
  545. EndDialog(hwnd, -1);
  546. return TRUE;
  547. }
  548. break;
  549. }
  550. return FALSE;
  551. }
  552. INT_PTR CALLBACK CMeHost::ExtFmtDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  553. {
  554. CMeHost *pHost=(CMeHost *)GetWindowLong(hwnd, DWL_USER);
  555. if (msg==WM_INITDIALOG)
  556. {
  557. pHost = (CMeHost *)lParam;
  558. SetWindowLong(hwnd, DWL_USER, lParam);
  559. }
  560. return pHost?pHost->FmtDlgProc(hwnd, msg, wParam, lParam):FALSE;
  561. }
  562. INT_PTR CALLBACK CMeHost::FmtDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  563. {
  564. WCHAR rgchW[MAX_PATH];
  565. VARIANTARG va;
  566. switch (msg)
  567. {
  568. case WM_COMMAND:
  569. switch (LOWORD(wParam))
  570. {
  571. case IDOK:
  572. GetWindowText(GetDlgItem(hwnd, idcEdit), m_szFmt, sizeof(m_szFmt));
  573. MultiByteToWideChar(CP_ACP, 0, m_szFmt, -1, rgchW, MAX_PATH);
  574. if (m_pCmdTarget)
  575. {
  576. va.vt = VT_BSTR;
  577. va.bstrVal = (BSTR)rgchW;
  578. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_PREVIEWFORMAT, OLECMDEXECOPT_DODEFAULT, &va, NULL);
  579. }
  580. // fall tro'
  581. case IDCANCEL:
  582. EndDialog(hwnd, LOWORD(wParam));
  583. return TRUE;
  584. }
  585. break;
  586. case WM_INITDIALOG:
  587. SetWindowText(GetDlgItem(hwnd, idcEdit), m_szFmt);
  588. SetFocus(GetDlgItem(hwnd, idcEdit));
  589. break;
  590. }
  591. return FALSE;
  592. }
  593. UINT uCodePageFromCharset(IMimeInternational *pIntl, HCHARSET hCharset)
  594. {
  595. INETCSETINFO CsetInfo;
  596. UINT uiCodePage = GetACP();
  597. if (hCharset &&
  598. (pIntl->GetCharsetInfo(hCharset, &CsetInfo)==S_OK))
  599. uiCodePage = CsetInfo.cpiWindows ;
  600. return uiCodePage;
  601. }
  602. INT_PTR CALLBACK CMeHost::ExtLangDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  603. {
  604. CMeHost *pHost=(CMeHost *)GetWindowLong(hwnd, DWL_USER);
  605. if (msg==WM_INITDIALOG)
  606. {
  607. pHost = (CMeHost *)lParam;
  608. SetWindowLong(hwnd, DWL_USER, lParam);
  609. }
  610. return pHost?pHost->LangDlgProc(hwnd, msg, wParam, lParam):FALSE;
  611. }
  612. INT_PTR CALLBACK CMeHost::LangDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  613. {
  614. VARIANTARG va;
  615. HKEY hk=0,
  616. hkSub;
  617. LONG cb;
  618. DWORD n=0,
  619. l,
  620. dwCodePage,
  621. dwType;
  622. TCHAR rgch[MAX_PATH];
  623. HWND hwndCombo = GetDlgItem(hwnd, idcLang);
  624. HCHARSET hCharset;
  625. HRESULT hr;
  626. switch (msg)
  627. {
  628. case WM_COMMAND:
  629. switch (LOWORD(wParam))
  630. {
  631. case IDOK:
  632. l = SendMessage(hwndCombo, CB_GETCURSEL, 0 ,0);
  633. dwCodePage = SendMessage(hwndCombo, CB_GETITEMDATA, l, 0);
  634. m_pIntl->GetCodePageCharset(dwCodePage, CHARSET_BODY, &hCharset);
  635. if (m_pCmdTarget)
  636. {
  637. va.vt = VT_I4;
  638. va.lVal = (LONG)hCharset;
  639. if (FAILED(hr=m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_CHARSET, OLECMDEXECOPT_DODEFAULT, &va, NULL)))
  640. {
  641. wsprintf(rgch, "Could not switch language hr=0x%x", hr);
  642. MessageBox(m_hwnd, rgch, "MePad", MB_OK);
  643. }
  644. }
  645. // fall tro'
  646. case IDCANCEL:
  647. EndDialog(hwnd, LOWORD(wParam));
  648. return TRUE;
  649. }
  650. break;
  651. case WM_INITDIALOG:
  652. if (RegOpenKey(HKEY_CLASSES_ROOT, "MIME\\Database\\Codepage", &hk)==ERROR_SUCCESS)
  653. {
  654. while (RegEnumKey(hk, n++, rgch, MAX_PATH)==ERROR_SUCCESS)
  655. {
  656. dwCodePage = atoi(rgch);
  657. if (RegOpenKey(hk, rgch, &hkSub)==ERROR_SUCCESS)
  658. {
  659. cb = MAX_PATH;
  660. if (RegQueryValueEx(hkSub, "Description", 0, &dwType, (LPBYTE)rgch, (ULONG *)&cb)==ERROR_SUCCESS)
  661. {
  662. l = SendMessage(hwndCombo, CB_ADDSTRING, NULL, (LPARAM)rgch);
  663. if (l>=0)
  664. SendMessage(hwndCombo, CB_SETITEMDATA, l, dwCodePage);
  665. }
  666. CloseHandle(hkSub);
  667. }
  668. }
  669. CloseHandle(hk);
  670. };
  671. if (m_pCmdTarget)
  672. {
  673. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_CHARSET, OLECMDEXECOPT_DODEFAULT, NULL, &va);
  674. dwCodePage = uCodePageFromCharset(m_pIntl, (HCHARSET)va.lVal);
  675. }
  676. else
  677. dwCodePage = 0;
  678. l = SendMessage(hwndCombo, CB_GETCOUNT, NULL, NULL);
  679. for (n=0; n<l; n++)
  680. {
  681. if ((DWORD)SendMessage(hwndCombo, CB_GETITEMDATA, n, NULL)==dwCodePage)
  682. {
  683. SendMessage(hwndCombo, CB_SETCURSEL, n, NULL);
  684. break;
  685. }
  686. }
  687. SetFocus(hwndCombo);
  688. return TRUE;
  689. }
  690. return FALSE;
  691. }
  692. LRESULT CMeHost::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  693. {
  694. VARIANTARG va;
  695. int id;
  696. BOOL fDirty=FALSE;
  697. IOleDocumentView *pDocView;
  698. switch (msg)
  699. {
  700. case WM_NCACTIVATE:
  701. if (m_lpOleObj &&
  702. m_lpOleObj->QueryInterface(IID_IOleDocumentView, (LPVOID *)&pDocView)==S_OK)
  703. {
  704. pDocView->UIActivate(LOWORD(wParam));
  705. pDocView->Release();
  706. }
  707. break;
  708. case WM_CLOSE:
  709. if (m_pCmdTarget &&
  710. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_DIRTY, 0, 0, &va)==S_OK &&
  711. va.vt == VT_BOOL)
  712. fDirty = va.boolVal == VARIANT_TRUE;
  713. if (fDirty)
  714. {
  715. id = MessageBox(m_hwnd, "This message has been modified. Do you want to save the changes?",
  716. "MimeEdit Host", MB_YESNOCANCEL);
  717. if (id==IDCANCEL)
  718. return 0;
  719. if (id==IDYES)
  720. {
  721. if (Save()==MIMEEDIT_E_USERCANCEL)
  722. return 0;
  723. }
  724. }
  725. break;
  726. }
  727. return CDocHost::WndProc(hwnd, msg, wParam, lParam);
  728. }
  729. HRESULT CMeHost::Save()
  730. {
  731. if (*m_szFileW==NULL)
  732. return SaveAs();
  733. return SaveToFile(m_szFileW);
  734. }
  735. HRESULT CMeHost::SaveAs()
  736. {
  737. OPENFILENAME ofn;
  738. TCHAR szFile[MAX_PATH];
  739. TCHAR szTitle[MAX_PATH];
  740. TCHAR szDefExt[30];
  741. if (!m_lpOleObj)
  742. return E_FAIL;
  743. lstrcpy(szFile, "c:\\*.eml");
  744. lstrcpy(szDefExt, ".eml");
  745. lstrcpy(szTitle, "Save Message As...");
  746. ZeroMemory (&ofn, sizeof (ofn));
  747. ofn.lStructSize = sizeof (ofn);
  748. ofn.hwndOwner = m_hwnd;
  749. ofn.lpstrFilter = c_szFilter;
  750. ofn.nFilterIndex = 1;
  751. ofn.lpstrFile = szFile;
  752. ofn.nMaxFile = sizeof (szFile);
  753. ofn.lpstrTitle = szTitle;
  754. ofn.lpstrDefExt = szDefExt;
  755. ofn.Flags = OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
  756. if (*szFile==NULL)
  757. return E_FAIL;
  758. // Show OpenFile Dialog
  759. if (!GetSaveFileName(&ofn))
  760. return MIMEEDIT_E_USERCANCEL;
  761. MultiByteToWideChar(CP_ACP, 0, szFile, -1, m_szFileW, MAX_PATH);
  762. SetWindowText(m_hwnd, szFile);
  763. return SaveToFile(m_szFileW);
  764. }
  765. HRESULT CMeHost::SaveAsMhtmlTest()
  766. {
  767. IMimeMessage *pMsg;
  768. IHTMLDocument2 *pDoc;
  769. IServiceProvider *pSP;
  770. DWORD dwFlags;
  771. if (m_lpOleObj->QueryInterface(IID_IServiceProvider, (LPVOID *)&pSP)==S_OK)
  772. {
  773. if (pSP->QueryService(IID_IHTMLDocument2, IID_IHTMLDocument2, (LPVOID *)&pDoc)==S_OK)
  774. {
  775. dwFlags = DialogBox(g_hInst, MAKEINTRESOURCE(iddSaveAsMHTML), m_hwnd, MhtmlDlgProc);
  776. if (dwFlags != -1)
  777. {
  778. if (!FAILED(MimeEditCreateMimeDocument(pDoc, m_pMsg, dwFlags, &pMsg)))
  779. {
  780. SetEncodingOptions(pMsg, GetCharset());
  781. pMsg->Commit(0);
  782. MimeEditViewSource(m_hwnd, pMsg);
  783. pMsg->Release();
  784. }
  785. }
  786. pDoc->Release();
  787. }
  788. pSP->Release();
  789. }
  790. return S_OK;
  791. }
  792. HRESULT CMeHost::SaveToFile(LPWSTR pszW)
  793. {
  794. IPersistMime *ppm;
  795. IPersistFile *pPF;
  796. IMimeMessage *pMsg;
  797. HRESULT hr;
  798. hr = m_lpOleObj->QueryInterface(IID_IPersistMime, (LPVOID *)&ppm);
  799. if (!FAILED(hr))
  800. {
  801. hr = CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&pMsg);
  802. if (!FAILED(hr))
  803. {
  804. pMsg->InitNew();
  805. hr = pMsg->QueryInterface(IID_IPersistFile, (LPVOID *)&pPF);
  806. if (!FAILED(hr))
  807. {
  808. hr = ppm->Save(pMsg, PMS_TEXT|PMS_HTML);
  809. if (!FAILED(hr))
  810. {
  811. SetEncodingOptions(pMsg, GetCharset());
  812. hr = pPF->Save(pszW, FALSE);
  813. }
  814. pPF->Release();
  815. }
  816. pMsg->Release();
  817. }
  818. ppm->Release();
  819. }
  820. return hr;
  821. }
  822. HCHARSET CMeHost::GetCharset()
  823. {
  824. VARIANTARG va;
  825. HCHARSET hCharset=0;
  826. if (m_pCmdTarget &&
  827. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_CHARSET, OLECMDEXECOPT_DODEFAULT, NULL, &va)==S_OK)
  828. hCharset = (HCHARSET)va.lVal;
  829. // if no charset has been set yet, let's use system codepage
  830. if (hCharset==NULL)
  831. m_pIntl->GetCodePageCharset(GetACP(), CHARSET_BODY, &hCharset);
  832. return hCharset;
  833. }
  834. HRESULT SetEncodingOptions(IMimeMessage *pMsg, HCHARSET hCharset)
  835. {
  836. PROPVARIANT rVariant;
  837. // Save Format
  838. rVariant.vt = VT_UI4;
  839. rVariant.ulVal = (ULONG)SAVE_RFC1521;
  840. pMsg->SetOption(OID_SAVE_FORMAT, &rVariant);
  841. // Text body encoding
  842. rVariant.ulVal = (ULONG)IET_QP;
  843. pMsg->SetOption(OID_TRANSMIT_TEXT_ENCODING, &rVariant);
  844. // Plain Text body encoding
  845. rVariant.ulVal = (ULONG)IET_QP;
  846. pMsg->SetOption(OID_XMIT_PLAIN_TEXT_ENCODING, &rVariant);
  847. // HTML Text body encoding
  848. rVariant.ulVal = (ULONG)IET_QP;
  849. pMsg->SetOption(OID_XMIT_HTML_TEXT_ENCODING, &rVariant);
  850. pMsg->SetCharset(hCharset, CSET_APPLY_ALL);
  851. return S_OK;
  852. }
  853. HRESULT IPersistMimeLoad(IUnknown *pUnk, IMimeMessage *pMsg)
  854. {
  855. IPersistMime *pPM;
  856. HRESULT hr;
  857. hr = pUnk->QueryInterface(IID_IPersistMime, (LPVOID *)&pPM);
  858. if (!FAILED(hr))
  859. {
  860. hr = pPM->Load(pMsg);
  861. pPM->Release();
  862. }
  863. return hr;
  864. }
  865. HRESULT CMeHost::BackRed()
  866. {
  867. IServiceProvider *pSP;
  868. IHTMLDocument2 *pDoc;
  869. IHTMLElement *pElem;
  870. IHTMLBodyElement *pBody;
  871. VARIANTARG v;
  872. if (m_lpOleObj->QueryInterface(IID_IServiceProvider, (LPVOID *)&pSP)==S_OK)
  873. {
  874. if (pSP->QueryService(IID_IHTMLDocument2, IID_IHTMLDocument2, (LPVOID *)&pDoc)==S_OK)
  875. {
  876. pElem=0;
  877. pDoc->get_body(&pElem);
  878. if (pElem)
  879. {
  880. if (pElem->QueryInterface(IID_IHTMLBodyElement, (LPVOID *)&pBody)==S_OK)
  881. {
  882. v.vt = VT_BSTR;
  883. v.bstrVal = SysAllocString(L"#FF0000");
  884. if (v.bstrVal)
  885. {
  886. pBody->put_bgColor(v);
  887. SysFreeString(v.bstrVal);
  888. }
  889. pBody->Release();
  890. }
  891. pElem->Release();
  892. }
  893. pDoc->Release();
  894. }
  895. pSP->Release();
  896. }
  897. return S_OK;
  898. }
  899. HRESULT CMeHost::ForeRed()
  900. {
  901. IServiceProvider *pSP;
  902. IHTMLDocument2 *pDoc;
  903. IHTMLSelectionObject *pSel=0;
  904. IOleCommandTarget *pCmdTarget;
  905. IDispatch *pID;
  906. if (m_lpOleObj->QueryInterface(IID_IServiceProvider, (LPVOID *)&pSP)==S_OK)
  907. {
  908. if (pSP->QueryService(IID_IHTMLDocument2, IID_IHTMLDocument2, (LPVOID *)&pDoc)==S_OK)
  909. {
  910. pDoc->get_selection(&pSel);
  911. if (pSel)
  912. {
  913. pSel->createRange(&pID);
  914. if (pID)
  915. {
  916. if (pID->QueryInterface(IID_IOleCommandTarget, (LPVOID *)&pCmdTarget)==S_OK)
  917. {
  918. VARIANTARG v;
  919. v.vt = VT_BSTR;
  920. v.bstrVal = SysAllocString(L"#FF0000");
  921. if (v.bstrVal)
  922. {
  923. pCmdTarget->Exec(&CMDSETID_Forms3, IDM_BACKCOLOR, NULL, &v, NULL);
  924. SysFreeString(v.bstrVal);
  925. }
  926. }
  927. pID->Release();
  928. }
  929. pSel->Release();
  930. }
  931. pDoc->Release();
  932. }
  933. pSP->Release();
  934. }
  935. return S_OK;
  936. }
  937. HRESULT CMeHost::SaveAsStationery()
  938. {
  939. VARIANTARG vaIn,
  940. vaOut;
  941. char rgch[MAX_PATH],
  942. rgch2[MAX_PATH+50];
  943. vaIn.vt = VT_BSTR;
  944. vaIn.bstrVal = SysAllocString(L"C:\\PROGRAM FILES\\COMMON FILES\\MICROSOFT SHARED\\STATIONERY");
  945. if (vaIn.bstrVal)
  946. {
  947. if (m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_SAVEASSTATIONERY, NULL, &vaIn, &vaOut)==S_OK)
  948. {
  949. if (WideCharToMultiByte(CP_ACP, 0, vaOut.bstrVal, SysStringLen(vaOut.bstrVal), rgch, MAX_PATH, NULL, NULL))
  950. {
  951. wsprintf(rgch2, "Stationery saved to %s", rgch);
  952. MessageBox(m_hwnd, rgch, "SaveAsStationery", MB_OK);
  953. }
  954. SysFreeString(vaOut.bstrVal);
  955. }
  956. SysFreeString(vaIn.bstrVal);
  957. }
  958. return S_OK;
  959. }
  960. HRESULT CMeHost::BackgroundPicture()
  961. {
  962. VARIANT va;
  963. char szUrl[MAX_PATH];
  964. WCHAR szUrlW[MAX_PATH];
  965. BSTR bstr;
  966. *szUrl=0;
  967. if (m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_BACKGROUNDIMAGE, NULL, NULL, &va)==S_OK)
  968. WideCharToMultiByte(CP_ACP, 0, va.bstrVal, -1, szUrl, MAX_PATH, NULL, NULL);
  969. if (GenericPrompt(m_hwnd, "Edit Background Picture...", "Choose a picture", szUrl, MAX_PATH)==S_OK)
  970. {
  971. if (MultiByteToWideChar(CP_ACP, 0, szUrl, -1, szUrlW, MAX_PATH) &&
  972. (bstr = SysAllocString(szUrlW)))
  973. {
  974. va.vt = VT_BSTR;
  975. va.bstrVal = bstr;
  976. m_pCmdTarget->Exec(&CMDSETID_MimeEdit, MECMDID_BACKGROUNDIMAGE, NULL, &va, NULL);
  977. SysFreeString(bstr);
  978. }
  979. }
  980. return S_OK;
  981. }
  982. HRESULT CMeHost::HrLoadFile(LPSTR pszFile)
  983. {
  984. IPersistFile *pPF;
  985. IMimeMessage *pMsg;
  986. if (!m_lpOleObj)
  987. return E_FAIL;
  988. if (pszFile == NULL || *pszFile==NULL)
  989. return E_FAIL;
  990. MultiByteToWideChar(CP_ACP, 0, pszFile, -1, m_szFileW, MAX_PATH);
  991. if (CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&pMsg)==S_OK)
  992. {
  993. if (pMsg->QueryInterface(IID_IPersistFile, (LPVOID *)&pPF)==S_OK)
  994. {
  995. if (pPF->Load(m_szFileW, 0)==S_OK)
  996. {
  997. if (IPersistMimeLoad(m_lpOleObj, pMsg)==S_OK)
  998. {
  999. SetWindowText(m_hwnd, pszFile);
  1000. ReplaceInterface(m_pMsg, pMsg);
  1001. }
  1002. }
  1003. pPF->Release();
  1004. }
  1005. pMsg->Release();
  1006. }
  1007. return S_OK;
  1008. }