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.

1298 lines
43 KiB

  1. // --------------------------------------------------------------------------------
  2. // Moletest.cpp
  3. // --------------------------------------------------------------------------------
  4. #define DEFINE_STRCONST
  5. #define INITGUID
  6. #include <windows.h>
  7. #include <windowsx.h>
  8. #include <richedit.h>
  9. #include <commctrl.h>
  10. #include <initguid.h>
  11. #include <ole2.h>
  12. #include <stdio.h>
  13. #include <conio.h>
  14. #include "resource.h"
  15. #include <d:\foobar\inc\Mimeole.h>
  16. IMimeOleMalloc *g_pMalloc=NULL;
  17. // --------------------------------------------------------------------------------
  18. // Prototypes
  19. // --------------------------------------------------------------------------------
  20. void MoleTestHeader(IStorage *pStorage);
  21. void MoleTestBody(IStorage *pStorage);
  22. INT_PTR CALLBACK MimeOLETest(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  23. INT_PTR CALLBACK RichStreamShow(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  24. // --------------------------------------------------------------------------------
  25. // Simple (UNSAFE) conversion to UNICODE
  26. // --------------------------------------------------------------------------------
  27. OLECHAR* ConvertToUnicode(char *szA)
  28. {
  29. static OLECHAR achW[1024];
  30. MultiByteToWideChar(CP_ACP, 0, szA, -1, achW, 1024);
  31. return achW;
  32. }
  33. // --------------------------------------------------------------------------------
  34. // Simple (UNSAFE) conversion to ANSI
  35. // --------------------------------------------------------------------------------
  36. char* ConvertToAnsi(OLECHAR FAR* szW)
  37. {
  38. static char achA[1024];
  39. WideCharToMultiByte(CP_ACP, 0, szW, -1, achA, 1024, NULL, NULL);
  40. return achA;
  41. }
  42. // --------------------------------------------------------------------------------
  43. // Moletest entry point
  44. // --------------------------------------------------------------------------------
  45. void main(int argc, char *argv[])
  46. {
  47. // Locals
  48. CHAR szDocFile[MAX_PATH];
  49. IStorage *pStorage=NULL;
  50. HRESULT hr;
  51. HINSTANCE hRichEdit=NULL;
  52. // Must have a path to a .stg file...
  53. if (argc != 2)
  54. {
  55. printf("Please enter the path and file name that mbxtodoc.exe generated: ");
  56. scanf("%s", szDocFile);
  57. fflush(stdin);
  58. }
  59. // Otherwise, copy parmaeter
  60. else
  61. lstrcpyn(szDocFile, argv[1], sizeof(szDocFile));
  62. hRichEdit = LoadLibrary("RICHED32.DLL");
  63. // Init OLE
  64. hr = CoInitialize(NULL);
  65. if (FAILED(hr))
  66. {
  67. printf("Error - Unable to initialize OLE.\n");
  68. exit(1);
  69. }
  70. // Get IMimeOleMalloc
  71. hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeOleMalloc, (LPVOID *)&g_pMalloc);
  72. if (FAILED(hr))
  73. {
  74. printf("Error - CoCreateInstance of CLSID_MIMEOLE\\IID_IMimeOleMalloc failed.\n");
  75. goto exit;
  76. }
  77. // Status
  78. printf("Opening source docfile: %s\n", szDocFile);
  79. // Get file
  80. /*
  81. hr = StgOpenStorage(ConvertToUnicode(szDocFile), NULL, STGM_TRANSACTED | STGM_NOSCRATCH | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &pStorage);
  82. if (FAILED(hr))
  83. {
  84. printf("StgOpenStorage failed\n");
  85. goto exit;
  86. }
  87. */
  88. DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_TEST), NULL, MimeOLETest, (LPARAM)szDocFile);
  89. //MoleTestBody(pStorage);
  90. exit:
  91. // Cleanup
  92. if (hRichEdit)
  93. FreeLibrary(hRichEdit);
  94. if (pStorage)
  95. pStorage->Release();
  96. if (g_pMalloc)
  97. g_pMalloc->Release();
  98. // Un-init OLE
  99. CoUninitialize();
  100. // Done
  101. return;
  102. }
  103. // --------------------------------------------------------------------------------
  104. // This is the IMimeHeader torture test
  105. // --------------------------------------------------------------------------------
  106. void MoleTestHeader(IStorage *pStorage)
  107. {
  108. // Locals
  109. IMimeHeader *pHeader=NULL;
  110. IEnumSTATSTG *pEnum=NULL;
  111. IStream *pStream=NULL;
  112. STATSTG rElement;
  113. ULONG i, c;
  114. HRESULT hr=S_OK;
  115. CHAR szData[50];
  116. IStream *pSave=NULL, *pstmHeader=NULL;
  117. IMimeEnumHeaderLines *pEnumLines=NULL;
  118. LPSTR pszData;
  119. // Status
  120. printf("Starting IMimeHeader torture test...\n");
  121. // Create a header object...
  122. hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeHeader, (LPVOID *)&pHeader);
  123. if (FAILED(hr))
  124. {
  125. printf("Error - CoCreateInstance of CLSID_Mime\\IID_IMimeHeader failed.\n");
  126. goto exit;
  127. }
  128. // Get storage enumerator
  129. hr = pStorage->EnumElements(0, NULL, 0, &pEnum);
  130. if (FAILED(hr))
  131. {
  132. printf("Error - IStorage::EnumElements failed.\n");
  133. goto exit;
  134. }
  135. // Enumerate
  136. for(i=0;;i++)
  137. {
  138. // Status
  139. //printf("Message: %d\n", i);
  140. // Get element
  141. hr = pEnum->Next(1, &rElement, &c);
  142. if (FAILED(hr))
  143. break;
  144. if (c == 0)
  145. break;
  146. // No Name ?
  147. if (NULL == rElement.pwcsName)
  148. continue;
  149. // Open the stream...
  150. hr = pStorage->OpenStream(rElement.pwcsName, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &pStream);
  151. if (FAILED(hr))
  152. {
  153. printf("IStorage::OpenStream failed: (iMsg = %d)\n", i);
  154. goto nextmsg;
  155. }
  156. // Load the header...
  157. hr = pHeader->Load(pStream);
  158. if (FAILED(hr))
  159. {
  160. printf("IMimeHeader::Load failed (HR = %08X): (iMsg = %d)\n", hr, i);
  161. goto nextmsg;
  162. }
  163. #if 0
  164. // Test Enumerator
  165. hr = pHeader->EnumHeaderLines(NULL, &pEnumLines);
  166. if (FAILED(hr))
  167. printf("IMimeHeader::EnumLines failed (HR = %08X): (iMsg = %d)\n", hr, i);
  168. else
  169. {
  170. ULONG cLines;
  171. //ULONG x;
  172. HEADERLINE rgLine[2];
  173. while(SUCCEEDED(pEnumLines->Next(2, rgLine, &cLines)) && cLines)
  174. {
  175. //for (x=0; x<cLines; x++)
  176. // printf("%s: %s\n", prgLine[x].pszHeader, prgLine[x].pszLine);
  177. g_pMalloc->FreeHeaderLineArray(cLines, rgLine, FALSE);
  178. }
  179. pEnumLines->Release();
  180. pEnumLines = NULL;
  181. }
  182. // Test Enumerator
  183. hr = pHeader->EnumHeaderLines("Received", &pEnumLines);
  184. if (FAILED(hr))
  185. printf("IMimeHeader::EnumLines failed (HR = %08X): (iMsg = %d)\n", hr, i);
  186. else
  187. {
  188. ULONG cLines;
  189. //ULONG x;
  190. HEADERLINE rgLine[2];
  191. while(SUCCEEDED(pEnumLines->Next(2, rgLine, &cLines)) && cLines)
  192. {
  193. //for (x=0; x<cLines; x++);
  194. // printf("%s: %s\n", prgLine[x].pszHeader, prgLine[x].pszLine);
  195. g_pMalloc->FreeHeaderLineArray(cLines, rgLine, FALSE);
  196. }
  197. pEnumLines->Release();
  198. pEnumLines = NULL;
  199. }
  200. // Test IMimeHeader Interface
  201. pHeader->IsContentType(NULL, NULL);
  202. pHeader->IsContentType(STR_CNT_MESSAGE, NULL);
  203. pHeader->IsContentType(NULL, STR_SUB_PLAIN);
  204. // ****************************************************************************************
  205. // Get a few items...
  206. if (i == 0)
  207. pHeader->GetInetProp(NULL, NULL);
  208. pszData = NULL;
  209. hr = pHeader->GetInetProp("To", &pszData);
  210. if (FAILED(hr) && hr != MIME_E_NOT_FOUND)
  211. printf("IMimeHeader::GetInetProp(\"To\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  212. else if (pszData)
  213. g_pMalloc->Free(pszData);
  214. // Get a few items...
  215. pszData = NULL;
  216. hr = pHeader->GetInetProp("Subject", &pszData);
  217. if (FAILED(hr) && hr != MIME_E_NOT_FOUND)
  218. printf("IMimeHeader::GetInetProp(\"Subject\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  219. else if (pszData)
  220. g_pMalloc->Free(pszData);
  221. // Get a few items... (multi-line header)
  222. pszData = NULL;
  223. hr = pHeader->GetInetProp("Received", &pszData);
  224. if (FAILED(hr) && hr != MIME_E_NOT_FOUND)
  225. printf("IMimeHeader::GetInetProp(\"Received\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  226. else if (pszData)
  227. g_pMalloc->Free(pszData);
  228. // Get a few items... (multi-line header)
  229. pszData = NULL;
  230. hr = pHeader->GetInetProp("Content-Type", &pszData);
  231. if (FAILED(hr) && hr != MIME_E_NOT_FOUND)
  232. printf("IMimeHeader::GetInetProp(\"Content-Type\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  233. else if (pszData)
  234. g_pMalloc->Free(pszData);
  235. // ****************************************************************************************
  236. // Prepare a line to set in a bunch of items...
  237. wsprintf(szData, "<Message@%s>", ConvertToAnsi(rElement.pwcsName));
  238. // Set a few items...
  239. if (i == 0)
  240. pHeader->SetInetProp(NULL, NULL);
  241. hr = pHeader->SetInetProp("To", szData);
  242. if (FAILED(hr))
  243. printf("IMimeHeader::SetInetProp(\"To\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  244. // Get a few items...
  245. hr = pHeader->SetInetProp("Subject", szData);
  246. if (FAILED(hr))
  247. printf("IMimeHeader::SetInetProp(\"Subject\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  248. // Get a few items... (multi-line header)
  249. hr = pHeader->SetInetProp("Received", szData);
  250. if (FAILED(hr))
  251. printf("IMimeHeader::SetInetProp(\"Received\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  252. // Get a few items... (multi-line header)
  253. hr = pHeader->SetInetProp("Content-Type", "multipart\\related");
  254. if (FAILED(hr))
  255. printf("IMimeHeader::SetInetProp(\"Content-Type\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  256. // ****************************************************************************************
  257. // Delete a few items
  258. if (i == 0)
  259. pHeader->DelInetProp(NULL);
  260. hr = pHeader->DelInetProp("MIME-Version");
  261. if (FAILED(hr) && hr != MIME_E_NOT_FOUND)
  262. printf("IMimeHeader::DelInetProp(\"MIME-Version\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  263. // Delete a few items
  264. hr = pHeader->DelInetProp("Content-Disposition");
  265. if (FAILED(hr) && hr != MIME_E_NOT_FOUND)
  266. printf("IMimeHeader::DelInetProp(\"Content-Disposition\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  267. // ****************************************************************************************
  268. // Get some parameters
  269. if (i == 0)
  270. {
  271. pHeader->SetInetProp(NULL, NULL);
  272. pHeader->GetInetProp("Content-Type", NULL);
  273. pHeader->GetInetProp("par:content-type:name", NULL);
  274. }
  275. pszData = NULL;
  276. pHeader->GetInetProp("par:content-type:name", &pszData);
  277. if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA)
  278. printf("IMimeHeader::GetInetProp(...,\"name\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  279. else if (pszData)
  280. g_pMalloc->Free(pszData);
  281. pszData = NULL;
  282. hr = pHeader->GetInetProp("par:Content-Disposition:filename", &pszData);
  283. if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA)
  284. printf("IMimeHeader::GetInetProp(...,\"filename\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  285. else if (pszData)
  286. g_pMalloc->Free(pszData);
  287. pszData = NULL;
  288. hr = pHeader->GetInetProp("par:Content-Type:charset", &pszData);
  289. if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA)
  290. printf("IMimeHeader::GetInetProp(...,\"charset\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  291. else if (pszData)
  292. g_pMalloc->Free(pszData);
  293. pszData = NULL;
  294. hr = pHeader->GetInetProp("par:Content-Type:boundary", &pszData);
  295. if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA)
  296. printf("IMimeHeader::GetInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  297. else if (pszData)
  298. g_pMalloc->Free(pszData);
  299. pszData = NULL;
  300. hr = pHeader->GetInetProp("par:Content-Type:part", &pszData);
  301. if (FAILED(hr) && hr != MIME_E_NOT_FOUND && hr != MIME_E_NO_DATA)
  302. printf("IMimeHeader::GetInetProp(...,\"part\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  303. else if (pszData)
  304. g_pMalloc->Free(pszData);
  305. // ****************************************************************************************
  306. // Set some parameters
  307. if (i == 0)
  308. {
  309. pHeader->SetInetProp(NULL, NULL);
  310. pHeader->SetInetProp("Content-Type", NULL);
  311. pHeader->SetInetProp("par:Content-Type:name", NULL);
  312. }
  313. hr = pHeader->SetInetProp("par:Content-Type:name", szData);
  314. if (FAILED(hr))
  315. printf("IMimeHeader::SetInetProp(...,\"name\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  316. hr = pHeader->SetInetProp("par:Content-Disposition:filename", szData);
  317. if (FAILED(hr))
  318. printf("IMimeHeader::SetInetProp(...,\"filename\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  319. hr = pHeader->SetInetProp("par:Content-Type:charset", szData);
  320. if (FAILED(hr))
  321. printf("IMimeHeader::SetInetProp(...,\"charset\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  322. hr = pHeader->SetInetProp("par:content-type:boundary", szData);
  323. if (FAILED(hr))
  324. printf("IMimeHeader::SetInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  325. hr = pHeader->SetInetProp("par:content-type:part", szData);
  326. if (FAILED(hr))
  327. printf("IMimeHeader::SetInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  328. hr = pHeader->DelInetProp("par:content-type:part");
  329. if (FAILED(hr))
  330. printf("IMimeHeader::DelInetProp(...,\"boundary\") failed (HR = %08X): (iMsg = %d)\n", hr, i);
  331. // ****************************************************************************************
  332. // Try to save it back
  333. if (i == 0)
  334. pHeader->GetSizeMax(NULL);
  335. //hr = pHeader->GetSizeMax(&uli);
  336. //if (FAILED(hr))
  337. // printf("IMimeHeader::GetSizeMax() failed (HR = %08X): (iMsg = %d)\n", hr, i);
  338. hr = pHeader->IsDirty();
  339. if (FAILED(hr))
  340. printf("IMimeHeader::IsDirty() failed (HR = %08X): (iMsg = %d)\n", hr, i);
  341. CreateStreamOnHGlobal(NULL, TRUE, &pstmHeader);
  342. hr = pHeader->Save(pstmHeader, TRUE);
  343. if (FAILED(hr))
  344. printf("IMimeHeader::Save() failed (HR = %08X): (iMsg = %d)\n", hr, i);
  345. pstmHeader->Release();
  346. #endif
  347. nextmsg:
  348. // Cleanup
  349. pStream->Release();
  350. pStream = NULL;
  351. // Free the name
  352. CoTaskMemFree(rElement.pwcsName);
  353. }
  354. exit:
  355. // Cleanup
  356. if (pEnum)
  357. pEnum->Release();
  358. if (pHeader)
  359. pHeader->Release();
  360. if (pStream)
  361. pStream->Release();
  362. if (pEnumLines)
  363. pEnumLines->Release();
  364. // Done
  365. return;
  366. }
  367. // --------------------------------------------------------------------------------
  368. // This is the IMimeBody torture test
  369. // --------------------------------------------------------------------------------
  370. void MoleTestBody(IStorage *pStorage)
  371. {
  372. // Locals
  373. IMimeMessage *pMessage=NULL;
  374. IEnumSTATSTG *pEnum=NULL;
  375. IStream *pStream=NULL,
  376. *pstmTree=NULL;
  377. STATSTG rElement;
  378. ULONG i, c, cbRead, x;
  379. HRESULT hr=S_OK;
  380. LARGE_INTEGER liOrigin = {0,0};
  381. HBODY hBody;
  382. IMimeBody *pBody=NULL;
  383. IStream *pBodyStream=NULL;
  384. BYTE rgbBuffer[1024];
  385. FINDBODY rFindBody;
  386. FILETIME ft;
  387. IMimeMessageParts *pParts=NULL;
  388. IStream *pSave=NULL;
  389. IDataObject *pDataObject=NULL;
  390. IMimeAddressTable *pAddressTable=NULL;
  391. LPSTR pszData=NULL;
  392. IMimeMessage *pCombine=NULL;
  393. IMimeBody *pRootBody=NULL;
  394. // Status
  395. printf("Starting IMimeBody torture test...\n");
  396. // Create a header object...
  397. hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&pMessage);
  398. if (FAILED(hr))
  399. {
  400. printf("Error - CoCreateInstance of CLSID_Mime\\IID_IMimeBody failed.\n");
  401. goto exit;
  402. }
  403. // Get storage enumerator
  404. hr = pStorage->EnumElements(0, NULL, 0, &pEnum);
  405. if (FAILED(hr))
  406. {
  407. printf("Error - IStorage::EnumElements failed.\n");
  408. goto exit;
  409. }
  410. // Enumerate
  411. for(i=0;;i++)
  412. {
  413. // Status
  414. // printf("Message: %d\n", i);
  415. // Get element
  416. hr = pEnum->Next(1, &rElement, &c);
  417. if (FAILED(hr))
  418. break;
  419. if (c == 0)
  420. break;
  421. // No Name ?
  422. if (NULL == rElement.pwcsName)
  423. continue;
  424. // Open the stream...
  425. hr = pStorage->OpenStream(rElement.pwcsName, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, 0, &pStream);
  426. if (FAILED(hr))
  427. {
  428. printf("IStorage::OpenStream failed: (iMsg = %d)\n", i);
  429. goto nextmsg;
  430. }
  431. // Init New the message
  432. hr = pMessage->InitNew();
  433. if (FAILED(hr))
  434. {
  435. printf("pMessage->InitNew failed (HR = %08X): (iMsg = %d)\n", hr, i);
  436. goto nextmsg;
  437. }
  438. // Load the header...
  439. hr = pMessage->BindToMessage(pStream);
  440. if (FAILED(hr))
  441. {
  442. printf("pMessage->BindMessage failed (HR = %08X): (iMsg = %d)\n", hr, i);
  443. goto nextmsg;
  444. }
  445. #if 0
  446. hr = pMessage->SplitMessage(64 * 1024, &pParts);
  447. if (FAILED(hr))
  448. MessageBox(NULL, "IMimeMessage::SplitMessage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  449. else
  450. {
  451. hr = pParts->CombineParts(&pCombine);
  452. if (FAILED(hr))
  453. MessageBox(NULL, "IMimeMessageParts::CombineParts failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  454. else
  455. pCombine->Release();
  456. pParts->Release();
  457. }
  458. // Test Addresss List
  459. hr = pMessage->GetAddressList(&pAddressTable);
  460. if (FAILED(hr))
  461. printf("IMimeHeader::GetAddressList failed (HR = %08X): (iMsg = %d)\n", hr, i);
  462. else
  463. {
  464. IADDRESSLIST rList;
  465. /*
  466. hr = pAddressTable->GetViewable(IAT_TO, TRUE, &pszData);
  467. if (FAILED(hr))
  468. printf("IMimeAddressList::GetViewable failed (HR = %08X): (iMsg = %d)\n", hr, i);
  469. else
  470. g_pMalloc->Free(pszData);
  471. */
  472. hr = pAddressTable->GetList(IAT_ALL, &rList);
  473. if (FAILED(hr) && hr != MIME_E_NO_DATA)
  474. printf("IMimeAddressList::GetList failed (HR = %08X): (iMsg = %d)\n", hr, i);
  475. else if (SUCCEEDED(hr))
  476. {
  477. // for (x=0; x<rList.cAddresses; x++)
  478. // printf("%30s%30s\n", rList.prgAddress[x].pszName, rList.prgAddress[x].pszEmail);
  479. g_pMalloc->FreeAddressList(&rList);
  480. // printf("------------------------------------------------------------------------\n");
  481. }
  482. pAddressTable->Release();
  483. }
  484. // QI for body tree
  485. hr = pMessage->BindToObject(HBODY_ROOT, IID_IMimeBody, (LPVOID *)&pRootBody);
  486. if (FAILED(hr))
  487. {
  488. printf("pMessage->GetRootBody failed (HR = %08X): (iMsg = %d)\n", hr, i);
  489. goto nextmsg;
  490. }
  491. hr = pRootBody->SetInetProp(STR_HDR_CNTTYPE, "text/plain");
  492. if (FAILED(hr))
  493. MessageBox(NULL, "pRootBody->SetInetProp failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  494. // Get the time...
  495. hr = pRootBody->GetSentTime(&ft);
  496. if (FAILED(hr))
  497. MessageBox(NULL, "IMimeMessage::GetSentTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  498. hr = pRootBody->SetSentTime(&ft);
  499. if (FAILED(hr))
  500. MessageBox(NULL, "IMimeMessage::SetSentTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  501. hr =pRootBody->GetReceiveTime(&ft);
  502. if (FAILED(hr))
  503. MessageBox(NULL, "IMimeMessage::GetReceiveTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  504. hr = pMessage->GetTextBody(NULL, NULL, &pSave);
  505. if (FAILED(hr) && hr != MIME_E_NO_DATA)
  506. MessageBox(NULL, "IMimeMessage::GetTextBody failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  507. else if (pSave)
  508. pSave->Release();
  509. hr = pMessage->GetTextBody("html", NULL, &pSave);
  510. if (FAILED(hr) && hr != MIME_E_NO_DATA)
  511. MessageBox(NULL, "IMimeMessage::GetTextBody failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  512. else if (pSave)
  513. pSave->Release();
  514. CreateStreamOnHGlobal(NULL, TRUE, &pSave);
  515. hr = pMessage->SaveMessage(pSave, TRUE);
  516. if (FAILED(hr))
  517. MessageBox(NULL, "IMimeMessage::GetReceiveTime failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  518. pSave->Release();
  519. hr = pMessage->QueryInterface(IID_IDataObject, (LPVOID *)&pDataObject);
  520. if (FAILED(hr))
  521. MessageBox(NULL, "IMimeMessage::QueryInterface failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  522. else
  523. {
  524. OleSetClipboard(pDataObject);
  525. pDataObject->Release();
  526. }
  527. // Get Message Source
  528. pStream->Release();
  529. pStream = NULL;
  530. hr = pMessage->GetMessageSource(&pStream);
  531. if (FAILED(hr))
  532. {
  533. printf("IMimeMessageTree::GetMessageSource failed (HR = %08X): (iMsg = %d)\n", hr, i);
  534. goto nextmsg;
  535. }
  536. // Create body tree stream
  537. hr = CreateStreamOnHGlobal(NULL, TRUE, &pstmTree);
  538. if (FAILED(hr))
  539. {
  540. printf("CreateStreamOnHGlobal failed (HR = %08X): (iMsg = %d)\n", hr, i);
  541. goto nextmsg;
  542. }
  543. // find first/next loop
  544. ZeroMemory(&rFindBody, sizeof(rFindBody));
  545. rFindBody.pszCntType = (LPSTR)STR_CNT_TEXT;
  546. hr = pMessage->FindFirst(&rFindBody, &hBody);
  547. if (FAILED(hr) && hr != MIME_E_NOT_FOUND)
  548. {
  549. printf("pMessage->FindFirst failed (HR = %08X): (iMsg = %d)\n", hr, i);
  550. goto nextmsg;
  551. }
  552. else if (SUCCEEDED(hr))
  553. {
  554. while(1)
  555. {
  556. // Open the body
  557. hr = pMessage->BindToObject(hBody, IID_IMimeBody, (LPVOID *)&pBody);
  558. if (FAILED(hr))
  559. {
  560. printf("pMessage->BindToObject failed (HR = %08X): (iMsg = %d)\n", hr, i);
  561. goto nextmsg;
  562. }
  563. // Get the body stream...
  564. if (SUCCEEDED(pBody->GetData(FMT_BINARY, &pBodyStream)))
  565. {
  566. // Seek to end and then begginnging
  567. hr = pBodyStream->Seek(liOrigin, STREAM_SEEK_END, NULL);
  568. if (FAILED(hr))
  569. {
  570. printf("pBodyStream->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i);
  571. goto nextmsg;
  572. }
  573. // Seek to end and then begginnging
  574. hr = pBodyStream->Seek(liOrigin, STREAM_SEEK_SET, NULL);
  575. if (FAILED(hr))
  576. {
  577. printf("pBodyStream->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i);
  578. goto nextmsg;
  579. }
  580. // Lets read data from the stream
  581. while(1)
  582. {
  583. // Read block
  584. hr = pBodyStream->Read(rgbBuffer, sizeof(rgbBuffer) - 1, &cbRead);
  585. if (FAILED(hr))
  586. {
  587. printf("pBodyStream->Read failed (HR = %08X): (iMsg = %d)\n", hr, i);
  588. goto nextmsg;
  589. }
  590. // Done
  591. if (0 == cbRead)
  592. break;
  593. // rgbBuffer[cbRead] = '\0';
  594. // printf("%s", (LPSTR)rgbBuffer);
  595. }
  596. pBodyStream->Release();
  597. pBodyStream = NULL;
  598. // printf("\n======================================================================\n");
  599. // _getch();
  600. }
  601. // Release
  602. pBody->Release();
  603. pBody = NULL;
  604. // Get Next
  605. if (FAILED(pMessage->FindNext(&rFindBody, &hBody)))
  606. break;
  607. }
  608. }
  609. // Save the Tree
  610. hr = pMessage->SaveTree(pstmTree);
  611. if (FAILED(hr))
  612. {
  613. printf("pMessage->Save failed (HR = %08X): (iMsg = %d)\n", hr, i);
  614. goto nextmsg;
  615. }
  616. // Commit the stream
  617. hr = pstmTree->Commit(STGC_DEFAULT);
  618. if (FAILED(hr))
  619. {
  620. printf("pstmTree->Commit failed (HR = %08X): (iMsg = %d)\n", hr, i);
  621. goto nextmsg;
  622. }
  623. // Rewind it
  624. hr = pstmTree->Seek(liOrigin, STREAM_SEEK_SET, NULL);
  625. if (FAILED(hr))
  626. {
  627. printf("pstmTree->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i);
  628. goto nextmsg;
  629. }
  630. // Init the tree
  631. hr = pMessage->InitNew();
  632. if (FAILED(hr))
  633. {
  634. printf("pMessage->InitNew failed (HR = %08X): (iMsg = %d)\n", hr, i);
  635. goto nextmsg;
  636. }
  637. // Load the body tree
  638. hr = pMessage->LoadTree(pstmTree);
  639. if (FAILED(hr))
  640. {
  641. printf("pMessage->Load failed (HR = %08X): (iMsg = %d)\n", hr, i);
  642. goto nextmsg;
  643. }
  644. // Rewind message stream
  645. hr = pStream->Seek(liOrigin, STREAM_SEEK_SET, NULL);
  646. if (FAILED(hr))
  647. {
  648. printf("pStream->Seek failed (HR = %08X): (iMsg = %d)\n", hr, i);
  649. goto nextmsg;
  650. }
  651. // Rebind
  652. hr = pMessage->BindMessage(pStream);
  653. if (FAILED(hr))
  654. {
  655. printf("pMessage->BindMessage failed (HR = %08X): (iMsg = %d)\n", hr, i);
  656. goto nextmsg;
  657. }
  658. #endif
  659. nextmsg:
  660. // Cleanup
  661. if (pstmTree)
  662. {
  663. pstmTree->Release();
  664. pstmTree = NULL;
  665. }
  666. if (pRootBody)
  667. {
  668. pRootBody->Release();
  669. pRootBody = NULL;
  670. }
  671. if (pStream)
  672. {
  673. pStream->Release();
  674. pStream = NULL;
  675. }
  676. if (pBody)
  677. {
  678. pBody->Release();
  679. pBody = NULL;
  680. }
  681. if (pBodyStream)
  682. {
  683. pBodyStream->Release();
  684. pBodyStream=NULL;
  685. }
  686. // Free the name
  687. CoTaskMemFree(rElement.pwcsName);
  688. }
  689. exit:
  690. // Cleanup
  691. if (pEnum)
  692. pEnum->Release();
  693. if (pMessage)
  694. pMessage->Release();
  695. if (pstmTree)
  696. pstmTree->Release();
  697. if (pStream)
  698. pStream->Release();
  699. // Done
  700. return;
  701. }
  702. void TreeViewInsertBody(HWND hwnd, IMimeMessageTree *pTree, HBODY hBody, HTREEITEM hParent, HTREEITEM hInsertAfter, HTREEITEM *phItem)
  703. {
  704. // Locals
  705. IMimeHeader *pHeader=NULL;
  706. LPSTR pszCntType=NULL,
  707. pszEncType=NULL,
  708. pszFree=NULL,
  709. psz=NULL,
  710. pszFileName=NULL,
  711. pszFName;
  712. TV_INSERTSTRUCT tvi;
  713. HRESULT hr;
  714. HTREEITEM hCurrent, hNew;
  715. HBODY hChild;
  716. // Get Header
  717. hr = pTree->BindToObject(hBody, IID_IMimeHeader, (LPVOID *)&pHeader);
  718. if (FAILED(hr))
  719. {
  720. MessageBox(GetParent(hwnd), "IMimeMessageTree->BindToObject - IID_IMimeHeader failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  721. goto exit;
  722. }
  723. // Get content type
  724. hr = pHeader->GetInetProp(STR_HDR_CNTTYPE, &pszCntType);
  725. if (FAILED(hr))
  726. {
  727. MessageBox(GetParent(hwnd), "IMimeHeader->GetContentType failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  728. goto exit;
  729. }
  730. // Get content type
  731. if (FAILED(pHeader->GetInetProp(STR_HDR_CNTENC, &pszFree)))
  732. pszEncType = (LPSTR)"Unknown";
  733. else
  734. pszEncType = pszFree;
  735. // Get content type
  736. if (FAILED(pHeader->GetInetProp(STR_ATT_FILENAME, &pszFileName)))
  737. pszFName = (LPSTR)"Unknown";
  738. else
  739. pszFName = pszFileName;
  740. // Build content-type string
  741. psz = (LPSTR)CoTaskMemAlloc(lstrlen(pszCntType) + lstrlen(pszEncType) + lstrlen(pszFName) + 15);
  742. // Insert
  743. ZeroMemory(&tvi, sizeof(TV_INSERTSTRUCT));
  744. tvi.hParent = hParent;
  745. tvi.hInsertAfter = hInsertAfter;
  746. tvi.item.mask = TVIF_PARAM | TVIF_TEXT;
  747. tvi.item.lParam = (LPARAM)hBody;
  748. tvi.item.cchTextMax = wsprintf(psz, "%s - %s (%s)", pszCntType, pszEncType, pszFName);
  749. tvi.item.pszText = psz;
  750. // Insert it
  751. *phItem = hCurrent = TreeView_InsertItem(hwnd, &tvi);
  752. // Multipart...
  753. if (pHeader->IsContentType(STR_CNT_MULTIPART, NULL) == S_OK)
  754. {
  755. // Get first child...
  756. hr = pTree->GetBody(BODY_FIRST_CHILD, hBody, &hChild);
  757. if (FAILED(hr))
  758. {
  759. MessageBox(GetParent(hwnd), "IMimeMessageTree->GetBody - BODY_FIRST_CHILD failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  760. goto exit;
  761. }
  762. // Loop
  763. while(hChild)
  764. {
  765. // Insert it
  766. TreeViewInsertBody(hwnd, pTree, hChild, hCurrent, TVI_LAST, &hNew);
  767. // Next
  768. hr = pTree->GetBody(BODY_NEXT, hChild, &hChild);
  769. if (FAILED(hr))
  770. break;
  771. }
  772. }
  773. TreeView_Expand(hwnd, *phItem, TVE_EXPAND);
  774. exit:
  775. // Cleanup
  776. if (pHeader)
  777. pHeader->Release();
  778. if (pszCntType)
  779. g_pMalloc->Free(pszCntType);
  780. if (pszFileName)
  781. g_pMalloc->Free(pszFileName);
  782. if (pszFree)
  783. g_pMalloc->Free(pszFree);
  784. if (psz)
  785. CoTaskMemFree(psz);
  786. // Done
  787. return;
  788. }
  789. void TreeViewMessage(HWND hwnd, IMimeMessage *pMessage)
  790. {
  791. // Locals
  792. IMimeMessageTree *pTree=NULL;
  793. HBODY hBody;
  794. HRESULT hr=S_OK;
  795. HTREEITEM hRoot;
  796. // Delete All
  797. TreeView_DeleteAllItems(hwnd);
  798. // QI for body tree
  799. hr = pMessage->QueryInterface(IID_IMimeMessageTree, (LPVOID *)&pTree);
  800. if (FAILED(hr))
  801. {
  802. MessageBox(GetParent(hwnd), "IMimeMessage->QueryInterface - IID_IMimeMessageTree failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  803. goto exit;
  804. }
  805. // Get the root body object
  806. hr = pTree->GetBody(BODY_ROOT, NULL, &hBody);
  807. if (FAILED(hr))
  808. {
  809. MessageBox(GetParent(hwnd), "IMimeMessageTree->GetBody - BODY_ROOT failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  810. goto exit;
  811. }
  812. // Insert Body
  813. TreeViewInsertBody(hwnd, pTree, hBody, TVI_ROOT, TVI_FIRST, &hRoot);
  814. // Expand all
  815. TreeView_SelectItem(GetDlgItem(hwnd, IDC_LIST), hRoot);
  816. exit:
  817. // Cleanup
  818. if (pTree)
  819. pTree->Release();
  820. // Done
  821. return;
  822. }
  823. DWORD CALLBACK EditStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
  824. {
  825. LPSTREAM pstm=(LPSTREAM)dwCookie;
  826. if(pstm)
  827. pstm->Read(pbBuff, cb, (ULONG *)pcb);
  828. return NOERROR;
  829. }
  830. HRESULT HrRicheditStreamIn(HWND hwndRE, LPSTREAM pstm, ULONG uSelFlags)
  831. {
  832. EDITSTREAM es;
  833. if(!pstm)
  834. return E_INVALIDARG;
  835. if(!IsWindow(hwndRE))
  836. return E_INVALIDARG;
  837. es.dwCookie = (DWORD)pstm;
  838. es.pfnCallback=(EDITSTREAMCALLBACK)EditStreamInCallback;
  839. SendMessage(hwndRE, EM_STREAMIN, uSelFlags, (LONG)&es);
  840. return NOERROR;
  841. }
  842. BOOL FOpenStorage(HWND hwnd, LPSTR pszFile, IStorage **ppStorage, IEnumSTATSTG **ppEnum)
  843. {
  844. // Locals
  845. HRESULT hr;
  846. // Get file
  847. hr = StgOpenStorage(ConvertToUnicode(pszFile), NULL, STGM_TRANSACTED | STGM_NOSCRATCH | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, ppStorage);
  848. if (FAILED(hr))
  849. {
  850. MessageBox(hwnd, "StgOpenStorage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  851. return FALSE;
  852. }
  853. // Get First element
  854. hr = (*ppStorage)->EnumElements(0, NULL, 0, ppEnum);
  855. if (FAILED(hr))
  856. {
  857. MessageBox(hwnd, "IStorage::EnumElements failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  858. return FALSE;
  859. }
  860. // Done
  861. return TRUE;
  862. }
  863. BOOL FOpenMessage(HWND hwnd, IMimeMessage *pMessage, IStorage *pStorage)
  864. {
  865. HRESULT hr;
  866. BOOL fResult=FALSE;
  867. LARGE_INTEGER liOrigin = {0,0};
  868. CHAR szName[255];
  869. LPSTREAM pStream=NULL;
  870. LV_ITEM lvi;
  871. LPHBODY prgAttach=NULL;
  872. ULONG cAttach;
  873. // Get selected string
  874. ULONG i = ListView_GetNextItem(GetDlgItem(hwnd, IDC_LIST), -1, LVNI_SELECTED);
  875. if (-1 == i)
  876. return FALSE;
  877. // Get the name
  878. ZeroMemory(&lvi, sizeof(lvi));
  879. lvi.mask = LVIF_TEXT;
  880. lvi.iItem = i;
  881. lvi.pszText = szName;
  882. lvi.cchTextMax = sizeof(szName);
  883. ListView_GetItem(GetDlgItem(hwnd, IDC_LIST), &lvi);
  884. // OpenStream
  885. hr = pStorage->OpenStream(ConvertToUnicode(szName), NULL, STGM_SHARE_EXCLUSIVE | STGM_READ, 0, &pStream);
  886. if (FAILED(hr))
  887. {
  888. MessageBox(hwnd, "IStorage::OpenStream failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  889. goto exit;
  890. }
  891. // Show Source
  892. pStream->Seek(liOrigin, STREAM_SEEK_SET, NULL);
  893. HrRicheditStreamIn(GetDlgItem(hwnd, IDE_EDIT), pStream, SF_TEXT);
  894. // Load the message
  895. pStream->Seek(liOrigin, STREAM_SEEK_SET, NULL);
  896. pMessage->InitNew();
  897. hr = pMessage->BindToMessage(pStream);
  898. if (FAILED(hr))
  899. {
  900. MessageBox(hwnd, "IMimeMessage::Load failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  901. goto exit;
  902. }
  903. // Save it back out
  904. #if 0
  905. pMessage->SetInetProp(HBODY_ROOT, STR_HDR_SUBJECT, "This is a test...");
  906. pMessage->GetAttached(&cAttach, &prgAttach);
  907. for (i=0; i<cAttach; i++)
  908. pMessage->DeleteBody(prgAttach[i]);
  909. if (prgAttach)
  910. g_pMalloc->Free(prgAttach);
  911. pMessage->Commit();
  912. #endif
  913. // View the message
  914. TreeViewMessage(GetDlgItem(hwnd, IDC_TREE), pMessage);
  915. // Success
  916. fResult = TRUE;
  917. exit:
  918. // Cleanup
  919. if (pStream)
  920. pStream->Release();
  921. // Done
  922. return TRUE;
  923. }
  924. // --------------------------------------------------------------------------------
  925. // MimeOLETest
  926. // --------------------------------------------------------------------------------
  927. INT_PTR CALLBACK MimeOLETest(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  928. {
  929. // Locals
  930. static CHAR s_szFile[MAX_PATH];
  931. static IMimeMessage *s_pMessage=NULL;
  932. static IStorage *s_pStorage=NULL;
  933. IMimeBody *pBody;
  934. IStream *pStream;
  935. HRESULT hr;
  936. IEnumSTATSTG *pEnum=NULL;
  937. TV_ITEM tvi;
  938. ULONG c;
  939. STATSTG rElement;
  940. HTREEITEM hItem;
  941. LV_COLUMN lvm;
  942. LV_ITEM lvi;
  943. HWND hwndC;
  944. // Handle the message
  945. switch(uMsg)
  946. {
  947. // Initialize
  948. case WM_INITDIALOG:
  949. // Create a header object...
  950. hr = CoCreateInstance(CLSID_MIMEOLE, NULL, CLSCTX_INPROC_SERVER, IID_IMimeMessage, (LPVOID *)&s_pMessage);
  951. if (FAILED(hr))
  952. {
  953. MessageBox(hwnd, "CoCreateInstance - IID_IMimeMessage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  954. return FALSE;
  955. }
  956. //s_pMessage->TestMe();
  957. // Formats
  958. hwndC = GetDlgItem(hwnd, IDCB_FORMAT);
  959. c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_BINARY");
  960. SendMessage(hwndC, CB_SETITEMDATA, c, FMT_BINARY);
  961. c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_INETCSET");
  962. SendMessage(hwndC, CB_SETITEMDATA, c, FMT_INETCSET);
  963. c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMIT64");
  964. SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMIT64);
  965. c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMITUU");
  966. SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMITUU);
  967. c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMITQP");
  968. SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMITQP);
  969. c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMIT7BIT");
  970. SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMIT7BIT);
  971. c = SendMessage(hwndC, CB_ADDSTRING, 0, (LPARAM)"FMT_XMIT8BIT");
  972. SendMessage(hwndC, CB_SETITEMDATA, c, FMT_XMIT8BIT);
  973. SendMessage(hwndC, CB_SETCURSEL, 0, 0);
  974. // To
  975. // ListView_SetExtendedListViewStyle(GetDlgItem(hwnd, IDC_LIST), LVS_EX_FULLROWSELECT);
  976. ZeroMemory(&lvm, sizeof(LV_COLUMN));
  977. lvm.mask = LVCF_WIDTH | LVCF_TEXT;
  978. lvm.pszText = "MessageID";
  979. lvm.cchTextMax = lstrlen(lvm.pszText);
  980. lvm.cx = 200;
  981. ListView_InsertColumn(GetDlgItem(hwnd, IDC_LIST), 0, &lvm);
  982. if (lParam)
  983. {
  984. // Copy File Name
  985. lstrcpyn(s_szFile, (LPSTR)lParam, MAX_PATH);
  986. // Set file name
  987. SetDlgItemText(hwnd, IDE_STORAGE, s_szFile);
  988. // Get file
  989. hr = StgOpenStorage(ConvertToUnicode(s_szFile), NULL, STGM_TRANSACTED | STGM_NOSCRATCH | STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &s_pStorage);
  990. if (FAILED(hr))
  991. {
  992. MessageBox(hwnd, "StgOpenStorage failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  993. return FALSE;
  994. }
  995. #if 0
  996. //MoleTestHeader(s_pStorage);
  997. MoleTestBody(s_pStorage);
  998. s_pMessage->Release();
  999. s_pStorage->Release();
  1000. exit(1);
  1001. #endif
  1002. // Get First element
  1003. hr = s_pStorage->EnumElements(0, NULL, 0, &pEnum);
  1004. if (FAILED(hr))
  1005. {
  1006. MessageBox(hwnd, "IStorage::EnumElements failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  1007. return FALSE;
  1008. }
  1009. // Enumerate
  1010. ZeroMemory(&lvi, sizeof(lvi));
  1011. lvi.mask = LVIF_TEXT;
  1012. lvi.iItem = 0;
  1013. while(SUCCEEDED(pEnum->Next(1, &rElement, &c)) && c)
  1014. {
  1015. lvi.pszText = ConvertToAnsi(rElement.pwcsName);
  1016. lvi.cchTextMax = lstrlen(lvi.pszText);
  1017. ListView_InsertItem(GetDlgItem(hwnd, IDC_LIST), &lvi);
  1018. CoTaskMemFree(rElement.pwcsName);
  1019. lvi.iItem++;
  1020. }
  1021. // Select first item
  1022. ListView_SetItemState(GetDlgItem(hwnd, IDC_LIST), 0, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
  1023. // Release enum
  1024. pEnum->Release();
  1025. }
  1026. // Done
  1027. return FALSE;
  1028. case WM_NOTIFY:
  1029. switch(wParam)
  1030. {
  1031. case IDC_LIST:
  1032. {
  1033. NM_LISTVIEW *pnmv;
  1034. pnmv = (NM_LISTVIEW *)lParam;
  1035. if (pnmv->uChanged & LVIF_STATE)
  1036. {
  1037. if (pnmv->uNewState & LVIS_SELECTED && pnmv->uNewState & LVIS_FOCUSED)
  1038. FOpenMessage(hwnd, s_pMessage, s_pStorage);
  1039. }
  1040. }
  1041. return 1;
  1042. }
  1043. break;
  1044. // Handle Command
  1045. case WM_COMMAND:
  1046. switch(GET_WM_COMMAND_ID(wParam,lParam))
  1047. {
  1048. case IDB_OPEN:
  1049. hItem = TreeView_GetSelection(GetDlgItem(hwnd, IDC_TREE));
  1050. if (hItem)
  1051. {
  1052. ZeroMemory(&tvi, sizeof(TV_ITEM));
  1053. tvi.mask = TVIF_PARAM | TVIF_HANDLE;
  1054. tvi.hItem = hItem;
  1055. if (TreeView_GetItem(GetDlgItem(hwnd, IDC_TREE), &tvi))
  1056. {
  1057. hr = s_pMessage->BindToObject((HBODY)tvi.lParam, IID_IMimeBody, (LPVOID *)&pBody);
  1058. if (FAILED(hr))
  1059. {
  1060. MessageBox(hwnd, "IMimeMessageTree::BindToObject failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  1061. return FALSE;
  1062. }
  1063. c = SendMessage(GetDlgItem(hwnd, IDCB_FORMAT), CB_GETCURSEL, 0, 0);
  1064. if (CB_ERR == c)
  1065. {
  1066. pBody->Release();
  1067. MessageBox(hwnd, "Select an Object Object Format", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  1068. return FALSE;
  1069. }
  1070. hr = pBody->GetData((BODYFORMAT)SendMessage(GetDlgItem(hwnd, IDCB_FORMAT), CB_GETITEMDATA, c, 0), &pStream);
  1071. if (FAILED(hr))
  1072. {
  1073. pBody->Release();
  1074. MessageBox(hwnd, "IMimeMessageTree::BindToObject failed", "MimeOLE Test", MB_OK | MB_ICONEXCLAMATION);
  1075. return FALSE;
  1076. }
  1077. DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_MESSAGE), NULL, RichStreamShow, (LPARAM)pStream);
  1078. pBody->Release();
  1079. pStream->Release();
  1080. }
  1081. }
  1082. return 1;
  1083. case IDCANCEL:
  1084. EndDialog(hwnd, IDCANCEL);
  1085. return 1;
  1086. }
  1087. break;
  1088. // Close
  1089. case WM_CLOSE:
  1090. EndDialog(hwnd, IDB_NEXT);
  1091. break;
  1092. // Cleanup
  1093. case WM_DESTROY:
  1094. if (s_pMessage)
  1095. s_pMessage->Release();
  1096. if (s_pStorage)
  1097. s_pStorage->Release();
  1098. break;
  1099. }
  1100. return FALSE;
  1101. }
  1102. // --------------------------------------------------------------------------------
  1103. // RichStreamShow
  1104. // --------------------------------------------------------------------------------
  1105. INT_PTR CALLBACK RichStreamShow(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1106. {
  1107. switch(uMsg)
  1108. {
  1109. case WM_INITDIALOG:
  1110. HrRicheditStreamIn(GetDlgItem(hwnd, IDE_EDIT), (IStream *)lParam, SF_TEXT);
  1111. return FALSE;
  1112. case WM_CLOSE:
  1113. EndDialog(hwnd, IDCANCEL);
  1114. break;
  1115. }
  1116. return FALSE;
  1117. }