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.

808 lines
19 KiB

  1. /*
  2. * e n v h o s t . c p p
  3. *
  4. * Purpose:
  5. *
  6. * History
  7. *
  8. * Copyright (C) Microsoft Corp. 1995, 1996.
  9. */
  10. #include <pch.hxx>
  11. #include "resource.h"
  12. #include "envcid.h"
  13. #include "commdlg.h"
  14. #include "docobj.h"
  15. #include "dllmain.h"
  16. #include "msoert.h"
  17. #include "mimeole.h"
  18. #include "envhost.h"
  19. #include "richedit.h"
  20. #include "init.h"
  21. #include "shellapi.h"
  22. HINSTANCE s_hRichEdit;
  23. HINSTANCE g_hLocRes ;
  24. HACCEL g_hAccelMailSend;
  25. HRESULT HrRicheditStreamOut(HWND hwndRE, LPSTREAM pstm, ULONG uSelFlags);
  26. void SaveFocus(BOOL fActive, HWND *phwnd);
  27. static const TCHAR c_szGWNoteWndClass[] = "GW_Note";
  28. //+---------------------------------------------------------------
  29. //
  30. // Member: Constructor
  31. //
  32. // Synopsis:
  33. //
  34. //---------------------------------------------------------------
  35. CEnvHost::CEnvHost(IUnknown *pUnkOuter) : CPrivateUnknown(pUnkOuter)
  36. {
  37. DllAddRef();
  38. }
  39. //+---------------------------------------------------------------
  40. //
  41. // Member: Destructor
  42. //
  43. // Synopsis:
  44. //
  45. //---------------------------------------------------------------
  46. CEnvHost::~CEnvHost()
  47. {
  48. DllRelease();
  49. }
  50. //+---------------------------------------------------------------
  51. //
  52. // Member: PrivateQueryInterface
  53. //
  54. // Synopsis:
  55. //
  56. //---------------------------------------------------------------
  57. HRESULT CEnvHost::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
  58. {
  59. if(!lplpObj)
  60. return E_INVALIDARG;
  61. *lplpObj = NULL;
  62. if (IsEqualIID(riid, IID_IUnknown))
  63. *lplpObj = (LPVOID)(IMsoEnvelopeHost *)this;
  64. else if (IsEqualIID(riid, IID_IMsoEnvelopeHost))
  65. *lplpObj = (LPVOID)(IMsoEnvelopeHost *)this;
  66. else
  67. {
  68. return E_NOINTERFACE;
  69. }
  70. AddRef();
  71. return NOERROR;
  72. }
  73. HRESULT CEnvHost::CreateNote(IUnknown *punk, REFCLSID clsidCreate, LPCWSTR wszTheme, LPCWSTR wszAuthor, LPCWSTR wszPrefix, DWORD grfCreate)
  74. {
  75. return HrCreateNote(clsidCreate, grfCreate);
  76. }
  77. HRESULT CEnvHost::LockServer(BOOL fLock)
  78. {
  79. return S_OK;
  80. }
  81. //+---------------------------------------------------------------
  82. //
  83. // Member: Constructor
  84. //
  85. // Synopsis:
  86. //
  87. //---------------------------------------------------------------
  88. CGWNote::CGWNote(IUnknown *pUnkOuter) : CPrivateUnknown(pUnkOuter)
  89. {
  90. m_pEnv=NULL;
  91. m_hwnd=NULL;
  92. m_hwndRE=NULL;
  93. m_pComponent=NULL;
  94. m_hwndFocus=NULL;
  95. DllAddRef();
  96. }
  97. //+---------------------------------------------------------------
  98. //
  99. // Member: Destructor
  100. //
  101. // Synopsis:
  102. //
  103. //---------------------------------------------------------------
  104. CGWNote::~CGWNote()
  105. {
  106. DllRelease();
  107. }
  108. //+---------------------------------------------------------------
  109. //
  110. // Member: PrivateQueryInterface
  111. //
  112. // Synopsis:
  113. //
  114. //---------------------------------------------------------------
  115. HRESULT CGWNote::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
  116. {
  117. if(!lplpObj)
  118. return E_INVALIDARG;
  119. *lplpObj = NULL;
  120. if (IsEqualIID(riid, IID_IUnknown))
  121. *lplpObj = (LPVOID)(IPersistMime *)this;
  122. else if (IsEqualIID(riid, IID_IServiceProvider))
  123. *lplpObj = (LPVOID)(IServiceProvider *)this;
  124. else if (IsEqualIID(riid, IID_IPersistMime))
  125. *lplpObj = (LPVOID)(IPersistMime *)this;
  126. else if (IsEqualIID(riid, IID_IMsoEnvelopeSite))
  127. *lplpObj = (LPVOID)(IMsoEnvelopeSite *)this;
  128. else if (IsEqualIID(riid, IID_IMsoComponentManager))
  129. *lplpObj = (LPVOID)(IMsoComponentManager *)this;
  130. else
  131. {
  132. return E_NOINTERFACE;
  133. }
  134. AddRef();
  135. return NOERROR;
  136. }
  137. //+---------------------------------------------------------------
  138. //
  139. // Member: GetClassID
  140. //
  141. // Synopsis:
  142. //
  143. //---------------------------------------------------------------
  144. HRESULT CGWNote::GetClassID(CLSID *pClassID)
  145. {
  146. *pClassID = CLSID_GWEnvelopeHost;
  147. return NOERROR;
  148. }
  149. // *** IServiceProvider ***
  150. //+---------------------------------------------------------------
  151. //
  152. // Member: QueryService
  153. //
  154. // Synopsis:
  155. //
  156. //---------------------------------------------------------------
  157. HRESULT CGWNote::QueryService(REFGUID guidService, REFIID riid, LPVOID *ppvObject)
  158. {
  159. if (IsEqualGUID(guidService, IID_IMsoComponentManager))
  160. return PrivateQueryInterface(riid, ppvObject);
  161. return E_NOINTERFACE;
  162. }
  163. // *** IPersistMime ***
  164. //+---------------------------------------------------------------
  165. //
  166. // Member: Load
  167. //
  168. // Synopsis:
  169. //
  170. //---------------------------------------------------------------
  171. HRESULT CGWNote::Load(IMimeMessage *pMsg)
  172. {
  173. return E_NOTIMPL;
  174. }
  175. //+---------------------------------------------------------------
  176. //
  177. // Member: Save
  178. //
  179. // Synopsis:
  180. //
  181. //---------------------------------------------------------------
  182. HRESULT CGWNote::Save(IMimeMessage *pMsg, DWORD dwFlags)
  183. {
  184. IPersistMime *pPM;
  185. IStream *pstm;
  186. HRESULT hr;
  187. // save envelope props
  188. if (m_pEnv &&
  189. m_pEnv->QueryInterface(IID_IPersistMime, (LPVOID *)&pPM)==S_OK)
  190. {
  191. hr = pPM->Save(pMsg, dwFlags);
  192. pPM->Release();
  193. }
  194. // save body props
  195. if (MimeOleCreateVirtualStream(&pstm)==S_OK)
  196. {
  197. if (HrRicheditStreamOut(m_hwndRE, pstm, SF_TEXT)==S_OK)
  198. pMsg->SetTextBody(TXT_PLAIN, IET_BINARY, NULL, pstm, NULL);
  199. pstm->Release();
  200. }
  201. return hr;
  202. }
  203. HRESULT CGWNote::RequestResize(int *pcHeight)
  204. {
  205. RECT rc;
  206. m_cyEnv = *pcHeight;
  207. GetClientRect(m_hwnd, &rc);
  208. rc.top +=2;
  209. rc.bottom = m_cyEnv+2;
  210. m_pEnv->Resize(&rc);
  211. GetClientRect(m_hwnd, &rc);
  212. rc.top += m_cyEnv + 4;
  213. rc.bottom -=2;
  214. SetWindowPos(m_hwndRE, NULL, 0, rc.top, rc.right-rc.left, rc.bottom-rc.top, SWP_NOZORDER);
  215. return S_OK;
  216. }
  217. HRESULT CGWNote::CloseNote(DWORD grfClose)
  218. {
  219. SendMessage(m_hwnd, WM_CLOSE, 0, 0);
  220. return S_OK;
  221. }
  222. HRESULT CGWNote::GetBody(IStream *pstm, DWORD dwCodePage, DWORD grfBody)
  223. {
  224. return E_NOTIMPL;
  225. }
  226. HRESULT CGWNote::SetBody(IStream *pstm, DWORD dwCodePage, DWORD grfBody)
  227. {
  228. return S_OK;
  229. }
  230. HRESULT CGWNote::SetFocus(BOOL fTab)
  231. {
  232. if (fTab)
  233. ::SetFocus(m_hwndRE);
  234. return S_OK;
  235. }
  236. HRESULT CGWNote::OnEnvSetFocus()
  237. {
  238. return S_OK;
  239. }
  240. HRESULT CGWNote::OnPropChange(ULONG dispid)
  241. {
  242. return S_OK;
  243. }
  244. HRESULT CGWNote::IsBodyDirty()
  245. {
  246. return S_OK;
  247. }
  248. HRESULT CGWNote::HandsOff()
  249. {
  250. return S_OK;
  251. }
  252. HRESULT CGWNote::GetMsoInst(HMSOINST *phinst)
  253. {
  254. return E_NOTIMPL;
  255. }
  256. HRESULT CGWNote::GetFrameWnd(HWND *phwndFrame)
  257. {
  258. return E_NOTIMPL;
  259. }
  260. HRESULT CGWNote::DisplayMessage(HRESULT hr, LPCWSTR wszError, DWORD grfMsg)
  261. {
  262. return S_OK;
  263. }
  264. LRESULT CGWNote::ExtWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  265. {
  266. CGWNote *pNote;
  267. if(msg==WM_CREATE)
  268. {
  269. pNote=(CGWNote *)((LPCREATESTRUCT)lParam)->lpCreateParams;
  270. if(!pNote)
  271. return -1;
  272. if(FAILED(pNote->OnCreate(hwnd)))
  273. return -1;
  274. }
  275. pNote = (CGWNote *)GetWndThisPtr(hwnd);
  276. if(pNote)
  277. return pNote->WndProc(hwnd, msg, wParam, lParam);
  278. else
  279. return DefWindowProc(hwnd, msg, wParam, lParam);
  280. }
  281. LRESULT CGWNote::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  282. {
  283. LONG lret;
  284. switch (msg)
  285. {
  286. case WM_NOTIFY:
  287. return (WMNotify(wParam, (NMHDR *)lParam)==S_OK);
  288. case WM_COMMAND:
  289. if (WMCommand( GET_WM_COMMAND_HWND(wParam, lParam),
  290. GET_WM_COMMAND_ID(wParam, lParam),
  291. GET_WM_COMMAND_CMD(wParam, lParam))==S_OK)
  292. return 0;
  293. break;
  294. case WM_SIZE:
  295. RequestResize((int *)&m_cyEnv);
  296. break;
  297. case WM_NCDESTROY:
  298. OnNCDestroy();
  299. break;
  300. }
  301. lret = DefWindowProc(hwnd, msg, wParam, lParam);
  302. if(msg==WM_ACTIVATE)
  303. {
  304. // post-process wm_activates to set focus back to
  305. // control
  306. SaveFocus((BOOL)(LOWORD(wParam)), &m_hwndFocus);
  307. g_pActiveNote = (LOWORD(wParam)==WA_INACTIVE)?NULL:this;
  308. }
  309. return lret;
  310. }
  311. HRESULT CGWNote::Init(REFCLSID clsidEnvelope, DWORD dwFlags)
  312. {
  313. HRESULT hr=S_OK;
  314. HWND hwnd;
  315. WNDCLASS wc;
  316. HMENU hMenu;
  317. TraceCall("CDocHost::Init");
  318. if (!GetClassInfo(g_hInst, c_szGWNoteWndClass, &wc))
  319. {
  320. ZeroMemory(&wc, sizeof(WNDCLASS));
  321. wc.lpfnWndProc = CGWNote::ExtWndProc;
  322. wc.hInstance = g_hInst;
  323. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  324. wc.lpszClassName = c_szGWNoteWndClass;
  325. wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  326. wc.style = CS_DBLCLKS;
  327. if(!RegisterClass(&wc))
  328. return E_OUTOFMEMORY;
  329. }
  330. hMenu = LoadMenu(g_hInst, "GWNOTEMENU");
  331. if (!hMenu)
  332. return E_OUTOFMEMORY;
  333. hwnd=CreateWindowEx(WS_EX_WINDOWEDGE|WS_EX_CONTROLPARENT,
  334. c_szGWNoteWndClass,
  335. "GW Note Control",
  336. WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
  337. 0,
  338. 0,
  339. 400,
  340. 400,
  341. NULL,
  342. hMenu,
  343. g_hInst,
  344. (LPVOID)this);
  345. if(!hwnd)
  346. {
  347. hr=E_OUTOFMEMORY;
  348. goto error;
  349. }
  350. hr = InitEnvelope(clsidEnvelope, dwFlags);
  351. error:
  352. return hr;
  353. }
  354. HRESULT CGWNote::OnCreate(HWND hwnd)
  355. {
  356. CHARFORMAT cf={0};
  357. m_hwnd = hwnd;
  358. SetWindowLong(hwnd, GWL_USERDATA, (LPARAM)this);
  359. m_hwndRE = CreateWindowEx(WS_EX_CLIENTEDGE,
  360. "RichEdit",
  361. "",
  362. //ES_MULTILINE|ES_SAVESEL|ES_AUTOVSCROLL|ES_SELECTIONBAR|ES_WANTRETURN|WS_VSCROLL|WS_CHILD|WS_TABSTOP|WS_VISIBLE,
  363. ES_SAVESEL|ES_WANTRETURN|ES_MULTILINE|WS_CHILD|WS_TABSTOP|WS_VISIBLE|ES_AUTOVSCROLL|WS_VSCROLL,
  364. 0, 0, 0, 0,
  365. hwnd,
  366. (HMENU)99,
  367. g_hInst,
  368. NULL);
  369. if (!m_hwndRE)
  370. return E_FAIL;
  371. cf.cbSize = sizeof(CHARFORMAT);
  372. cf.dwMask = CFM_COLOR|CFM_FACE;
  373. cf.crTextColor = RGB(0,0,255);
  374. lstrcpy(cf.szFaceName, "Verdana");
  375. SendMessage(m_hwndRE, EM_SETCHARFORMAT, 0, (LPARAM)&cf);
  376. SendMessage(m_hwndRE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
  377. SendMessage(m_hwndRE, EM_SETEVENTMASK, 0, ENM_KEYEVENTS);
  378. AddRef();
  379. return S_OK;
  380. }
  381. HRESULT CGWNote::OnNCDestroy()
  382. {
  383. SafeRelease(m_pEnv);
  384. if (m_pComponent)
  385. {
  386. m_pComponent->Terminate();
  387. SafeRelease(m_pComponent);
  388. }
  389. SetWindowLong(m_hwnd, GWL_USERDATA, NULL);
  390. m_hwnd = NULL;
  391. Release();
  392. return S_OK;
  393. }
  394. HRESULT CGWNote::Show()
  395. {
  396. ShowWindow(m_hwnd, SW_SHOW);
  397. return S_OK;
  398. }
  399. HRESULT CGWNote::InitEnvelope(REFCLSID clsidEnvelope, DWORD dwFlags)
  400. {
  401. HRESULT hr;
  402. RECT rc;
  403. hr = CoCreateInstance(clsidEnvelope, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, IID_IMsoEnvelope, (LPVOID *)&m_pEnv);
  404. if (FAILED(hr))
  405. goto error;
  406. hr = m_pEnv->Init(NULL, (IMsoEnvelopeSite *)this, dwFlags);
  407. if (FAILED(hr))
  408. goto error;
  409. hr = m_pEnv->SetParent(m_hwnd);
  410. if (FAILED(hr))
  411. goto error;
  412. hr = m_pEnv->Show(TRUE);
  413. if (FAILED(hr))
  414. goto error;
  415. m_pEnv->SetFocus(ENV_FOCUS_INITIAL);
  416. error:
  417. return hr;
  418. }
  419. HRESULT CGWNote::TranslateAcclerator(MSG *lpmsg)
  420. {
  421. if (!g_hAccelMailSend)
  422. g_hAccelMailSend= LoadAccelerators(g_hInst, MAKEINTRESOURCE(idacMail_SendNote));
  423. if (::TranslateAccelerator(m_hwnd, g_hAccelMailSend, lpmsg))
  424. return S_OK;
  425. if (m_pComponent &&
  426. m_pComponent->FPreTranslateMessage(lpmsg))
  427. return S_OK;
  428. return S_FALSE;
  429. }
  430. DWORD CALLBACK EditStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
  431. {
  432. return ((LPSTREAM)dwCookie)->Write(pbBuff, cb, (ULONG *)pcb);
  433. }
  434. HRESULT HrRicheditStreamOut(HWND hwndRE, LPSTREAM pstm, ULONG uSelFlags)
  435. {
  436. EDITSTREAM es;
  437. if(!pstm)
  438. return E_INVALIDARG;
  439. if(!IsWindow(hwndRE))
  440. return E_INVALIDARG;
  441. HrRewindStream(pstm);
  442. es.dwCookie = (DWORD)pstm;
  443. es.pfnCallback=(EDITSTREAMCALLBACK)EditStreamOutCallback;
  444. SendMessage(hwndRE, EM_STREAMOUT, uSelFlags, (LONG)&es);
  445. return S_OK;
  446. }
  447. BOOL CGWNote::FRegisterComponent(IMsoComponent *piComponent, const MSOCRINFO *pcrinfo, DWORD *pdwComponentID)
  448. {
  449. if (m_pComponent) // only one register allowed
  450. return E_FAIL;
  451. ReplaceInterface(m_pComponent, piComponent);
  452. *pdwComponentID=666;
  453. return TRUE;
  454. }
  455. BOOL CGWNote::FRevokeComponent(DWORD dwComponentID)
  456. {
  457. return TRUE;
  458. }
  459. BOOL CGWNote::FUpdateComponentRegistration(DWORD dwComponentID, const MSOCRINFO *pcrinfo)
  460. {
  461. return FALSE;
  462. }
  463. BOOL CGWNote::FOnComponentActivate(DWORD dwComponentID)
  464. {
  465. return FALSE;
  466. }
  467. BOOL CGWNote::FSetTrackingComponent(DWORD dwComponentID, BOOL fTrack)
  468. {
  469. return FALSE;
  470. }
  471. void CGWNote::OnComponentEnterState(DWORD dwComponentID, ULONG uStateID, ULONG uContext,ULONG cpicmExclude,IMsoComponentManager **rgpicmExclude, DWORD dwReserved)
  472. {
  473. }
  474. BOOL CGWNote::FOnComponentExitState(DWORD dwComponentID, ULONG uStateID, ULONG uContext,ULONG cpicmExclude,IMsoComponentManager **rgpicmExclude)
  475. {
  476. return FALSE;
  477. }
  478. BOOL CGWNote::FInState(ULONG uStateID, void *pvoid)
  479. {
  480. return FALSE;
  481. }
  482. BOOL CGWNote::FContinueIdle ()
  483. {
  484. return FALSE;
  485. }
  486. BOOL CGWNote::FPushMessageLoop(DWORD dwComponentID, ULONG uReason, void *pvLoopData)
  487. {
  488. return FALSE;
  489. }
  490. BOOL CGWNote::FCreateSubComponentManager(IUnknown *piunkOuter, IUnknown *piunkServProv,REFIID riid, void **ppvObj)
  491. {
  492. return FALSE;
  493. }
  494. BOOL CGWNote::FGetParentComponentManager(IMsoComponentManager **ppicm)
  495. {
  496. return FALSE;
  497. }
  498. BOOL CGWNote::FGetActiveComponent(DWORD dwgac, IMsoComponent **ppic, MSOCRINFO *pcrinfo, DWORD dwReserved)
  499. {
  500. return FALSE;
  501. }
  502. BOOL CGWNote::FDebugMessage(HMSOINST hinst, UINT message, WPARAM wParam, LPARAM lParam)
  503. {
  504. return FALSE;
  505. }
  506. HRESULT CGWNote::WMCommand(HWND hwndCmd, int id, WORD wCmd)
  507. {
  508. if (wCmd > 1)
  509. return S_FALSE;
  510. switch(id)
  511. {
  512. case idmNewMsg:
  513. ShellExecute(m_hwnd, NULL, "mailto:", 0, 0, SW_SHOW);
  514. return S_OK;
  515. case idmProperties:
  516. MessageBox(m_hwnd, "PlaceHolder", "Properties", MB_OK);
  517. return S_OK;
  518. case idmSaveAs:
  519. return SaveAs();
  520. case idmClose:
  521. PostMessage(m_hwnd, WM_CLOSE, 0, 0);
  522. return S_OK;
  523. case idmCheckNames:
  524. return HrHeaderExecCommand(MSOEENVCMDID_CHECKNAMES, MSOCMDEXECOPT_PROMPTUSER, NULL);
  525. case idmPickRecipients:
  526. return HrHeaderExecCommand(MSOEENVCMDID_SELECTRECIPIENTS, MSOCMDEXECOPT_DODEFAULT, NULL);
  527. case idmViewContacts:
  528. return HrHeaderExecCommand(MSOEENVCMDID_VIEWCONTACTS, MSOCMDEXECOPT_DODEFAULT, NULL);
  529. default:
  530. MessageBox(m_hwnd, "Not Yet Implemented", "Menu Command", MB_OK);
  531. return S_OK;
  532. }
  533. return S_FALSE;
  534. }
  535. HRESULT CGWNote::HrHeaderExecCommand(UINT uCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn)
  536. {
  537. HRESULT hr = S_FALSE;
  538. IOleCommandTarget *pCmdTarget;
  539. if(m_pEnv &&
  540. m_pEnv->QueryInterface(IID_IOleCommandTarget, (LPVOID *)&pCmdTarget)==S_OK)
  541. {
  542. hr = pCmdTarget->Exec(&CGID_Envelope, uCmdID, nCmdExecOpt, pvaIn, NULL);
  543. pCmdTarget->Release();
  544. }
  545. return hr;
  546. }
  547. HRESULT CGWNote::WMNotify(int idFrom, NMHDR *pnmh)
  548. {
  549. MSGFILTER *pmf=(MSGFILTER *)pnmh;
  550. BOOL fShift;
  551. switch (pnmh->code)
  552. {
  553. case EN_MSGFILTER:
  554. if (pmf->msg == WM_KEYDOWN && pmf->wParam == VK_TAB && !(GetKeyState(VK_CONTROL) & 0x8000))
  555. {
  556. // shift tab puts focus in the envelope
  557. if (GetKeyState(VK_SHIFT)&0x8000 && m_pEnv)
  558. {
  559. m_pEnv->SetFocus(ENV_FOCUS_TAB);
  560. return S_OK;
  561. }
  562. }
  563. break;
  564. }
  565. return S_FALSE;
  566. }
  567. void SaveFocus(BOOL fActive, HWND *phwnd)
  568. {
  569. if(fActive&&IsWindow(*phwnd))
  570. SetFocus(*phwnd);
  571. else
  572. *phwnd=GetFocus();
  573. }
  574. static char c_szFilter[] = "Rfc 822 Messages (*.eml)\0*.eml\0\0";
  575. HRESULT CGWNote::SaveAs()
  576. {
  577. OPENFILENAME ofn;
  578. TCHAR szFile[MAX_PATH];
  579. TCHAR szTitle[MAX_PATH];
  580. TCHAR szDefExt[30];
  581. WCHAR szFileW[MAX_PATH];
  582. lstrcpy(szFile, "c:\\*.eml");
  583. lstrcpy(szDefExt, ".eml");
  584. lstrcpy(szTitle, "Save Message As...");
  585. ZeroMemory (&ofn, sizeof (ofn));
  586. ofn.lStructSize = sizeof (ofn);
  587. ofn.hwndOwner = m_hwnd;
  588. ofn.lpstrFilter = c_szFilter;
  589. ofn.nFilterIndex = 1;
  590. ofn.lpstrFile = szFile;
  591. ofn.nMaxFile = sizeof (szFile);
  592. ofn.lpstrTitle = szTitle;
  593. ofn.lpstrDefExt = szDefExt;
  594. ofn.Flags = OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;
  595. if (*szFile==NULL)
  596. return E_FAIL;
  597. // Show OpenFile Dialog
  598. if (!GetSaveFileName(&ofn))
  599. return MIMEEDIT_E_USERCANCEL;
  600. MultiByteToWideChar(CP_ACP, 0, szFile, -1, szFileW, MAX_PATH);
  601. return SaveToFile(szFileW);
  602. }
  603. HRESULT CGWNote::SaveToFile(LPWSTR pszW)
  604. {
  605. IPersistMime *ppm;
  606. IPersistFile *pPF;
  607. IMimeMessage *pMsg;
  608. HRESULT hr;
  609. hr = CoCreateInstance(CLSID_IMimeMessage, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&pMsg);
  610. if (!FAILED(hr))
  611. {
  612. pMsg->InitNew();
  613. hr = pMsg->QueryInterface(IID_IPersistFile, (LPVOID *)&pPF);
  614. if (!FAILED(hr))
  615. {
  616. hr = Save(pMsg, 0);
  617. if (!FAILED(hr))
  618. {
  619. hr = pPF->Save(pszW, FALSE);
  620. }
  621. pPF->Release();
  622. }
  623. pMsg->Release();
  624. }
  625. return hr;
  626. }
  627. HRESULT CGWNote::DirtyToolbars(void)
  628. {
  629. return S_OK;
  630. }
  631. HRESULT CGWNote::SetHelpMode(BOOL fEnter)
  632. {
  633. return S_OK;
  634. }
  635. HRESULT CGWNote::TranslateAccelerators(MSG *pMsg)
  636. {
  637. return S_FALSE;
  638. }