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.

1918 lines
56 KiB

  1. // =================================================================================
  2. // S T A T N E R Y . C P P
  3. // =================================================================================
  4. #include "pch.hxx"
  5. #include "strconst.h"
  6. #include "goptions.h"
  7. #include "error.h"
  8. #include "resource.h"
  9. #include "mailutil.h"
  10. #include "statnery.h"
  11. #include "wininet.h"
  12. #include "options.h"
  13. #include <shlwapi.h>
  14. #include <shlwapip.h>
  15. #include "regutil.h"
  16. #include "menuutil.h"
  17. #include "thumb.h"
  18. #include "optres.h"
  19. #include <statwiz.h>
  20. #include "url.h"
  21. #include <bodyutil.h>
  22. #include "demand.h"
  23. #include "menures.h"
  24. #include "ipab.h"
  25. #include "mailnews.h"
  26. #define STARTINDEX 0
  27. #define CNOMORE 4
  28. #define MAX_ENTRY 10
  29. #define MAX_SHOWNAME 50
  30. BOOL PASCAL MoreStationeryNotify(HWND hDlg, LPOFNOTIFYW pofn);
  31. BOOL FHtmlFile(LPWSTR pwszFile);
  32. BOOL CALLBACK MoreStationeryDlgHookProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  33. BOOL IsValidFileName(LPWSTR pwszFile);
  34. void ShowBlankPreview(HWND hwnd);
  35. HRESULT ShowMorePreview(HWND hwnd);
  36. HRESULT FillHtmlToFileA(LPSTATWIZ pApp, HANDLE hFile, INT idsSample, BOOL fTemp);
  37. HRESULT FillHtmlToFileW(LPSTATWIZ pApp, HANDLE hFile, INT idsSample, BOOL fTemp);
  38. BOOL fValidFile(LPWSTR pwszFile);
  39. BOOL fFileOK(LPWSTR pwszFile);
  40. static WCHAR s_wszStationeryDir[MAX_PATH]={0};
  41. static WCHAR g_wszLastStationeryPath[MAX_PATH];
  42. static const HELPMAP g_rgStatWizHlp[] = {
  43. {IDC_SHOWPREVIEW_BUTTON_ADD, IDH_STATIONERY_BROWSE_PICTURE },
  44. {IDC_SHOWPREVIEW_BUTTON_EDIT, IDH_STATIONERY_EDIT },
  45. {IDC_STATWIZ_PREVIEWBACKGROUND, IDH_STATIONERY_PREVIEW},
  46. {IDC_MOREPREVIEW, 35640},
  47. {IDC_SHOWPREVIEW_CHECK, 35656},
  48. {0, 0}
  49. };
  50. const static CHAR c_szHtmlExtension[] = ".htm";
  51. const static CHAR c_szTempFileName[] = "StatWiz";
  52. static const WCHAR c_wszFile[] = L"File";
  53. static const WCHAR c_wszRSFileFmt[] = L"%s%d";
  54. const static WCHAR c_wszBlankHtml[] = L"blank.htm";
  55. const static WCHAR c_wszEditCmd[] = L"edit";
  56. const static WCHAR c_wszHtmlHeadFmt[] = L"<HTML>\r\n<HEAD>\r\n<STYLE>\r\nBODY {\r\n";
  57. const static WCHAR c_wszStyleClose[] = L"}\r\n</STYLE>\r\n</HEAD>\r\n";
  58. const static WCHAR c_wszBodyFmt[] = L"<BODY %s=\"%s\">\r\n";
  59. const static WCHAR c_wszHtmlClose[] = L"</BODY>\r\n</HTML>\r\n";
  60. const static WCHAR c_wszBkPicture[] = L"background";
  61. const static WCHAR c_wszBkColor[] = L"bgcolor";
  62. const static WCHAR c_wszFontFmt[] = L"font-family: %s;\r\nfont-size: %dpt;\r\ncolor: %s;\r\n";
  63. const static WCHAR c_wszBold[] = L"font-weight: bold;\r\n";
  64. const static WCHAR c_wszItalic[] = L"font-style: italic;\r\n";
  65. const static WCHAR c_wszLeftMarginFmt[] = L"margin-left: %d px;\r\n";
  66. const static WCHAR c_wszTopMarginFmt[] = L"margin-top: %d px;\r\n";
  67. const static WCHAR c_wszFontFamily[] = L"font-family:";
  68. const static WCHAR c_wszFontSize[] = L"font-size:";
  69. const static WCHAR c_wszFontColor[] = L"color:";
  70. const static WCHAR c_wszBkRepeat[] = L"background-repeat: %s;\r\n";
  71. const static WCHAR c_wszBkPosition[] = L"background-position: %s;\r\n";
  72. const static LPWSTR c_lppwszBkPos[3][3] = {
  73. {L"top left", L"top center", L"top right"},
  74. {L"center left", L"center center", L"center right"},
  75. {L"bottom left", L"bottom center", L"bottom right"}};
  76. static const LPWSTR c_rgpwszHTMLExtensions[] = {L"*.htm", L"*.html"};
  77. const static LPWSTR c_lpwszRepeatPos[] = {L"no-repeat", L"repeat-y", L"repeat-x", L"repeat" };
  78. static const LPWSTR c_wszPictureExtensions[] = {L"*.gif", L"*.bmp", L"*.jpg"};
  79. const static CHAR c_szBlankHtml[] = "blank.htm";
  80. const static CHAR c_szEditCmd[] = "edit";
  81. const static CHAR c_szHtmlHeadFmt[] = "<HTML>\r\n<HEAD>\r\n<STYLE>\r\nBODY {\r\n";
  82. const static CHAR c_szStyleClose[] = "}\r\n</STYLE>\r\n</HEAD>\r\n";
  83. const static CHAR c_szBodyFmt[] = "<BODY %s=\"%s\">\r\n";
  84. const static CHAR c_szHtmlClose[] = "</BODY>\r\n</HTML>\r\n";
  85. const static CHAR c_szBkPicture[] = "background";
  86. const static CHAR c_szBkColor[] = "bgcolor";
  87. const static CHAR c_szFontFmt[] = "font-family: %s;\r\nfont-size: %dpt;\r\ncolor: %s;\r\n";
  88. const static CHAR c_szBold[] = "font-weight: bold;\r\n";
  89. const static CHAR c_szItalic[] = "font-style: italic;\r\n";
  90. const static CHAR c_szLeftMarginFmt[] = "margin-left: %d px;\r\n";
  91. const static CHAR c_szTopMarginFmt[] = "margin-top: %d px;\r\n";
  92. const static CHAR c_szFontFamily[] = "font-family:";
  93. const static CHAR c_szFontSize[] = "font-size:";
  94. const static CHAR c_szFontColor[] = "color:";
  95. const static CHAR c_szBkRepeat[] = "background-repeat: %s;\r\n";
  96. const static CHAR c_szBkPosition[] = "background-position: %s;\r\n";
  97. const static LPSTR c_lppszBkPos[3][3] = {
  98. {"top left", "top center", "top right"},
  99. {"center left", "center center", "center right"},
  100. {"bottom left", "bottom center", "bottom right"}};
  101. static const LPSTR c_rgpszHTMLExtensions[] = {"*.htm", "*.html"};
  102. const static LPSTR c_lpszRepeatPos[] = {"no-repeat", "repeat-y", "repeat-x", "repeat" };
  103. static const LPSTR c_szPictureExtensions[] = {"*.gif", "*.bmp", "*.jpg"};
  104. /******************************************************************************************
  105. * ListEntry
  106. *******************************************************************************************/
  107. ListEntry::ListEntry()
  108. {
  109. INT iLen;
  110. m_cRef = 1;
  111. m_pwszFile = NULL;
  112. m_pNext = NULL;
  113. }
  114. HRESULT ListEntry::HrInit(LPWSTR pwszFile)
  115. {
  116. INT iLen;
  117. HRESULT hr = S_OK;
  118. if(NULL == pwszFile || *pwszFile == 0)
  119. IF_FAILEXIT(hr = E_INVALIDARG);
  120. #pragma prefast(suppress:11, "noise")
  121. iLen = lstrlenW(pwszFile);
  122. IF_NULLEXIT(MemAlloc((LPVOID*)&m_pwszFile, (iLen+1)*sizeof(WCHAR)));
  123. StrCpyNW(m_pwszFile, pwszFile,iLen+1);
  124. exit:
  125. return hr;
  126. }
  127. ListEntry::~ListEntry()
  128. {
  129. MemFree(m_pwszFile);
  130. m_pNext = NULL;
  131. }
  132. ULONG ListEntry::AddRef(VOID)
  133. {
  134. return ++m_cRef;
  135. }
  136. ULONG ListEntry::Release(VOID)
  137. {
  138. if (--m_cRef == 0)
  139. {
  140. delete this;
  141. return 0;
  142. }
  143. return m_cRef;
  144. }
  145. /******************************************************************************************
  146. * CStationery
  147. *******************************************************************************************/
  148. CStationery::CStationery()
  149. {
  150. m_cRef = 1;
  151. m_pFirst = NULL;
  152. InitializeCriticalSection(&m_rCritSect);
  153. }
  154. CStationery::~CStationery()
  155. {
  156. Assert (m_cRef == 0);
  157. while(S_OK==HrDeleteEntry(0));
  158. DeleteCriticalSection(&m_rCritSect);
  159. }
  160. ULONG CStationery::AddRef(VOID)
  161. {
  162. return ++m_cRef;
  163. }
  164. ULONG CStationery::Release(VOID)
  165. {
  166. if (--m_cRef == 0)
  167. {
  168. delete this;
  169. return 0;
  170. }
  171. return m_cRef;
  172. }
  173. // always insert at the beginning.
  174. HRESULT CStationery::HrInsertEntry(LPWSTR pwszFile)
  175. {
  176. LPLISTENTRY pNewEntry = NULL;
  177. HRESULT hr = S_OK;
  178. if(!fFileOK(pwszFile))
  179. return E_INVALIDARG;
  180. EnterCriticalSection(&m_rCritSect);
  181. IF_NULLEXIT(pNewEntry = new ListEntry);
  182. IF_FAILEXIT(hr = pNewEntry->HrInit(pwszFile));
  183. IF_FAILEXIT(hr = HrInsertEntry(pNewEntry));
  184. pNewEntry = NULL; //prevent deleting.
  185. exit:
  186. LeaveCriticalSection(&m_rCritSect);
  187. ReleaseObj(pNewEntry);
  188. return hr;
  189. }
  190. HRESULT CStationery::HrInsertEntry(LPLISTENTRY pEntry)
  191. {
  192. HRESULT hr = S_OK;
  193. if(NULL==pEntry || !fFileOK(pEntry->m_pwszFile))
  194. return TraceResult(E_INVALIDARG);
  195. EnterCriticalSection(&m_rCritSect);
  196. if(cEntries()==MAX_ENTRY)
  197. IF_FAILEXIT(hr = HrDeleteEntry(MAX_ENTRY-1));
  198. if(NULL!=m_pFirst) //not empty
  199. pEntry->m_pNext = m_pFirst;
  200. m_pFirst = pEntry;
  201. exit:
  202. LeaveCriticalSection(&m_rCritSect);
  203. return hr;
  204. }
  205. // iIndex is 0 based
  206. HRESULT CStationery::HrPromoteEntry(INT iIndex)
  207. {
  208. HRESULT hr = NOERROR;
  209. LPLISTENTRY pPromotedEntry = NULL;
  210. if(iIndex == 0 || !fValidIndex(iIndex))
  211. return TraceResult(E_INVALIDARG);
  212. EnterCriticalSection(&m_rCritSect);
  213. IF_NULLEXIT(pPromotedEntry = RemoveEntry(iIndex));
  214. IF_FAILEXIT(hr = HrInsertEntry(pPromotedEntry));
  215. exit:
  216. LeaveCriticalSection(&m_rCritSect);
  217. return hr;
  218. }
  219. LPLISTENTRY CStationery::MoveToEntry(INT iIndex)
  220. {
  221. LPLISTENTRY pEntry = NULL;
  222. if(!fValidIndex(iIndex))
  223. goto error;
  224. pEntry = m_pFirst;
  225. if(iIndex!=0)
  226. {
  227. for(INT i=0; i<iIndex; i++)
  228. {
  229. pEntry = pEntry->m_pNext;
  230. Assert(pEntry);
  231. }
  232. }
  233. error:
  234. return pEntry;
  235. }
  236. LPLISTENTRY CStationery::RemoveEntry(INT iIndex)
  237. {
  238. LPLISTENTRY pRemovedEntry = NULL,
  239. pEntry = m_pFirst;
  240. if(!fValidIndex(iIndex))
  241. goto error;
  242. EnterCriticalSection(&m_rCritSect);
  243. if(iIndex==0) //remove the first one,
  244. {
  245. pRemovedEntry = m_pFirst;
  246. m_pFirst = pRemovedEntry->m_pNext;
  247. }
  248. else
  249. {
  250. pEntry = MoveToEntry(iIndex - 1);
  251. pRemovedEntry = pEntry->m_pNext;
  252. pEntry->m_pNext = pRemovedEntry ->m_pNext;
  253. }
  254. error:
  255. LeaveCriticalSection(&m_rCritSect);
  256. return pRemovedEntry;
  257. }
  258. HRESULT CStationery::HrDeleteEntry(INT iIndex)
  259. {
  260. HRESULT hr = NOERROR;
  261. LPLISTENTRY pRemovedEntry = NULL;
  262. if(!fValidIndex(iIndex))
  263. return TraceResult(E_INVALIDARG);
  264. EnterCriticalSection(&m_rCritSect);
  265. pRemovedEntry = RemoveEntry(iIndex);
  266. if (!pRemovedEntry)
  267. IF_FAILEXIT(hr = E_FAIL);
  268. exit:
  269. ReleaseObj(pRemovedEntry);
  270. LeaveCriticalSection(&m_rCritSect);
  271. return hr;
  272. }
  273. VOID CStationery::ValidateList(BOOL fCheckExist)
  274. {
  275. HRESULT hr = NOERROR;
  276. LPLISTENTRY pEntry = m_pFirst,
  277. pPrev = NULL;
  278. BOOL fValid = FALSE;
  279. EnterCriticalSection(&m_rCritSect);
  280. while(pEntry != NULL)
  281. {
  282. fValid = fCheckExist ? fValidFile(pEntry->m_pwszFile) : fFileOK(pEntry->m_pwszFile);
  283. if(!fValid)
  284. {
  285. if(pEntry == m_pFirst)
  286. {
  287. m_pFirst = pEntry->m_pNext;
  288. ReleaseObj(pEntry);
  289. pEntry = m_pFirst;
  290. }
  291. else if (pPrev != NULL)
  292. {
  293. pPrev->m_pNext = pEntry->m_pNext;
  294. ReleaseObj(pEntry);
  295. pEntry = pPrev->m_pNext;
  296. }
  297. }
  298. pPrev = pEntry;
  299. if(pEntry)
  300. pEntry = pEntry->m_pNext;
  301. }
  302. LeaveCriticalSection(&m_rCritSect);
  303. return;
  304. }
  305. HRESULT CStationery::HrGetFileName(INT iIndex, LPWSTR pwszBuf)
  306. {
  307. HRESULT hr = NOERROR;
  308. LPLISTENTRY pEntry = NULL;
  309. if(!fValidIndex(iIndex) || NULL==pwszBuf)
  310. return TraceResult(E_INVALIDARG);
  311. pEntry = MoveToEntry(iIndex);
  312. if (!pEntry)
  313. IF_FAILEXIT(hr = E_FAIL);
  314. #pragma prefast(suppress:11, "noise")
  315. StrCpyNW(pwszBuf, pEntry->m_pwszFile, MAX_PATH);
  316. exit:
  317. return hr;
  318. }
  319. INT CStationery::cEntries()
  320. {
  321. INT iRet = 0;
  322. LPLISTENTRY pEntry = m_pFirst;
  323. while(pEntry != NULL)
  324. {
  325. pEntry = pEntry->m_pNext;
  326. iRet++;
  327. }
  328. return iRet;
  329. }
  330. BOOL CStationery::fValidIndex(INT iIndex)
  331. {
  332. BOOL fRet = TRUE;
  333. if(iIndex < 0 || iIndex > MAX_ENTRY)
  334. fRet = FALSE;
  335. if(cEntries()<=iIndex)
  336. fRet = FALSE;
  337. return fRet;
  338. }
  339. BOOL fFileOK(LPWSTR pwszFile)
  340. {
  341. BOOL fRet = FALSE;
  342. if(pwszFile == NULL || *pwszFile == 0)
  343. goto exit;
  344. if (!FHtmlFile(pwszFile))
  345. goto exit;
  346. fRet = TRUE;
  347. exit:
  348. return fRet;
  349. }
  350. BOOL fValidFile(LPWSTR pwszFile)
  351. {
  352. BOOL fRet = FALSE;
  353. WCHAR wszBuf[MAX_PATH];
  354. DWORD dwAttributes;
  355. *wszBuf = 0;
  356. if(!fFileOK(pwszFile))
  357. goto exit;
  358. StrCpyNW(wszBuf, pwszFile, ARRAYSIZE(wszBuf));
  359. InsertStationeryDir(wszBuf);
  360. dwAttributes = GetFileAttributesWrapW(wszBuf);
  361. if((UINT)dwAttributes==(UINT)-1 || dwAttributes&FILE_ATTRIBUTE_DIRECTORY)
  362. goto exit;
  363. fRet = TRUE;
  364. exit:
  365. return fRet;
  366. }
  367. HRESULT CStationery::HrFindEntry(LPWSTR pwszFile, INT* pRet)
  368. {
  369. INT iRet = -1, iIndex=0;
  370. LPLISTENTRY pEntry = m_pFirst;
  371. HRESULT hr = S_OK;
  372. *pRet = iRet;
  373. if(!fFileOK(pwszFile))
  374. return TraceResult(E_INVALIDARG);
  375. while(pEntry != NULL)
  376. {
  377. if(StrCmpW(pEntry->m_pwszFile, pwszFile) == 0)
  378. {
  379. iRet = iIndex;
  380. break;
  381. }
  382. pEntry = pEntry->m_pNext;
  383. iIndex++;
  384. }
  385. *pRet = iRet;
  386. if(iRet==-1)
  387. hr = E_FAIL;
  388. return hr;
  389. }
  390. HRESULT CStationery::HrLoadStationeryList()
  391. {
  392. HRESULT hr = NOERROR;
  393. INT i;
  394. HKEY hkey=NULL;
  395. DWORD dwType=0, cb=0, dw=0;
  396. WCHAR wszFileName[INTERNET_MAX_URL_LENGTH];
  397. WCHAR wszFileRegName[MAX_PATH];
  398. LONG lRegResult;
  399. *wszFileName = 0;
  400. *wszFileRegName = 0;
  401. lRegResult = AthUserOpenKey(c_szRegPathRSWideList, KEY_READ, &hkey);
  402. // If we failed, then try and open up the old list.
  403. if (ERROR_SUCCESS != lRegResult)
  404. lRegResult = AthUserOpenKey(c_szRegPathRSList, KEY_READ, &hkey);
  405. if (ERROR_SUCCESS == lRegResult)
  406. {
  407. for(i = MAX_ENTRY-1; i >= 0; i--)
  408. {
  409. wnsprintfW(wszFileRegName, ARRAYSIZE(wszFileRegName), c_wszRSFileFmt, c_wszFile, i);
  410. cb = sizeof(wszFileName);
  411. if(ERROR_SUCCESS == RegQueryValueExWrapW(hkey, wszFileRegName, 0,
  412. &dwType, (LPBYTE)wszFileName, &cb))
  413. {
  414. hr = HrInsertEntry(wszFileName);
  415. if (hr == E_OUTOFMEMORY)
  416. break;
  417. }
  418. }
  419. RegCloseKey(hkey);
  420. }
  421. if(E_OUTOFMEMORY != hr)
  422. hr = NOERROR; //we only catch E_OUTOFMEMORY.
  423. return hr;
  424. }
  425. void CStationery::SaveStationeryList()
  426. {
  427. INT index = 0;
  428. HKEY hkey=NULL;
  429. WCHAR wszFileRegName[MAX_PATH];
  430. LPLISTENTRY pEntry = m_pFirst;
  431. INT i;
  432. DWORD dw;
  433. *wszFileRegName = 0;
  434. if (ERROR_SUCCESS == AthUserCreateKey(c_szRegPathRSWideList, KEY_WRITE, &hkey, &dw))
  435. {
  436. while(pEntry != NULL)
  437. {
  438. wnsprintfW(wszFileRegName, ARRAYSIZE(wszFileRegName), c_wszRSFileFmt, c_wszFile, index);
  439. StripStationeryDir(pEntry->m_pwszFile);
  440. if(pEntry->m_pwszFile && *(pEntry->m_pwszFile))
  441. {
  442. DWORD cb = (lstrlenW(pEntry->m_pwszFile) + 1) * sizeof(WCHAR);
  443. RegSetValueExWrapW(hkey, wszFileRegName, 0, REG_SZ, (LPBYTE)(pEntry->m_pwszFile), cb);
  444. index++;
  445. }
  446. pEntry = pEntry->m_pNext;
  447. }
  448. for(i = index; i < MAX_ENTRY; i++) // NULL the rest
  449. {
  450. wnsprintfW(wszFileRegName, ARRAYSIZE(wszFileRegName), c_wszRSFileFmt, c_wszFile, i);
  451. RegSetValueExWrapW(hkey, wszFileRegName, 0, REG_SZ, (LPBYTE)c_wszEmpty, sizeof(WCHAR));
  452. }
  453. RegCloseKey(hkey);
  454. }
  455. }
  456. HRESULT CStationery::HrGetShowNames(LPWSTR pwszFile, LPWSTR pwszShowName, int cchShowName, INT index)
  457. {
  458. HRESULT hr = S_OK;
  459. LPWSTR pwsz = NULL;
  460. INT iLen;
  461. WCHAR wszBuf[MAX_PATH];
  462. *wszBuf = 0;
  463. if(pwszFile==NULL || *pwszFile==0 || pwszShowName==NULL)
  464. IF_FAILEXIT(hr = E_INVALIDARG);
  465. #pragma prefast(suppress:11, "noise")
  466. iLen = lstrlenW(pwszFile);
  467. *pwszShowName = 0;
  468. PathCompactPathExW(wszBuf, pwszFile, MAX_SHOWNAME, 0);
  469. if(*wszBuf == 0)
  470. IF_FAILEXIT(hr = E_FAIL);
  471. if(index == (MAX_ENTRY-1))
  472. wnsprintfW(pwszShowName, cchShowName, c_wszNumberFmt10, wszBuf);
  473. else
  474. wnsprintfW(pwszShowName, cchShowName, c_wszNumberFmt, index+1, wszBuf);
  475. // delete .htm and .html
  476. PathRemoveExtensionW(pwszShowName);
  477. exit:
  478. return hr;
  479. }
  480. // Assumes that there are no other items on the menu that have to be numbered.
  481. void CStationery::AddStationeryMenu(HMENU hmenu, int idFirst, int idMore)
  482. {
  483. INT iIndex = 0,
  484. cNumIDs;
  485. LPLISTENTRY pEntry = m_pFirst;
  486. WCHAR wszBuf[MAX_PATH];
  487. INT cMenus;
  488. MENUITEMINFOW mii;
  489. INT iInsertPos;
  490. BOOL fInsertSep = FALSE;
  491. int idMax = idFirst + 10;
  492. *wszBuf = 0;
  493. if (hmenu == NULL)
  494. return;
  495. // First delete any previous stationery off this menu
  496. for (UINT i = idFirst; i < (UINT)idMax; i++)
  497. {
  498. // When delete fails, then have gone as far as needed
  499. if (0 == DeleteMenu(hmenu, i, MF_BYCOMMAND))
  500. break;
  501. }
  502. DeleteMenu(hmenu, ID_STATIONERY_SEPARATOR, MF_BYCOMMAND);
  503. // Now figure out what index to start inserting at
  504. cNumIDs = GetMenuItemCount(hmenu) - 1;
  505. while (((UINT)idMore != GetMenuItemID(hmenu, cNumIDs)) && (cNumIDs > 0))
  506. cNumIDs--;
  507. mii.cbSize = sizeof(mii);
  508. mii.fMask = MIIM_SUBMENU;
  509. ValidateList(FALSE);
  510. pEntry = m_pFirst;
  511. while(pEntry)
  512. {
  513. *wszBuf = 0;
  514. HrGetShowNames(pEntry->m_pwszFile, wszBuf, ARRAYSIZE(wszBuf), iIndex);
  515. if(*wszBuf != 0)
  516. {
  517. InsertMenuWrapW(hmenu, (UINT)(cNumIDs+iIndex), MF_BYPOSITION|MF_STRING, idFirst + iIndex, wszBuf);
  518. iIndex++;
  519. fInsertSep = TRUE;
  520. }
  521. pEntry = pEntry->m_pNext;
  522. }
  523. if(fInsertSep)
  524. InsertMenu(hmenu, (UINT)(cNumIDs+iIndex), MF_BYPOSITION | MF_SEPARATOR, ID_STATIONERY_SEPARATOR, NULL);
  525. return;
  526. }
  527. void CStationery::GetStationeryMenu(HMENU *phMenu)
  528. {
  529. LPLISTENTRY pEntry = m_pFirst;
  530. INT iIndex = 0;
  531. WCHAR wszBuf[MAX_PATH];
  532. *wszBuf = 0;
  533. *phMenu = LoadPopupMenu(IDR_NEW_MSG_POPUP);
  534. ValidateList(FALSE);
  535. pEntry = m_pFirst;
  536. while(pEntry)
  537. {
  538. *wszBuf = 0;
  539. HrGetShowNames(pEntry->m_pwszFile, wszBuf, ARRAYSIZE(wszBuf), iIndex);
  540. if(*wszBuf != 0)
  541. {
  542. InsertMenuWrapW(*phMenu, (UINT)iIndex, MF_BYPOSITION | MF_STRING, ID_STATIONERY_RECENT_0 + iIndex, wszBuf);
  543. iIndex++;
  544. }
  545. pEntry = pEntry->m_pNext;
  546. }
  547. if(iIndex > 0)
  548. InsertMenu(*phMenu, (UINT)iIndex, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
  549. }
  550. HRESULT HrStationeryInit(void)
  551. {
  552. HRESULT hr = S_OK;
  553. if (NULL == g_pStationery)
  554. {
  555. g_pStationery = new CStationery;
  556. if (NULL == g_pStationery)
  557. {
  558. hr = E_OUTOFMEMORY;
  559. goto exit;
  560. }
  561. IF_FAILEXIT(hr = g_pStationery->HrLoadStationeryList());
  562. }
  563. exit:
  564. return hr;
  565. }
  566. void AddStationeryMenu(HMENU hmenu, int idPopup, int idFirst, int idMore)
  567. {
  568. if (idPopup)
  569. {
  570. MENUITEMINFOW mii;
  571. mii.cbSize = sizeof(mii);
  572. mii.fMask = MIIM_SUBMENU;
  573. if (GetMenuItemInfoWrapW(hmenu, idPopup, FALSE, &mii))
  574. hmenu = mii.hSubMenu;
  575. }
  576. if(g_pStationery == NULL)
  577. {
  578. if (FAILED(HrStationeryInit()))
  579. return;
  580. }
  581. #pragma prefast(suppress:11, "noise")
  582. g_pStationery->AddStationeryMenu(hmenu, idFirst, idMore);
  583. }
  584. void GetStationeryMenu(HMENU *phmenu)
  585. {
  586. if(g_pStationery == NULL)
  587. {
  588. if (FAILED(HrStationeryInit()))
  589. return;
  590. }
  591. #pragma prefast(suppress:11, "noise")
  592. g_pStationery->GetStationeryMenu(phmenu);
  593. }
  594. HRESULT HrGetStationeryFileName(INT index, LPWSTR pwszFile)
  595. {
  596. HRESULT hr = S_OK;
  597. if(pwszFile==NULL)
  598. IF_FAILEXIT(hr = E_INVALIDARG);
  599. if(g_pStationery == NULL)
  600. IF_FAILEXIT(hr = HrStationeryInit());
  601. #pragma prefast(disable:11, "noise")
  602. *pwszFile = 0;
  603. g_pStationery->HrGetFileName(index, pwszFile);
  604. #pragma prefast(enable:11, "noise")
  605. if(*pwszFile != 0)
  606. {
  607. if(!fValidFile(pwszFile))
  608. {
  609. g_pStationery->ValidateList(TRUE);
  610. IF_FAILEXIT(hr = E_FAIL);
  611. }
  612. InsertStationeryDir(pwszFile);
  613. }
  614. exit:
  615. return hr;
  616. }
  617. HRESULT HrNewStationery(HWND hwnd, INT id, LPWSTR pwszFile,
  618. BOOL fModal, BOOL fMail, FOLDERID folderID,
  619. BOOL fAddToMRU, DWORD dwSource, IUnknown *pUnkPump,
  620. IMimeMessage *pMsg)
  621. {
  622. INT index = id - ID_STATIONERY_RECENT_0;
  623. WCHAR wszBuf[INTERNET_MAX_URL_LENGTH];
  624. HRESULT hr = S_OK;
  625. *wszBuf=0;
  626. if(g_pStationery == NULL)
  627. IF_FAILEXIT(hr = HrStationeryInit());
  628. if(pwszFile == NULL)
  629. g_pStationery->HrGetFileName(index, wszBuf);
  630. else
  631. StrCpyNW(wszBuf, pwszFile, ARRAYSIZE(wszBuf));
  632. if(*wszBuf == 0)
  633. IF_FAILEXIT(hr = E_FAIL)
  634. if(!fValidFile(wszBuf))
  635. {
  636. g_pStationery->ValidateList(TRUE);
  637. IF_FAILEXIT(hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  638. }
  639. InsertStationeryDir(wszBuf);
  640. // This might pop up a dialog, in which case, error might be valid. Don't traceresult.
  641. // If don't add to MRU, then stationery by default. Therefore, send a signature.
  642. hr = HrSendWebPageDirect(wszBuf, hwnd, fModal, fMail, folderID,
  643. TRUE, pUnkPump, pMsg);
  644. if(fAddToMRU && SUCCEEDED(hr))
  645. // Since this only adds to the MRU, we don't care about error.
  646. HrAddToStationeryMRU(wszBuf);
  647. exit:
  648. ULONG ulErrRsrc;
  649. // At this point, if we canceled, then propagate success up.
  650. if (MAPI_E_USER_CANCEL == hr)
  651. hr = S_OK;
  652. if(FAILED(hr))
  653. {
  654. if( hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) )
  655. {
  656. ulErrRsrc = idsErrStationeryNotFound;
  657. switch (dwSource)
  658. {
  659. case NSS_MRU:
  660. // Remove fromt he MRU if file not found.
  661. HrRemoveFromStationeryMRU(wszBuf);
  662. break;
  663. case NSS_DEFAULT:
  664. // need to reset stationary for user if couldn't find it in the dir
  665. if( !SetDwOption( fMail ? OPT_MAIL_USESTATIONERY : OPT_NEWS_USESTATIONERY, 0, hwnd, 0) )
  666. {
  667. DebugTrace("reset failed\n");
  668. }
  669. break;
  670. }
  671. }
  672. else
  673. {
  674. ulErrRsrc = idsErrNewStationery;
  675. }
  676. AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsAthenaMail),
  677. MAKEINTRESOURCEW(ulErrRsrc), NULL, MB_OK);
  678. if (!pMsg)
  679. {
  680. // Only contacts passes us pMsg. In that case it handles the failure correctly.
  681. if (FNewMessage(hwnd, fModal, FALSE, !fMail, folderID, pUnkPump))
  682. hr = S_OK;
  683. else
  684. hr = E_FAIL;
  685. }
  686. }
  687. return hr;
  688. }
  689. HRESULT HrAddToStationeryMRU(LPWSTR pwszFile)
  690. {
  691. int index;
  692. HRESULT hr;
  693. if (pwszFile==NULL || *pwszFile==0)
  694. IF_FAILEXIT(hr = E_INVALIDARG);
  695. if (g_pStationery == NULL)
  696. IF_FAILEXIT(hr = HrStationeryInit());
  697. StripStationeryDir(pwszFile);
  698. #pragma prefast(suppress:11, "noise")
  699. hr = g_pStationery->HrFindEntry(pwszFile, &index);
  700. if(FAILED(hr))
  701. hr = g_pStationery->HrInsertEntry(pwszFile);
  702. else
  703. hr = g_pStationery->HrPromoteEntry(index);
  704. exit:
  705. return hr;
  706. }
  707. HRESULT HrRemoveFromStationeryMRU(LPWSTR pwszFile)
  708. {
  709. int index;
  710. HRESULT hr;
  711. if (pwszFile==NULL || *pwszFile==0)
  712. IF_FAILEXIT(hr = E_INVALIDARG);
  713. if (g_pStationery == NULL)
  714. IF_FAILEXIT(hr = HrStationeryInit());
  715. StripStationeryDir(pwszFile);
  716. IF_FAILEXIT(hr = g_pStationery->HrFindEntry(pwszFile, &index));
  717. IF_FAILEXIT(hr = g_pStationery->HrDeleteEntry(index));
  718. exit:
  719. return hr;
  720. }
  721. HRESULT HrGetStationeryPath(LPWSTR pwszPath)
  722. {
  723. HRESULT hr = NOERROR;
  724. DWORD cb, dwType;
  725. LONG lReg=0;
  726. HKEY hkey = 0;
  727. if(pwszPath == NULL)
  728. IF_FAILEXIT(hr = E_INVALIDARG);
  729. if(*s_wszStationeryDir == 0)
  730. {
  731. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegStationery, 0, KEY_QUERY_VALUE, &hkey))
  732. {
  733. cb = sizeof(s_wszStationeryDir);
  734. // Will need to convert this. Won't compile right now.
  735. lReg = RegQueryValueExWrapW(hkey, c_wszValueStationery, 0, &dwType, (LPBYTE)s_wszStationeryDir , &cb);
  736. if (ERROR_SUCCESS!=lReg || cb==0)
  737. IF_FAILEXIT(hr = E_FAIL);
  738. }
  739. if(*s_wszStationeryDir == 0)
  740. IF_FAILEXIT(hr = E_FAIL);
  741. PathRemoveBackslashW(s_wszStationeryDir);
  742. }
  743. Assert(*s_wszStationeryDir);
  744. ExpandEnvironmentStringsWrapW(s_wszStationeryDir, pwszPath, MAX_PATH);
  745. exit:
  746. if (hkey)
  747. RegCloseKey(hkey);
  748. return hr;
  749. }
  750. HRESULT HrGetMoreStationeryFileName(HWND hwnd, LPWSTR pwszFile)
  751. {
  752. OPENFILENAMEW ofn;
  753. WCHAR wszStationeryOpen[MAX_PATH],
  754. wsz[MAX_PATH],
  755. wszDir[MAX_PATH],
  756. wszFile[MAX_PATH];
  757. LPWSTR pwszDir = NULL;
  758. HRESULT hr = S_OK;
  759. *wszStationeryOpen = *wszDir = *wsz = 0;
  760. if(!pwszFile)
  761. return TraceResult(E_INVALIDARG);
  762. ZeroMemory(&ofn, sizeof(ofn));
  763. AthLoadStringW(idsHtmlFileFilter, wsz, ARRAYSIZE(wsz));
  764. ReplaceCharsW(wsz, L'|', L'\0');
  765. wszFile[0] = L'\0';
  766. AthLoadStringW(idsStationeryOpen, wszStationeryOpen, ARRAYSIZE(wszStationeryOpen));
  767. if (!PathIsDirectoryW(g_wszLastStationeryPath))
  768. {
  769. *g_wszLastStationeryPath = 0;
  770. HrGetStationeryPath(g_wszLastStationeryPath);
  771. }
  772. ofn.lStructSize = sizeof(ofn);
  773. ofn.hwndOwner = hwnd;
  774. ofn.hInstance = g_hLocRes;
  775. ofn.lpstrFilter = wsz;
  776. ofn.nFilterIndex = 1;
  777. ofn.lpstrFile = wszFile;
  778. ofn.lpstrTitle = wszStationeryOpen;
  779. ofn.nMaxFile = ARRAYSIZE(wszStationeryOpen);
  780. ofn.lpstrInitialDir = g_wszLastStationeryPath;
  781. ofn.lpTemplateName = MAKEINTRESOURCEW(iddMoreStationery);
  782. ofn.lpfnHook = (LPOFNHOOKPROC)MoreStationeryDlgHookProc;
  783. ofn.Flags = OFN_EXPLORER |
  784. OFN_HIDEREADONLY |
  785. OFN_FILEMUSTEXIST |
  786. OFN_NODEREFERENCELINKS|
  787. OFN_ENABLEHOOK |
  788. OFN_ENABLETEMPLATE |
  789. OFN_NOCHANGEDIR;
  790. if(GetOpenFileNameWrapW(&ofn) && *wszFile!=0)
  791. {
  792. // store the file
  793. StrCpyNW(pwszFile, wszFile, MAX_PATH);
  794. // store the last path
  795. *g_wszLastStationeryPath = 0;
  796. StrCpyNW(g_wszLastStationeryPath, ofn.lpstrFile, ARRAYSIZE(g_wszLastStationeryPath));
  797. if (!PathIsDirectoryW(g_wszLastStationeryPath))
  798. PathRemoveFileSpecW(g_wszLastStationeryPath);
  799. }
  800. else
  801. hr = E_FAIL;
  802. return hr;
  803. }
  804. HRESULT HrMoreStationery(HWND hwnd, BOOL fModal, BOOL fMail, FOLDERID folderID, IUnknown *pUnkPump)
  805. {
  806. WCHAR wszFileName[MAX_PATH];
  807. HRESULT hr;
  808. // Might return user cancel
  809. hr = HrGetMoreStationeryFileName(hwnd, wszFileName);
  810. if(SUCCEEDED(hr))
  811. hr = HrNewStationery(hwnd, 0, wszFileName, fModal, fMail, folderID, TRUE, NSS_MORE_DIALOG, pUnkPump, NULL);
  812. return hr;
  813. }
  814. BOOL CALLBACK MoreStationeryDlgHookProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  815. {
  816. WORD code;
  817. switch (msg)
  818. {
  819. case WM_COMMAND:
  820. {
  821. code = GET_WM_COMMAND_CMD(wParam, lParam);
  822. switch (GET_WM_COMMAND_ID(wParam, lParam))
  823. {
  824. case IDC_SHOWPREVIEW_CHECK:
  825. if (code == BN_CLICKED)
  826. {
  827. BOOL fChecked;
  828. fChecked = SendMessage(GET_WM_COMMAND_HWND(wParam,lParam), BM_GETCHECK, 0, 0) == BST_CHECKED;
  829. SetDwOption(OPT_NOPREVIEW, !fChecked, NULL, 0);
  830. if (fChecked)
  831. ShowMorePreview(hwnd);
  832. else
  833. ShowBlankPreview(GetDlgItem(hwnd, IDC_MOREPREVIEW));
  834. }
  835. SetFocus(GetDlgItem(GetParent(hwnd), lst1));
  836. return FALSE;
  837. case IDC_SHOWPREVIEW_BUTTON_EDIT:
  838. {
  839. WCHAR wszBuf[MAX_PATH];
  840. TCHAR szBuf[2 * MAX_PATH];
  841. *wszBuf = 0;
  842. if (SendMessageWrapW(GetParent(hwnd), CDM_GETSPEC, (WPARAM)ARRAYSIZE(wszBuf), (LPARAM)wszBuf) && lstrlenW(wszBuf) > 0)
  843. {
  844. // This is a workaround for a bug in SendMessageWrapW. It doesn't wrap ansi strings properly
  845. //Win 9x returns an ANSI string in the wide buffer.
  846. //Need to make it a real wide string
  847. //Bug# 78629
  848. if (VER_PLATFORM_WIN32_WINDOWS == g_OSInfo.dwPlatformId)
  849. {
  850. memcpy(szBuf, wszBuf, 2 * MAX_PATH);
  851. MultiByteToWideChar(CP_ACP, 0, szBuf, MAX_PATH, wszBuf, MAX_PATH);
  852. }
  853. SHELLEXECUTEINFOW sei;
  854. sei.cbSize = sizeof(sei);
  855. sei.fMask = SEE_MASK_UNICODE;
  856. sei.hwnd = hwnd;
  857. sei.lpVerb = c_wszEditCmd;
  858. sei.lpFile = wszBuf;
  859. sei.lpParameters = NULL;
  860. sei.lpDirectory = NULL;
  861. sei.nShow = SW_SHOWNORMAL;
  862. sei.hInstApp = 0;
  863. if(SE_ERR_NOASSOC == (INT_PTR)ShellExecuteExWrapW(&sei))
  864. {
  865. sei.lpVerb = c_wszNotepad;
  866. ShellExecuteExWrapW(&sei);
  867. }
  868. }
  869. else
  870. {
  871. AthMessageBoxW(hwnd, MAKEINTRESOURCEW(idsAthenaMail),
  872. MAKEINTRESOURCEW(idsErrStatEditNoSelection), NULL, MB_OK);
  873. }
  874. return FALSE;
  875. }
  876. case IDC_SHOWPREVIEW_BUTTON_ADD:
  877. {
  878. CStatWiz* pStatWiz = 0;
  879. HWND hDlg = GetParent(hwnd);
  880. LPWSTR pwszFile;
  881. LPSTR pszFile;
  882. pStatWiz = new CStatWiz();
  883. if( !pStatWiz ) return TRUE; // bail if can't create wiz
  884. if (pStatWiz->DoWizard(hwnd) == S_OK)
  885. {
  886. pwszFile = PathFindFileNameW(pStatWiz->m_wszHtmlFileName);
  887. // bobn; Raid 81946; 7/1/99
  888. // CDM_SETCONTROLTEXT is not handled by SendMessageWrapW,
  889. // we have to thunk it ourselves...
  890. if (VER_PLATFORM_WIN32_NT == g_OSInfo.dwPlatformId)
  891. SendMessageW(hDlg, CDM_SETCONTROLTEXT, (WPARAM)edt1, (LPARAM)pwszFile);
  892. else
  893. {
  894. pszFile = PszToANSI(CP_ACP, pwszFile);
  895. if(pszFile)
  896. {
  897. SendMessageA(hDlg, CDM_SETCONTROLTEXT, (WPARAM)edt1, (LPARAM)pszFile);
  898. MemFree(pszFile);
  899. }
  900. }
  901. if( !DwGetOption(OPT_NOPREVIEW) )
  902. {
  903. ShowMorePreview(hwnd);
  904. }
  905. }
  906. ReleaseObj(pStatWiz);
  907. return FALSE;
  908. }
  909. }
  910. }
  911. return TRUE;
  912. case WM_INITDIALOG:
  913. {
  914. TCHAR szBuf[CCHMAX_STRINGRES];
  915. LoadString(g_hLocRes, idsOK, szBuf, sizeof(szBuf));
  916. if (!DwGetOption(OPT_NOPREVIEW))
  917. CheckDlgButton(hwnd, IDC_SHOWPREVIEW_CHECK, BST_CHECKED);
  918. SetWindowText(GetDlgItem(GetParent(hwnd), IDOK), szBuf);
  919. CenterDialog( GetParent(hwnd) );
  920. }
  921. return TRUE;
  922. case WM_NOTIFY:
  923. MoreStationeryNotify(hwnd, (LPOFNOTIFYW)lParam);
  924. return TRUE;
  925. case WM_HELP:
  926. case WM_CONTEXTMENU:
  927. return OnContextHelp(hwnd, msg, wParam, lParam, g_rgStatWizHlp);
  928. }
  929. return FALSE;
  930. }
  931. void ShowBlankPreview(HWND hwnd)
  932. {
  933. SendMessage(hwnd, THM_LOADPAGE, 0, (LPARAM)c_wszBlankHtml);
  934. }
  935. HRESULT ShowPreview(HWND hwnd, LPWSTR pwszFile)
  936. {
  937. GetStationeryFullName(pwszFile);
  938. // Even if the full name fails, will need to clear the thumbprint
  939. SendMessage(hwnd, THM_LOADPAGE, 0, (LPARAM)pwszFile);
  940. return S_OK;
  941. }
  942. HRESULT FillHtmlToFile(LPSTATWIZ pApp, HANDLE hFile, INT idsSample, BOOL fTemp)
  943. {
  944. WCHAR wszImageFile[MAX_PATH];
  945. CHAR szImageFile[MAX_PATH];
  946. if (!hFile || !pApp)
  947. return E_INVALIDARG;
  948. if (*pApp->m_wszBkPictureFileName)
  949. {
  950. WideCharToMultiByte(CP_ACP, 0, pApp->m_wszBkPictureFileName, -1, szImageFile, ARRAYSIZE(szImageFile), NULL, NULL);
  951. MultiByteToWideChar(CP_ACP, 0, szImageFile, -1, wszImageFile, ARRAYSIZE(wszImageFile));
  952. if(StrCmpW(wszImageFile, pApp->m_wszBkPictureFileName))
  953. return(FillHtmlToFileW(pApp, hFile, idsSample, fTemp));
  954. }
  955. return(FillHtmlToFileA(pApp, hFile, idsSample, fTemp));
  956. }
  957. #define PSZ_CB(psz) lstrlen(psz)*sizeof(*psz)
  958. HRESULT FillHtmlToFileA(LPSTATWIZ pApp, HANDLE hFile, INT idsSample, BOOL fTemp)
  959. {
  960. WCHAR wszFileSpec[MAX_PATH];
  961. CHAR szBuf[MAX_PATH],
  962. szFileSpec[MAX_PATH];
  963. LPSTREAM pStm = NULL;
  964. LPSTR pszFontFace = NULL,
  965. pszFontColor = NULL,
  966. pszBkColor = NULL;
  967. HRESULT hr = S_OK;
  968. *szFileSpec = 0;
  969. if (!hFile || !pApp)
  970. IF_FAILEXIT(hr = E_INVALIDARG);
  971. IF_FAILEXIT(hr = MimeOleCreateVirtualStream(&pStm));
  972. IF_FAILEXIT(hr = pStm->Write(c_szHtmlHeadFmt, PSZ_CB(c_szHtmlHeadFmt), 0));
  973. if (*pApp->m_wszFontFace && pApp->m_iFontSize && *pApp->m_wszFontColor)
  974. {
  975. IF_NULLEXIT(pszFontFace = PszToANSI(CP_ACP, pApp->m_wszFontFace));
  976. IF_NULLEXIT(pszFontColor = PszToANSI(CP_ACP, pApp->m_wszFontColor));
  977. wnsprintf(szBuf, ARRAYSIZE(szBuf), c_szFontFmt, pszFontFace, pApp->m_iFontSize, pszFontColor);
  978. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0));
  979. }
  980. if (pApp->m_iLeftMargin > 0)
  981. {
  982. wnsprintf(szBuf, ARRAYSIZE(szBuf), c_szLeftMarginFmt, pApp->m_iLeftMargin);
  983. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0));
  984. }
  985. if (pApp->m_iTopMargin > 0)
  986. {
  987. wnsprintf(szBuf, ARRAYSIZE(szBuf), c_szTopMarginFmt, pApp->m_iTopMargin);
  988. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0));
  989. }
  990. if (pApp->m_fBold)
  991. IF_FAILEXIT(hr = pStm->Write(c_szBold, PSZ_CB(c_szBold), 0));
  992. if (pApp->m_fItalic)
  993. IF_FAILEXIT(hr = pStm->Write(c_szItalic, PSZ_CB(c_szItalic), 0));
  994. wnsprintf(szBuf, ARRAYSIZE(szBuf), c_szBkPosition, c_lppszBkPos[pApp->m_iVertPos][pApp->m_iHorzPos] );
  995. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0 ));
  996. wnsprintf(szBuf, ARRAYSIZE(szBuf), c_szBkRepeat, c_lpszRepeatPos[pApp->m_iTile]);
  997. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0 ));
  998. IF_FAILEXIT(hr = pStm->Write(c_szStyleClose, PSZ_CB(c_szStyleClose), 0));
  999. if (*pApp->m_wszBkPictureFileName)
  1000. {
  1001. StrCpyNW(wszFileSpec, pApp->m_wszBkPictureFileName, ARRAYSIZE(wszFileSpec));
  1002. if (fTemp)
  1003. {
  1004. GetStationeryFullName(wszFileSpec);
  1005. }
  1006. else
  1007. {
  1008. PathStripPathW(wszFileSpec);
  1009. }
  1010. WideCharToMultiByte(CP_ACP, 0, wszFileSpec, -1, szFileSpec, MAX_PATH, NULL, NULL);
  1011. if (*szFileSpec)
  1012. {
  1013. wnsprintf(szBuf, ARRAYSIZE(szBuf), c_szBodyFmt, c_szBkPicture, szFileSpec);
  1014. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0));
  1015. }
  1016. }
  1017. if (*pApp->m_wszBkColor)
  1018. {
  1019. IF_NULLEXIT(pszBkColor = PszToANSI(CP_ACP, pApp->m_wszBkColor));
  1020. wnsprintf(szBuf, ARRAYSIZE(szBuf), c_szBodyFmt, c_szBkColor, pszBkColor);
  1021. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0));
  1022. }
  1023. if (idsSample)
  1024. {
  1025. AthLoadString(idsSample, szBuf, ARRAYSIZE(szBuf));
  1026. for (int i=0; i<50; i++)
  1027. IF_FAILEXIT(hr = pStm->Write(szBuf, PSZ_CB(szBuf), 0));
  1028. }
  1029. IF_FAILEXIT(hr = pStm->Write(c_szHtmlClose, PSZ_CB(c_szHtmlClose), 0));
  1030. IF_FAILEXIT(hr = HrRewindStream(pStm));
  1031. IF_FAILEXIT(hr = WriteStreamToFileHandle(pStm, hFile, NULL));
  1032. IF_FAILEXIT(hr = (FlushFileBuffers(hFile)?S_OK:E_FAIL));
  1033. exit:
  1034. MemFree(pszFontFace);
  1035. MemFree(pszFontColor);
  1036. MemFree(pszBkColor);
  1037. ReleaseObj(pStm);
  1038. return hr;
  1039. }
  1040. #define PWSZ_CB(pwsz) lstrlenW(pwsz)*sizeof(*pwsz)
  1041. HRESULT FillHtmlToFileW(LPSTATWIZ pApp, HANDLE hFile, INT idsSample, BOOL fTemp)
  1042. {
  1043. WCHAR wszBuf[MAX_PATH],
  1044. wszFileSpec[MAX_PATH];
  1045. LPSTREAM pStm = NULL;
  1046. BYTE bUniMark = 0xFF;
  1047. HRESULT hr = S_OK;
  1048. *wszFileSpec = 0;
  1049. if (!hFile || !pApp)
  1050. IF_FAILEXIT(hr = E_INVALIDARG);
  1051. IF_FAILEXIT(hr = MimeOleCreateVirtualStream(&pStm));
  1052. // Write out the BOM
  1053. IF_FAILEXIT(hr = pStm->Write(&bUniMark, sizeof(bUniMark), NULL));
  1054. bUniMark = 0xFE;
  1055. IF_FAILEXIT(hr = pStm->Write(&bUniMark, sizeof(bUniMark), NULL));
  1056. IF_FAILEXIT(hr = pStm->Write(c_wszHtmlHeadFmt, PWSZ_CB(c_wszHtmlHeadFmt), 0));
  1057. if (*pApp->m_wszFontFace && pApp->m_iFontSize && *pApp->m_wszFontColor)
  1058. {
  1059. wnsprintfW(wszBuf, ARRAYSIZE(wszBuf), c_wszFontFmt, pApp->m_wszFontFace, pApp->m_iFontSize, pApp->m_wszFontColor);
  1060. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0));
  1061. }
  1062. if (pApp->m_iLeftMargin > 0)
  1063. {
  1064. wnsprintfW(wszBuf, ARRAYSIZE(wszBuf), c_wszLeftMarginFmt, pApp->m_iLeftMargin);
  1065. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0));
  1066. }
  1067. if (pApp->m_iTopMargin > 0)
  1068. {
  1069. wnsprintfW(wszBuf, ARRAYSIZE(wszBuf), c_wszTopMarginFmt, pApp->m_iTopMargin);
  1070. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0));
  1071. }
  1072. if (pApp->m_fBold)
  1073. IF_FAILEXIT(hr = pStm->Write(c_wszBold, PWSZ_CB(c_wszBold), 0));
  1074. if (pApp->m_fItalic)
  1075. IF_FAILEXIT(hr = pStm->Write(c_wszItalic, PWSZ_CB(c_wszItalic), 0));
  1076. wnsprintfW(wszBuf, ARRAYSIZE(wszBuf), c_wszBkPosition, c_lppwszBkPos[pApp->m_iVertPos][pApp->m_iHorzPos] );
  1077. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0 ));
  1078. wnsprintfW(wszBuf, ARRAYSIZE(wszBuf), c_wszBkRepeat, c_lpwszRepeatPos[pApp->m_iTile]);
  1079. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0 ));
  1080. IF_FAILEXIT(hr = pStm->Write(c_wszStyleClose, PWSZ_CB(c_wszStyleClose), 0));
  1081. if (*pApp->m_wszBkPictureFileName)
  1082. {
  1083. StrCpyNW(wszFileSpec, pApp->m_wszBkPictureFileName, ARRAYSIZE(wszFileSpec));
  1084. if (fTemp)
  1085. {
  1086. GetStationeryFullName(wszFileSpec);
  1087. }
  1088. else
  1089. {
  1090. PathStripPathW(wszFileSpec);
  1091. }
  1092. if (*wszFileSpec)
  1093. {
  1094. wnsprintfW(wszBuf, ARRAYSIZE(wszBuf), c_wszBodyFmt, c_wszBkPicture, wszFileSpec);
  1095. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0));
  1096. }
  1097. }
  1098. if (*pApp->m_wszBkColor)
  1099. {
  1100. wnsprintfW(wszBuf, ARRAYSIZE(wszBuf), c_wszBodyFmt, c_wszBkColor, pApp->m_wszBkColor);
  1101. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0));
  1102. }
  1103. if (idsSample)
  1104. {
  1105. AthLoadStringW(idsSample, wszBuf, ARRAYSIZE(wszBuf));
  1106. for (int i=0; i<50; i++)
  1107. IF_FAILEXIT(hr = pStm->Write(wszBuf, PWSZ_CB(wszBuf), 0));
  1108. }
  1109. IF_FAILEXIT(hr = pStm->Write(c_wszHtmlClose, PWSZ_CB(c_wszHtmlClose), 0));
  1110. IF_FAILEXIT(hr = HrRewindStream(pStm));
  1111. IF_FAILEXIT(hr = WriteStreamToFileHandle(pStm, hFile, NULL));
  1112. IF_FAILEXIT(hr = (FlushFileBuffers(hFile)?S_OK:E_FAIL));
  1113. exit:
  1114. ReleaseObj(pStm);
  1115. return hr;
  1116. }
  1117. HRESULT ShowPreview(HWND hwnd, LPSTATWIZ pApp, INT idsSample)
  1118. {
  1119. WCHAR wszBuf[MAX_PATH];
  1120. HRESULT hr;
  1121. LPSTREAM pStm = NULL;
  1122. LPSTR pszTempFile = NULL;
  1123. LPWSTR pwszTempFile = NULL;
  1124. HANDLE hFile=0;
  1125. *wszBuf = 0;
  1126. if (!hwnd || !pApp)
  1127. IF_FAILEXIT(hr = E_INVALIDARG);
  1128. IF_FAILEXIT(hr = CreateTempFile(c_szTempFileName, c_szHtmlExtension, &pszTempFile, &hFile));
  1129. IF_FAILEXIT(hr = FillHtmlToFile(pApp, hFile, idsSample, TRUE));
  1130. IF_NULLEXIT(pwszTempFile = PszToUnicode(CP_ACP, pszTempFile));
  1131. SendMessage(hwnd, THM_LOADPAGE, 0, (LPARAM)pwszTempFile);
  1132. exit:
  1133. if (hFile)
  1134. CloseHandle(hFile);
  1135. if (pszTempFile)
  1136. DeleteFile(pszTempFile);
  1137. MemFree(pszTempFile);
  1138. MemFree(pwszTempFile);
  1139. return hr;
  1140. }
  1141. HRESULT ShowMorePreview(HWND hwnd)
  1142. {
  1143. HRESULT hr = S_OK;
  1144. WCHAR wszFile[MAX_PATH];
  1145. TCHAR szFile[2 * MAX_PATH];
  1146. *wszFile = 0;
  1147. // Get the path of the selected file.
  1148. if (SendMessageWrapW(GetParent(hwnd), CDM_GETFILEPATH, (WPARAM)ARRAYSIZE(wszFile), (LPARAM)(LPWSTR)wszFile) &&
  1149. *wszFile!=0)
  1150. {
  1151. //Work around for a bug in SendMessageWrapW
  1152. //Win 9x returns an ANSI string in the wide buffer.
  1153. //Need to make it a real wide string
  1154. //Bug# 78619
  1155. if (VER_PLATFORM_WIN32_WINDOWS == g_OSInfo.dwPlatformId)
  1156. {
  1157. memcpy(szFile, wszFile, 2 * MAX_PATH);
  1158. MultiByteToWideChar(CP_ACP, 0, szFile, MAX_PATH, wszFile, MAX_PATH);
  1159. }
  1160. hr = ShowPreview(GetDlgItem(hwnd, IDC_MOREPREVIEW), wszFile);
  1161. }
  1162. return hr;
  1163. }
  1164. BOOL PASCAL MoreStationeryNotify(HWND hDlg, LPOFNOTIFYW pofn)
  1165. {
  1166. if (CDN_SELCHANGE == pofn->hdr.code)
  1167. {
  1168. if (IsDlgButtonChecked(hDlg, IDC_SHOWPREVIEW_CHECK))
  1169. ShowMorePreview(hDlg);
  1170. }
  1171. return TRUE;
  1172. }
  1173. BOOL FHtmlFile(LPWSTR pwszFile)
  1174. {
  1175. LPWSTR pwszExt = PathFindExtensionW(pwszFile);
  1176. if (pwszExt && (StrStrIW(pwszExt, L".htm") || StrStrIW(pwszExt, L".html")))
  1177. return TRUE;
  1178. else
  1179. return FALSE;
  1180. }
  1181. VOID InsertStationeryDir(LPWSTR pwszPicture)
  1182. {
  1183. WCHAR wszDir[MAX_PATH],
  1184. wszCopy[MAX_PATH];
  1185. LPWSTR pwszT1 = NULL,
  1186. pwszT2 = NULL;
  1187. *wszDir = 0;
  1188. *wszCopy = 0;
  1189. if(pwszPicture == NULL || lstrlenW(pwszPicture)==0)
  1190. return;
  1191. pwszT1 = StrStrIW(pwszPicture, L"\\"); //private drive
  1192. pwszT2 = StrStrIW(pwszPicture, L"/"); //URLs
  1193. if(pwszT1==NULL && pwszT2==NULL) // files in background directory.
  1194. {
  1195. if (SUCCEEDED(HrGetStationeryPath(wszDir)))
  1196. {
  1197. StrCpyNW(wszCopy, pwszPicture, ARRAYSIZE(wszCopy));
  1198. wnsprintfW(pwszPicture, MAX_PATH, L"%s\\%s", wszDir, wszCopy);
  1199. }
  1200. }
  1201. return;
  1202. }
  1203. DWORD GetShortPathNameWrapW(LPCWSTR pwszLongPath, LPWSTR pwszShortPath, DWORD cchBuffer)
  1204. {
  1205. CHAR szShortPath[MAX_PATH*2]; // Each Unicode char might go multibyte
  1206. LPSTR pszLongPath = NULL;
  1207. DWORD cch = 0,
  1208. cch2 = 0;
  1209. Assert(pwszLongPath);
  1210. Assert(pwszShortPath);
  1211. pwszShortPath[0] = L'\0';
  1212. if (VER_PLATFORM_WIN32_NT == g_OSInfo.dwPlatformId)
  1213. return(GetShortPathNameW(pwszLongPath, pwszShortPath, cchBuffer));
  1214. pszLongPath = PszToANSI(CP_ACP, pwszLongPath);
  1215. if (pszLongPath)
  1216. {
  1217. cch2 = GetShortPathName(pszLongPath, szShortPath, ARRAYSIZE(szShortPath));
  1218. if (cch2)
  1219. cch2 = MultiByteToWideChar(CP_ACP, 0, szShortPath, cch2+1, pwszShortPath, cchBuffer);
  1220. if (cch2)
  1221. cch = cch2 - 1;
  1222. MemFree(pszLongPath);
  1223. }
  1224. return cch;
  1225. }
  1226. HRESULT StripStationeryDir(LPWSTR pwszPicture)
  1227. {
  1228. WCHAR wszDir[MAX_PATH],
  1229. wszPicture[MAX_PATH],
  1230. wszPicturePath[MAX_PATH],
  1231. wszShortPath[MAX_PATH] = L"",
  1232. wszShortDir[MAX_PATH] = L"";
  1233. HRESULT hr = E_FAIL;
  1234. DWORD cch;
  1235. *wszDir = *wszPicture = *wszPicturePath = 0;
  1236. if (pwszPicture==NULL)
  1237. IF_FAILEXIT(hr = E_INVALIDARG);
  1238. IF_FAILEXIT(hr = HrGetStationeryPath(wszDir));
  1239. StrCpyNW(wszPicturePath, pwszPicture, ARRAYSIZE(wszPicturePath));
  1240. PathRemoveFileSpecW(wszPicturePath);
  1241. PathRemoveBackslashW(wszPicturePath);
  1242. if (0 == StrCmpIW(wszDir, wszPicturePath))
  1243. PathStripPathW(pwszPicture);
  1244. else
  1245. {
  1246. // Convert the Picture Path to the short name as
  1247. // it could be in the registry that way...
  1248. if((cch = GetShortPathNameWrapW(wszDir, wszShortDir, ARRAYSIZE(wszShortDir)))==0)
  1249. {
  1250. hr = E_FAIL;
  1251. goto exit;
  1252. }
  1253. if((cch = GetShortPathNameWrapW(wszPicturePath, wszShortPath, ARRAYSIZE(wszShortPath)))==0)
  1254. {
  1255. hr = E_FAIL;
  1256. goto exit;
  1257. }
  1258. if (0 == StrCmpIW(wszShortDir, wszShortPath))
  1259. PathStripPathW(pwszPicture);
  1260. }
  1261. exit:
  1262. return hr;
  1263. }
  1264. BOOL GetStationeryFullName(LPWSTR pwszName)
  1265. {
  1266. WCHAR wszBuf[MAX_PATH];
  1267. DWORD dwAttributes;
  1268. HRESULT hr = S_OK;
  1269. *wszBuf = 0;
  1270. if (pwszName==NULL || *pwszName==0)
  1271. IF_FAILEXIT(hr = E_INVALIDARG);
  1272. InsertStationeryDir(pwszName);
  1273. StrCpyNW(wszBuf, pwszName, ARRAYSIZE(wszBuf));
  1274. if (!FHtmlFile(wszBuf))
  1275. PathAddExtensionW(wszBuf, L".htm");
  1276. if (!PathFileExistsW(wszBuf))
  1277. {
  1278. StrCpyNW(wszBuf, pwszName, ARRAYSIZE(wszBuf));
  1279. if (!FHtmlFile(wszBuf))
  1280. PathAddExtensionW(wszBuf, L".html");
  1281. if (!PathFileExistsW(wszBuf))
  1282. {
  1283. *pwszName = 0; //this file does not exist.
  1284. IF_FAILEXIT(hr = E_FAIL);
  1285. }
  1286. }
  1287. StrCpyNW(pwszName, wszBuf, MAX_PATH);
  1288. exit:
  1289. return SUCCEEDED(hr);
  1290. }
  1291. BOOL IsValidCreateFileName(LPWSTR pwszFile)
  1292. {
  1293. BOOL fRet = TRUE;
  1294. WCHAR wszBuf[MAX_PATH];
  1295. HANDLE hFile;
  1296. *wszBuf = 0;
  1297. StrCpyNW(wszBuf, pwszFile, ARRAYSIZE(wszBuf));
  1298. if (!FHtmlFile(wszBuf))
  1299. PathAddExtensionW(wszBuf, L".htm");
  1300. InsertStationeryDir(wszBuf);
  1301. if (!PathFileExistsW(wszBuf))
  1302. {
  1303. hFile = CreateFileWrapW(wszBuf, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
  1304. if (hFile != INVALID_HANDLE_VALUE)
  1305. {
  1306. CloseHandle(hFile);
  1307. DeleteFileWrapW(wszBuf);
  1308. StrCpyNW(pwszFile, wszBuf, MAX_PATH);
  1309. fRet = FALSE;
  1310. }
  1311. }
  1312. return fRet;
  1313. }
  1314. LRESULT StationeryListBox_AddString(HWND hwndList, LPWSTR pwszFileName)
  1315. {
  1316. LRESULT lr=CB_ERR;
  1317. WCHAR wszBuf[MAX_PATH];
  1318. HDC hdc;
  1319. PAINTSTRUCT ps;
  1320. SIZE rSize;
  1321. HFONT hfontOld, hfont;
  1322. *wszBuf = 0;
  1323. if(pwszFileName==NULL || *pwszFileName==0)
  1324. return lr;
  1325. StrCpyNW(wszBuf, pwszFileName, ARRAYSIZE(wszBuf));
  1326. StripStationeryDir(wszBuf);
  1327. PathRemoveExtensionW(wszBuf);
  1328. // If cannot find it
  1329. if (SendMessageWrapW(hwndList, LB_FINDSTRINGEXACT, 0, (LPARAM)wszBuf))
  1330. {
  1331. hdc = GetDC(hwndList);
  1332. hfont = (HFONT) SendMessage(hwndList, WM_GETFONT, 0, 0);
  1333. hfontOld = (HFONT) SelectObject(hdc, hfont);
  1334. GetTextExtentPoint32AthW(hdc, wszBuf, lstrlenW(wszBuf), &rSize, NOFLAGS);
  1335. SelectObject(hdc, hfontOld);
  1336. ReleaseDC(hwndList, hdc);
  1337. if((rSize.cx+10) > ListBox_GetHorizontalExtent(hwndList))
  1338. ListBox_SetHorizontalExtent(hwndList, rSize.cx+10);
  1339. lr = SendMessageWrapW(hwndList, LB_ADDSTRING, 0, (LPARAM)wszBuf);
  1340. }
  1341. return lr;
  1342. }
  1343. LRESULT StationeryListBox_SelectString(HWND hwndList, LPWSTR pwszFileName)
  1344. {
  1345. LRESULT lr=CB_ERR;
  1346. WCHAR wszBuf[MAX_PATH];
  1347. *wszBuf = 0;
  1348. if (pwszFileName != NULL && *pwszFileName != 0)
  1349. {
  1350. StrCpyNW(wszBuf, pwszFileName, ARRAYSIZE(wszBuf));
  1351. StripStationeryDir(wszBuf);
  1352. PathRemoveExtensionW(wszBuf);
  1353. lr = SendMessageWrapW(hwndList, LB_FINDSTRINGEXACT, 0, (LPARAM)wszBuf);
  1354. }
  1355. if (lr < 0)
  1356. lr = 0;
  1357. ListBox_SetCurSel(hwndList, lr);
  1358. return lr;
  1359. }
  1360. LRESULT StationeryComboBox_SelectString(HWND hwndCombo, LPWSTR pwszFileName)
  1361. {
  1362. LRESULT lr=CB_ERR;
  1363. WCHAR wszBuf[MAX_PATH];
  1364. *wszBuf = 0;
  1365. if (pwszFileName != NULL && *pwszFileName != 0)
  1366. {
  1367. StrCpyNW(wszBuf, pwszFileName, ARRAYSIZE(wszBuf));
  1368. StripStationeryDir(wszBuf);
  1369. lr = SendMessageWrapW(hwndCombo, LB_FINDSTRINGEXACT, 0, (LPARAM)wszBuf);
  1370. }
  1371. if (lr < 0)
  1372. lr = 0;
  1373. ComboBox_SetCurSel(hwndCombo, lr);
  1374. return lr;
  1375. }
  1376. HRESULT HrLoadStationery(HWND hwndList, LPWSTR pwszStationery)
  1377. {
  1378. HRESULT hr = NOERROR;
  1379. LPWSTR pwszFiles = NULL,
  1380. pwszT = NULL,
  1381. pwsz = NULL;
  1382. LRESULT lr=0;
  1383. WCHAR wszDir[MAX_PATH];
  1384. DWORD dw, dwType=0, cb=0;
  1385. HKEY hkey=NULL;
  1386. INT i;
  1387. *wszDir = 0;
  1388. ListBox_ResetContent(hwndList);
  1389. IF_FAILEXIT(hr = HrGetStationeryPath(wszDir))
  1390. for(i = 0; i < (ARRAYSIZE(c_rgpwszHTMLExtensions)); i++)
  1391. {
  1392. if(pwszFiles = Util_EnumFiles(wszDir, c_rgpwszHTMLExtensions[i]))
  1393. {
  1394. pwszT = pwszFiles;
  1395. while (*pwszT)
  1396. {
  1397. lr = StationeryListBox_AddString(hwndList, pwszT);
  1398. pwszT += (lstrlenW(pwszT) + 1);
  1399. }
  1400. }
  1401. SafeMemFree(pwszFiles);
  1402. }
  1403. StationeryListBox_AddString(hwndList, pwszStationery);
  1404. exit:
  1405. StationeryListBox_SelectString(hwndList, pwszStationery);
  1406. return hr;
  1407. }
  1408. HRESULT HrBrowsePicture(HWND hwndParent, HWND hwndCombo)
  1409. {
  1410. OPENFILENAMEW ofn;
  1411. WCHAR wszOpenFileName[MAX_PATH],
  1412. wsz[MAX_PATH],
  1413. wszDir[MAX_PATH],
  1414. wszTitle[MAX_PATH];
  1415. LPWSTR pwszDir = NULL;
  1416. HRESULT hr;
  1417. *wszOpenFileName = *wsz = *wszDir = *wszTitle = 0;
  1418. ZeroMemory(&ofn, sizeof(ofn));
  1419. AthLoadStringW(idsImageFileFilter, wsz, ARRAYSIZE(wsz));
  1420. ReplaceCharsW(wsz, L'|', L'\0');
  1421. AthLoadStringW(idsPictureTitle, wszTitle, ARRAYSIZE(wszTitle));
  1422. hr = HrGetStationeryPath(wszDir);
  1423. if(SUCCEEDED(hr))
  1424. pwszDir = wszDir;
  1425. ofn.lStructSize = sizeof(ofn);
  1426. ofn.hwndOwner = hwndParent;
  1427. ofn.hInstance = g_hLocRes;
  1428. ofn.lpstrFilter = wsz;
  1429. ofn.nFilterIndex = 1;
  1430. ofn.lpstrFile = wszOpenFileName;
  1431. ofn.nMaxFile = MAX_PATH;
  1432. ofn.lpstrInitialDir = pwszDir;
  1433. ofn.lpstrTitle = wszTitle;
  1434. ofn.Flags = OFN_EXPLORER |
  1435. OFN_HIDEREADONLY |
  1436. OFN_FILEMUSTEXIST |
  1437. OFN_NODEREFERENCELINKS|
  1438. OFN_NOCHANGEDIR;
  1439. if(GetOpenFileNameWrapW(&ofn))
  1440. PictureComboBox_AddString(hwndCombo, wszOpenFileName);
  1441. return hr;
  1442. }
  1443. // lpszPicture is the default picture name,
  1444. HRESULT HrFillStationeryCombo(HWND hwndCombo, BOOL fBackGround, LPWSTR pwszPicture)
  1445. {
  1446. HRESULT hr = NOERROR;
  1447. LPWSTR pwszFiles = NULL,
  1448. pwszT = NULL,
  1449. pwsz = NULL;
  1450. const LPWSTR *pwszExtension = NULL;
  1451. LRESULT lr=0;
  1452. WCHAR wszDir[MAX_PATH];
  1453. DWORD dw,
  1454. dwType=0,
  1455. cb = 0;
  1456. HKEY hkey=NULL;
  1457. INT i, size;
  1458. *wszDir = 0;
  1459. IF_FAILEXIT(hr = HrGetStationeryPath(wszDir));
  1460. if (fBackGround)
  1461. {
  1462. pwszExtension = c_wszPictureExtensions;
  1463. size = ARRAYSIZE(c_wszPictureExtensions);
  1464. }
  1465. else
  1466. {
  1467. pwszExtension = c_rgpwszHTMLExtensions;
  1468. size = ARRAYSIZE(c_rgpwszHTMLExtensions);
  1469. }
  1470. for(i = 0; i < size; i++)
  1471. {
  1472. if(pwszFiles = Util_EnumFiles(wszDir, pwszExtension[i]))
  1473. {
  1474. pwszT = pwszFiles;
  1475. while (*pwszT)
  1476. {
  1477. lr = SendMessageWrapW(hwndCombo, CB_ADDSTRING, 0, (LPARAM)pwszT);
  1478. if (lr == CB_ERR || lr == CB_ERRSPACE)
  1479. break;
  1480. pwszT += (lstrlenW(pwszT) + 1);
  1481. }
  1482. }
  1483. SafeMemFree(pwszFiles);
  1484. if(lr == CB_ERR || lr == CB_ERRSPACE)
  1485. break;
  1486. }
  1487. exit:
  1488. // add the default picture name.
  1489. if (pwszPicture)
  1490. PictureComboBox_AddString(hwndCombo, pwszPicture);
  1491. return hr;
  1492. }
  1493. // add default picture name to the background picture combobox.
  1494. LRESULT PictureComboBox_AddString(HWND hwndCombo, LPWSTR pwszPicture)
  1495. {
  1496. LRESULT lr=CB_ERR;
  1497. if(pwszPicture==NULL || *pwszPicture==0 || !IsValidFileName(pwszPicture))
  1498. return lr;
  1499. StripStationeryDir(pwszPicture);
  1500. if (SendMessageWrapW(hwndCombo, CB_FINDSTRINGEXACT, (WPARAM)0, (LPARAM)pwszPicture) < 0)
  1501. {
  1502. lr = SendMessageWrapW(hwndCombo, CB_ADDSTRING, 0, (LPARAM)pwszPicture);
  1503. if(lr==CB_ERR || lr==CB_ERRSPACE)
  1504. return lr;
  1505. }
  1506. lr = SendMessageWrapW(hwndCombo, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)pwszPicture);
  1507. return lr;
  1508. }
  1509. BOOL IsValidFileName(LPWSTR pwszFile)
  1510. {
  1511. BOOL fRet = TRUE;
  1512. WCHAR wszBuf[INTERNET_MAX_URL_LENGTH];
  1513. *wszBuf = 0;
  1514. if(pwszFile == NULL || *pwszFile == 0)
  1515. {
  1516. fRet = FALSE;
  1517. goto exit;
  1518. }
  1519. StrCpyNW(wszBuf, pwszFile, ARRAYSIZE(wszBuf));
  1520. InsertStationeryDir(wszBuf);
  1521. if(!PathIsURLW(wszBuf))
  1522. {
  1523. if(!PathFileExistsW(wszBuf))
  1524. {
  1525. fRet = FALSE;
  1526. goto exit;
  1527. }
  1528. }
  1529. exit:
  1530. return fRet;
  1531. }
  1532. // Assumes that pwszName is of at least MAX_PATH chars
  1533. HRESULT GetDefaultStationeryName(BOOL fMail, LPWSTR pwszName)
  1534. {
  1535. DWORD fConverted = TRUE;
  1536. CHAR szName[MAX_PATH];
  1537. *pwszName = 0;
  1538. *szName = 0;
  1539. fConverted = DwGetOption(fMail?OPT_MAIL_STATCONVERTED:OPT_NEWS_STATCONVERTED);
  1540. if (!fConverted)
  1541. {
  1542. fConverted = TRUE;
  1543. GetOption(fMail?OPT_MAIL_STATIONERYNAME:OPT_NEWS_STATIONERYNAME, szName, sizeof(szName));
  1544. MultiByteToWideChar(CP_ACP, 0, szName, -1, pwszName, MAX_PATH);
  1545. SetDefaultStationeryName(fMail, pwszName);
  1546. }
  1547. else
  1548. GetOption(fMail?OPT_MAIL_STATIONERYNAMEW:OPT_NEWS_STATIONERYNAMEW, pwszName, MAX_PATH*sizeof(WCHAR));
  1549. return (0 == *pwszName) ? E_FAIL : S_OK;
  1550. }
  1551. HRESULT SetDefaultStationeryName(BOOL fMail, LPWSTR pwszName)
  1552. {
  1553. DWORD fConverted = TRUE;
  1554. SetOption(fMail?OPT_MAIL_STATIONERYNAMEW:OPT_NEWS_STATIONERYNAMEW, pwszName, (lstrlenW(pwszName)+1)*sizeof(WCHAR), NULL, 0);
  1555. SetDwOption(fMail?OPT_MAIL_STATCONVERTED:OPT_NEWS_STATCONVERTED, fConverted, NULL, 0);
  1556. return S_OK;
  1557. }