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.

1413 lines
43 KiB

  1. // =================================================================================
  2. // F O N T S . C P P
  3. // =================================================================================
  4. #include "pch.hxx"
  5. #include "fonts.h"
  6. #include "multlang.h"
  7. #include "xpcomm.h"
  8. #include "strconst.h"
  9. #include "mimeole.h"
  10. #include "goptions.h"
  11. #include "error.h"
  12. #include "thormsgs.h"
  13. #include "richedit.h"
  14. #include "ibodyopt.h"
  15. #include "shlwapi.h"
  16. #include "shlwapip.h"
  17. #include "mimeutil.h"
  18. #include "optres.h"
  19. #include "demand.h"
  20. #include "menures.h"
  21. #include "multiusr.h"
  22. // this part creates a MIME COM object from MLAMG.DLL which gives us a consistent
  23. // language menu to be the same as IE browser
  24. // HMENU CreateMimeLanguageMenu(void)
  25. #include <inetreg.h>
  26. #include <mlang.h>
  27. #include "resource.h"
  28. #define IGNORE_HR(x) (x)
  29. #define MIMEINFO_NAME_MAX 72
  30. #define DEFAULT_FONTSIZE 2
  31. // MLANG language menu items table
  32. static PMIMECPINFO g_pMimeCPInfo = NULL;
  33. static ULONG g_cMimeCPInfoCount = 0;
  34. static DWORD g_cRefMultiLanguage = 0;
  35. TCHAR g_szMore[32];
  36. #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
  37. #define BREAK_ITEM 20
  38. #define CP_UNDEFINED UINT(-1)
  39. #define CP_AUTO 50001 // cross language detection
  40. #define CP_1252 1252 // Ansi, Western Europe
  41. #define CCPDEFAULT 2
  42. void SendTridentOptionsChange();
  43. typedef struct {
  44. UINT cp;
  45. ULONG ulIdx;
  46. int cUsed;
  47. } CPCACHE;
  48. class CCachedCPInfo
  49. {
  50. public:
  51. CCachedCPInfo();
  52. static void InitCpCache (PMIMECPINFO pcp, ULONG ccp);
  53. static void SaveCodePage (UINT codepage, PMIMECPINFO pcp, ULONG ccp);
  54. BOOL fAutoSelectInstalled;
  55. BOOL fAutoSelectChecked;
  56. static UINT GetCodePage(int idx)
  57. {
  58. return idx < ARRAY_SIZE(_CpCache) ? _CpCache[idx].cp: 0;
  59. }
  60. static ULONG GetCcp()
  61. {
  62. return _ccpInfo;
  63. }
  64. static ULONG GetMenuIdx(int idx)
  65. {
  66. return idx < ARRAY_SIZE(_CpCache) ? _CpCache[idx].ulIdx: 0;
  67. }
  68. private:
  69. static ULONG _ccpInfo;
  70. static CPCACHE _CpCache[5];
  71. };
  72. CCachedCPInfo::CCachedCPInfo()
  73. {
  74. fAutoSelectInstalled = FALSE;
  75. fAutoSelectChecked = FALSE;
  76. }
  77. // declaration for static members
  78. ULONG CCachedCPInfo::_ccpInfo = CCPDEFAULT;
  79. CPCACHE CCachedCPInfo::_CpCache[5] =
  80. {
  81. {CP_AUTO, 0, 0}, // cross-codepage autodetect
  82. {CP_1252,0,0},
  83. };
  84. CCachedCPInfo g_cpcache;
  85. // useful macros...
  86. inline BOOL IsPrimaryCodePage(MIMECPINFO *pcpinfo)
  87. {
  88. return pcpinfo->uiCodePage == pcpinfo->uiFamilyCodePage;
  89. }
  90. //------------------------------------------------------------------------
  91. //
  92. // Function: CCachedCPInfo::InitCpCache
  93. //
  94. // Initialize the cache with default codepages
  95. // which do not change through the session
  96. //
  97. //------------------------------------------------------------------------
  98. void CCachedCPInfo::InitCpCache (PMIMECPINFO pcp, ULONG ccp)
  99. {
  100. UINT iCache, iCpInfo;
  101. if (pcp && ccp > 0)
  102. {
  103. for (iCache= 0; iCache < CCPDEFAULT; iCache++)
  104. {
  105. for (iCpInfo= 0; iCpInfo < ccp; iCpInfo++)
  106. {
  107. if ( pcp[iCpInfo].uiCodePage == _CpCache[iCache].cp )
  108. {
  109. if(CP_AUTO == _CpCache[iCache].cp)
  110. {
  111. g_cpcache.fAutoSelectInstalled = TRUE;
  112. }
  113. _CpCache[iCache].ulIdx = iCpInfo;
  114. _CpCache[iCache].cUsed = ARRAY_SIZE(_CpCache)-1;
  115. break;
  116. }
  117. }
  118. }
  119. }
  120. }
  121. //------------------------------------------------------------------------
  122. //
  123. // Function: CCachedCPInfo::SaveCodePage
  124. //
  125. // Cache the given codepage along with the index to
  126. // the given array of MIMECPINFO
  127. //
  128. //------------------------------------------------------------------------
  129. void CCachedCPInfo::SaveCodePage (UINT codepage, PMIMECPINFO pcp, ULONG ccp)
  130. {
  131. int ccpSave = -1;
  132. BOOL bCached = FALSE;
  133. UINT i;
  134. // first check if we already have this cp
  135. for (i = 0; i < _ccpInfo; i++)
  136. {
  137. if (_CpCache[i].cp == codepage)
  138. {
  139. ccpSave = i;
  140. bCached = TRUE;
  141. break;
  142. }
  143. }
  144. // if cache is not full, use the current
  145. // index to an entry
  146. if (ccpSave < 0 && _ccpInfo < ARRAY_SIZE(_CpCache))
  147. {
  148. ccpSave = _ccpInfo;
  149. }
  150. // otherwise, popout the least used entry.
  151. // the default codepages always stay
  152. // this also decriments the usage count
  153. int cMinUsed = ARRAY_SIZE(_CpCache);
  154. UINT iMinUsed = 0;
  155. for ( i = CCPDEFAULT; i < _ccpInfo; i++)
  156. {
  157. if (_CpCache[i].cUsed > 0)
  158. _CpCache[i].cUsed--;
  159. if ( ccpSave < 0 && _CpCache[i].cUsed < cMinUsed)
  160. {
  161. cMinUsed = _CpCache[i].cUsed;
  162. iMinUsed = i;
  163. }
  164. }
  165. if (ccpSave < 0)
  166. ccpSave = iMinUsed;
  167. // set initial usage count, which goes down to 0 if it doesn't get
  168. // chosen twice in a row (with current array size)
  169. _CpCache[ccpSave].cUsed = ARRAY_SIZE(_CpCache)-1;
  170. // find a matching entry from given array of
  171. // mimecpinfo
  172. if (pcp && ccp > 0)
  173. {
  174. for (i= 0; i < ccp; i++)
  175. {
  176. if ( pcp[i].uiCodePage == codepage )
  177. {
  178. _CpCache[ccpSave].cp = codepage;
  179. _CpCache[ccpSave].ulIdx = i;
  180. if (!bCached && _ccpInfo < ARRAY_SIZE(_CpCache))
  181. _ccpInfo++;
  182. break;
  183. }
  184. }
  185. }
  186. }
  187. // Get UI language which can shown, using System fonts
  188. LANGID OEGetUILang()
  189. {
  190. LANGID lidUI = MLGetUILanguage();
  191. if(fIsNT5()) // Nothing for NT5
  192. return(lidUI);
  193. if (0x0409 != lidUI) // US resource is always no need to munge
  194. {
  195. CHAR szUICP[8];
  196. CHAR szInstallCP[8];
  197. GetLocaleInfo(MAKELCID(lidUI, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szUICP, ARRAYSIZE(szUICP));
  198. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE, szInstallCP, ARRAYSIZE(szInstallCP));
  199. if (lstrcmpi(szUICP, szInstallCP)) // return default user language ID
  200. return(LANGIDFROMLCID(LOCALE_USER_DEFAULT));
  201. }
  202. return (lidUI); // return lang ID from MLGetUILanguage()
  203. }
  204. BOOL CheckAutoSelect(UINT * CodePage)
  205. {
  206. if(g_cpcache.fAutoSelectChecked)
  207. {
  208. *CodePage = CP_AUTO;
  209. return(TRUE);
  210. }
  211. return(FALSE);
  212. }
  213. HRESULT _InitMultiLanguage(void)
  214. {
  215. HRESULT hr;
  216. IMultiLanguage *pMLang1=NULL;
  217. IMultiLanguage2 *pMLang2=NULL;
  218. // check if data has been initialized
  219. if (g_pMimeCPInfo)
  220. return S_OK ;
  221. Assert(g_cMimeCPInfoCount == NULL );
  222. // create MIME COM object
  223. hr = CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (void**)&pMLang2);
  224. if (FAILED(hr))
  225. hr = CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage, (void**)&pMLang1);
  226. if (SUCCEEDED(hr))
  227. {
  228. UINT cNum;
  229. IEnumCodePage *pEnumCodePage;
  230. if (pMLang2)
  231. {
  232. hr = pMLang2->EnumCodePages(MIMECONTF_MAILNEWS | MIMECONTF_VALID, OEGetUILang(), &pEnumCodePage);
  233. if (SUCCEEDED(hr))
  234. pMLang2->GetNumberOfCodePageInfo(&cNum);
  235. }
  236. else
  237. {
  238. hr = pMLang1->EnumCodePages(MIMECONTF_MAILNEWS | MIMECONTF_VALID, &pEnumCodePage);
  239. if (SUCCEEDED(hr))
  240. pMLang1->GetNumberOfCodePageInfo(&cNum);
  241. }
  242. if (SUCCEEDED(hr))
  243. {
  244. MemAlloc((LPVOID *)&g_pMimeCPInfo, sizeof(MIMECPINFO) * cNum);
  245. if ( g_pMimeCPInfo )
  246. {
  247. ZeroMemory(g_pMimeCPInfo, sizeof(MIMECPINFO) * cNum);
  248. hr = pEnumCodePage->Next(cNum, g_pMimeCPInfo, &g_cMimeCPInfoCount);
  249. IGNORE_HR(MemRealloc((void **)&g_pMimeCPInfo, sizeof(MIMECPINFO) * g_cMimeCPInfoCount));
  250. }
  251. pEnumCodePage->Release();
  252. }
  253. // Release Objects
  254. SafeRelease(pMLang1);
  255. SafeRelease(pMLang2);
  256. }
  257. // get default charset, before user make any change to View/Language
  258. if (g_hDefaultCharsetForMail == NULL)
  259. ReadSendMailDefaultCharset();
  260. return hr;
  261. }
  262. HRESULT InitMultiLanguage(void)
  263. {
  264. // we defer the call to _InitMultiLanguage until it is necessary
  265. // add reference count
  266. g_cRefMultiLanguage++ ;
  267. return S_OK ;
  268. }
  269. void DeinitMultiLanguage(void)
  270. {
  271. // decrease reference count
  272. if ( g_cRefMultiLanguage )
  273. g_cRefMultiLanguage--;
  274. if ( g_cRefMultiLanguage <= 0 )
  275. {
  276. if ( g_pMimeCPInfo)
  277. {
  278. MemFree(g_pMimeCPInfo);
  279. g_pMimeCPInfo = NULL;
  280. g_cMimeCPInfoCount = 0;
  281. }
  282. WriteSendMailDefaultCharset();
  283. }
  284. return ;
  285. }
  286. HMENU CreateMimeLanguageMenu(BOOL bMailNote, BOOL bReadNote, UINT cp)
  287. {
  288. ULONG i;
  289. HMENU hMenu = NULL;
  290. ULONG cchXlated ;
  291. UINT uCodePage ;
  292. CHAR szBuffer[MIMEINFO_NAME_MAX];
  293. BOOL fUseSIO;
  294. BOOL fBroken = FALSE;
  295. ULONG iMenuIdx;
  296. UINT uNoteCP;
  297. if(fIsNT5())
  298. {
  299. if(GetLocaleInfoW(OEGetUILang(),
  300. LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
  301. (LPWSTR)(&uCodePage),
  302. sizeof(UINT)/sizeof(WCHAR) ) != sizeof(UINT)/sizeof(WCHAR))
  303. uCodePage = GetACP();
  304. }
  305. else
  306. uCodePage = GetACP();
  307. if(!cp)
  308. uNoteCP = uCodePage;
  309. else
  310. uNoteCP = GetMapCP(cp, bReadNote);
  311. bMailNote = FALSE;
  312. hMenu = CreatePopupMenu();
  313. if ( g_pMimeCPInfo == NULL)
  314. {
  315. _InitMultiLanguage();
  316. if ( g_pMimeCPInfo == NULL)
  317. {
  318. // create an empty menu
  319. LoadString(g_hLocRes, idsEmptyStr, szBuffer, MIMEINFO_NAME_MAX);
  320. AppendMenu(hMenu, MF_DISABLED|MF_GRAYED , (UINT)-1, szBuffer);
  321. return hMenu ;
  322. }
  323. }
  324. g_cpcache.InitCpCache(g_pMimeCPInfo, g_cMimeCPInfoCount);
  325. g_cpcache.SaveCodePage(uNoteCP, g_pMimeCPInfo, g_cMimeCPInfoCount);
  326. for(i = 0; i < g_cpcache.GetCcp(); i++)
  327. {
  328. iMenuIdx = g_cpcache.GetMenuIdx(i);
  329. // cchXlated = WideCharToMultiByte(uCodePage, 0, g_pMimeCPInfo[iMenuIdx].wszDescription, -1, szBuffer, MIMEINFO_NAME_MAX, NULL, NULL);
  330. if(!fCheckEncodeMenu(g_pMimeCPInfo[iMenuIdx].uiCodePage, bReadNote))
  331. continue ;
  332. if(i != 0)
  333. AppendMenuWrapW(hMenu, MF_ENABLED, iMenuIdx + ID_LANG_FIRST,g_pMimeCPInfo[iMenuIdx].wszDescription);
  334. // [SBAILEY]: Raid 69638: oe:ml: Autoselect doesnt work (we don't support global encoding auto-detect, therefore don't show it
  335. #if 0
  336. else if(g_cpcache.fAutoSelectInstalled && bReadNote)
  337. {
  338. AppendMenuWrapW(hMenu, MF_ENABLED, iMenuIdx + ID_LANG_FIRST,g_pMimeCPInfo[iMenuIdx].wszDescription);
  339. AppendMenuWrapW(hMenu, MF_SEPARATOR, 0, 0);
  340. }
  341. #endif
  342. // mark the cp entry so we can skip it for submenu
  343. // this assumes we'd never use the MSB for MIMECONTF
  344. g_pMimeCPInfo[iMenuIdx].dwFlags |= 0x80000000;
  345. }
  346. // Check Params
  347. Assert(g_pMimeCPInfo);
  348. Assert(g_cMimeCPInfoCount > 0 );
  349. // add the submenu for the rest of encodings
  350. HMENU hSubMenu = CreatePopupMenu();
  351. UINT uiLastFamilyCp = 0;
  352. if ( g_cMimeCPInfoCount )
  353. {
  354. // Get System CodePage
  355. if (hSubMenu)
  356. {
  357. for (i = 0; i < g_cMimeCPInfoCount ; i++)
  358. {
  359. if(!fCheckEncodeMenu(g_pMimeCPInfo[i].uiCodePage, bReadNote))
  360. continue ;
  361. // skip codepages that are on teir1 menu
  362. if (!(g_pMimeCPInfo[i].dwFlags & 0x80000000))
  363. {
  364. if ((g_pMimeCPInfo[i].dwFlags & MIMECONTF_VALID)
  365. || IsPrimaryCodePage(g_pMimeCPInfo+i))
  366. {
  367. UINT uiFlags = MF_ENABLED;
  368. if (uiLastFamilyCp > 0
  369. && uiLastFamilyCp != g_pMimeCPInfo[i].uiFamilyCodePage)
  370. {
  371. // add separater between different family unless
  372. // we will be adding the menu bar break
  373. if(i < BREAK_ITEM || fBroken)
  374. {
  375. AppendMenuWrapW(hSubMenu, MF_SEPARATOR, 0, 0);
  376. }
  377. else
  378. {
  379. uiFlags |= MF_MENUBARBREAK;
  380. fBroken = TRUE;
  381. }
  382. }
  383. // This menu gets really long. Let's break at a defined number so it all
  384. // fits on the screen
  385. /* cchXlated = WideCharToMultiByte(uCodePage,
  386. 0,
  387. g_pMimeCPInfo[i].wszDescription,
  388. -1,
  389. szBuffer,
  390. MIMEINFO_NAME_MAX
  391. , NULL
  392. , NULL); */
  393. AppendMenuWrapW(hSubMenu,
  394. uiFlags,
  395. i+ID_LANG_FIRST,
  396. g_pMimeCPInfo[i].wszDescription);
  397. // save the family of added codepage
  398. uiLastFamilyCp = g_pMimeCPInfo[i].uiFamilyCodePage;
  399. }
  400. }
  401. else
  402. g_pMimeCPInfo[i].dwFlags &= 0x7FFFFFFF;
  403. }
  404. // add this submenu to the last of tier1 menu
  405. if (!g_szMore[0])
  406. {
  407. LoadString(g_hLocRes,
  408. idsEncodingMore,
  409. g_szMore,
  410. ARRAY_SIZE(g_szMore));
  411. }
  412. if (GetMenuItemCount(hSubMenu) > 0)
  413. {
  414. MENUITEMINFO mii;
  415. mii.cbSize = sizeof(MENUITEMINFO);
  416. mii.fMask = MIIM_SUBMENU;
  417. mii.hSubMenu = hSubMenu;
  418. AppendMenu(hMenu, MF_DISABLED, ID_POPUP_LANGUAGE_MORE, g_szMore);
  419. SetMenuItemInfo(hMenu, ID_POPUP_LANGUAGE_MORE, FALSE, &mii);
  420. }
  421. else
  422. {
  423. DestroyMenu(hSubMenu);
  424. }
  425. }
  426. }
  427. else
  428. {
  429. // create an empty menu
  430. LoadString(g_hLocRes, idsEmptyStr, szBuffer, MIMEINFO_NAME_MAX);
  431. AppendMenu(hMenu, MF_DISABLED|MF_GRAYED , (UINT)-1, szBuffer);
  432. }
  433. return hMenu;
  434. }
  435. HCHARSET GetMimeCharsetFromMenuID(int nIdm)
  436. {
  437. UINT idx;
  438. HCHARSET hCharset = NULL ;
  439. ULONG cchXlated ;
  440. UINT uCodePage ;
  441. CHAR szBuffer[MIMEINFO_NAME_MAX];
  442. idx = nIdm - ID_LANG_FIRST;
  443. if((g_pMimeCPInfo[idx].uiCodePage == CP_AUTO) && g_cpcache.fAutoSelectInstalled) // Auto Select selected
  444. {
  445. g_cpcache.fAutoSelectChecked = !g_cpcache.fAutoSelectChecked;
  446. return(NULL);
  447. }
  448. if ( g_pMimeCPInfo && idx < g_cMimeCPInfoCount )
  449. {
  450. uCodePage = GetACP();
  451. cchXlated = WideCharToMultiByte(uCodePage, 0, g_pMimeCPInfo[idx].wszBodyCharset, -1, szBuffer, ARRAYSIZE(szBuffer), NULL, NULL);
  452. szBuffer[ARRAYSIZE(szBuffer) - 1] = '\0'; //better safe than not null-terminated
  453. // check if BodyCharset starts with '_' like "_iso-2022-JP$ESC"
  454. // if it is, use BodyCharset
  455. // otherwise, use WebCharset
  456. // BUGBUG - special case for Korean 949 use BodyCharset, fix by RTM
  457. if ( szBuffer[0] != '_' && 949 != g_pMimeCPInfo[idx].uiCodePage)
  458. {
  459. cchXlated = WideCharToMultiByte(uCodePage, 0, g_pMimeCPInfo[idx].wszWebCharset, -1, szBuffer, ARRAYSIZE(szBuffer), NULL, NULL);
  460. szBuffer[ARRAYSIZE(szBuffer) - 1] = '\0'; //better safe than not null-terminated
  461. }
  462. MimeOleFindCharset(szBuffer,&hCharset);
  463. }
  464. return hCharset ;
  465. }
  466. HCHARSET GetMimeCharsetFromCodePage(UINT uiCodePage )
  467. {
  468. HCHARSET hCharset = NULL ;
  469. ULONG cchXlated, i ;
  470. UINT uCodePage ;
  471. CHAR szBuffer[MIMEINFO_NAME_MAX];
  472. if ( g_pMimeCPInfo == NULL)
  473. _InitMultiLanguage();
  474. if ( g_pMimeCPInfo )
  475. {
  476. uCodePage = GetACP();
  477. for (i = 0; i < g_cMimeCPInfoCount ; i++)
  478. {
  479. if (uiCodePage == g_pMimeCPInfo[i].uiCodePage)
  480. {
  481. cchXlated = WideCharToMultiByte(uCodePage, 0, g_pMimeCPInfo[i].wszBodyCharset, -1, szBuffer, ARRAYSIZE(szBuffer), NULL, NULL);
  482. szBuffer[ARRAYSIZE(szBuffer) - 1] = '\0'; //better safe than not null-terminated
  483. // check if BodyCharset starts with '_' like "_iso-2022-JP$ESC"
  484. // if it is, use BodyCharset
  485. // otherwise, use WebCharset
  486. // BUGBUG - special case for Korean 949 use BodyCharset, fix by RTM
  487. if ( szBuffer[0] != '_' && 949 != g_pMimeCPInfo[i].uiCodePage)
  488. {
  489. cchXlated = WideCharToMultiByte(uCodePage, 0, g_pMimeCPInfo[i].wszWebCharset, -1, szBuffer, ARRAYSIZE(szBuffer), NULL, NULL);
  490. szBuffer[ARRAYSIZE(szBuffer) - 1] = '\0'; //better safe than not null-terminated
  491. }
  492. MimeOleFindCharset(szBuffer,&hCharset);
  493. break ;
  494. }
  495. }
  496. }
  497. return hCharset ;
  498. }
  499. void _GetMimeCharsetLangString(BOOL bWebCharset, UINT uiCodePage, LPINT pnIdm, LPTSTR lpszString, int nSize )
  500. {
  501. ULONG i, cchXlated ;
  502. UINT uCodePage ;
  503. if ( g_pMimeCPInfo == NULL)
  504. _InitMultiLanguage();
  505. if ( g_cMimeCPInfoCount )
  506. {
  507. // Get System CodePage
  508. uCodePage = GetACP();
  509. for (i = 0; i < g_cMimeCPInfoCount ; i++)
  510. {
  511. if (uiCodePage == g_pMimeCPInfo[i].uiCodePage)
  512. {
  513. // convert WideString to MultiByteString
  514. if (lpszString)
  515. {
  516. if (bWebCharset)
  517. cchXlated = WideCharToMultiByte(uCodePage, 0, g_pMimeCPInfo[i].wszWebCharset, -1, lpszString, nSize, NULL, NULL);
  518. else
  519. cchXlated = WideCharToMultiByte(uCodePage, 0, g_pMimeCPInfo[i].wszDescription, -1, lpszString, nSize, NULL, NULL);
  520. }
  521. if ( pnIdm )
  522. *pnIdm = i+ID_LANG_FIRST;
  523. break ;
  524. }
  525. }
  526. }
  527. return ;
  528. }
  529. int SetMimeLanguageCheckMark(UINT uiCodePage, int index)
  530. {
  531. ULONG i;
  532. if((g_pMimeCPInfo[index].uiCodePage == CP_AUTO) && g_cpcache.fAutoSelectInstalled && DwGetOption(OPT_INCOMDEFENCODE))
  533. return (0);
  534. else if((g_pMimeCPInfo[index].uiCodePage == CP_AUTO) && g_cpcache.fAutoSelectChecked && g_cpcache.fAutoSelectInstalled)
  535. return (OLECMDF_LATCHED | OLECMDF_ENABLED);
  536. UINT iStart = g_cpcache.fAutoSelectInstalled ? 1 : 0;
  537. if (1 < g_cMimeCPInfoCount)
  538. {
  539. if(uiCodePage == g_pMimeCPInfo[index].uiCodePage)
  540. return (OLECMDF_NINCHED | OLECMDF_ENABLED);
  541. else
  542. return OLECMDF_ENABLED;
  543. }
  544. return FALSE;
  545. }
  546. INT GetFontSize(void)
  547. {
  548. DWORD cb, iFontSize = 0;
  549. cb = sizeof(iFontSize);
  550. AthUserGetValue(NULL, c_szRegValIMNFontSize, NULL, (LPBYTE)&iFontSize, &cb);
  551. if(iFontSize < 1 || iFontSize > 7)
  552. iFontSize = 2;
  553. return((INT)iFontSize);
  554. }
  555. //
  556. // GetICP() - Gets the system's *internet* codepage from the ANSI codepage
  557. //
  558. UINT GetICP(UINT acp)
  559. {
  560. HCHARSET hCharset = NULL;
  561. UINT icp = NULL;
  562. CODEPAGEINFO rCodePage;
  563. INETCSETINFO CsetInfo;
  564. HRESULT hr;
  565. ULONG i;
  566. if(!acp)
  567. acp = GetACP();
  568. icp = acp;
  569. // Get the codepage info for acp
  570. IF_FAILEXIT(hr = MimeOleGetCodePageInfo(acp, &rCodePage));
  571. // Use the body (internet) charset description to get the codepage id for
  572. // the body charset
  573. IF_FAILEXIT(hr = MimeOleFindCharset(rCodePage.szBodyCset, &hCharset));
  574. IF_FAILEXIT(hr = MimeOleGetCharsetInfo(hCharset,&CsetInfo));
  575. // Now, we need to know if MLANG understands this CP
  576. if ( g_pMimeCPInfo == NULL)
  577. _InitMultiLanguage();
  578. if ( g_cMimeCPInfoCount )
  579. {
  580. for (i = 0; i < g_cMimeCPInfoCount ; i++)
  581. {
  582. if (CsetInfo.cpiInternet == g_pMimeCPInfo[i].uiCodePage)
  583. {
  584. icp = CsetInfo.cpiInternet;
  585. break ;
  586. }
  587. }
  588. }
  589. exit:
  590. return icp;
  591. }
  592. void ReadSendMailDefaultCharset(void)
  593. {
  594. // Locals
  595. HKEY hTopkey;
  596. DWORD cb;
  597. CODEPAGEID cpiCodePage;
  598. // only read once, skip if it is defined
  599. if (g_hDefaultCharsetForMail == NULL)
  600. {
  601. cb = sizeof(cpiCodePage);
  602. if (ERROR_SUCCESS == AthUserGetValue(c_szRegPathMail, c_szDefaultCodePage, NULL, (LPBYTE)&cpiCodePage, &cb))
  603. {
  604. if (cpiCodePage == 50222 || cpiCodePage == 50221)
  605. g_hDefaultCharsetForMail = GetJP_ISOControlCharset();
  606. else
  607. g_hDefaultCharsetForMail = GetMimeCharsetFromCodePage(cpiCodePage);
  608. }
  609. }
  610. if (g_hDefaultCharsetForMail == NULL)
  611. {
  612. if(FAILED(HGetDefaultCharset(&g_hDefaultCharsetForMail)))
  613. g_hDefaultCharsetForMail = GetMimeCharsetFromCodePage(GetICP(NULL));
  614. }
  615. return;
  616. }
  617. void WriteSendMailDefaultCharset(void)
  618. {
  619. // Locals
  620. CODEPAGEID uiCodePage;
  621. INETCSETINFO CsetInfo ;
  622. // get CodePage from HCHARSET
  623. if (g_hDefaultCharsetForMail)
  624. {
  625. MimeOleGetCharsetInfo(g_hDefaultCharsetForMail,&CsetInfo);
  626. uiCodePage = CsetInfo.cpiInternet ;
  627. AthUserSetValue(c_szRegPathMail, c_szDefaultCodePage, REG_DWORD, (LPBYTE)&uiCodePage, sizeof(uiCodePage));
  628. }
  629. return;
  630. }
  631. INT_PTR CALLBACK CharsetChgDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  632. {
  633. if (msg == WM_COMMAND)
  634. {
  635. int id = GET_WM_COMMAND_ID(wParam, lParam);
  636. if (id == IDOK || id == IDCANCEL ||
  637. id == idcSendAsUnicode )
  638. {
  639. EndDialog(hwndDlg, id);
  640. return TRUE;
  641. }
  642. }
  643. else if (msg == WM_INITDIALOG )
  644. {
  645. CenterDialog(hwndDlg);
  646. }
  647. return FALSE;
  648. }
  649. static const HELPMAP g_rgCtxMapCharSetMap[] =
  650. {
  651. {idcStatic1, 35545},
  652. {idcLangCheck, 35540},
  653. {0, 0}
  654. };
  655. INT_PTR CALLBACK ReadCharsetDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  656. {
  657. CODEPAGEID cpiWindows;
  658. CODEPAGEID cpiInternet;
  659. TCHAR szCodePage[MAX_PATH];
  660. TCHAR szBuffer[MIMEINFO_NAME_MAX] = "";
  661. int Idm;
  662. switch (msg)
  663. {
  664. case WM_INITDIALOG:
  665. {
  666. // Open Trident\International
  667. DWORD cb = sizeof(cpiWindows);
  668. if (ERROR_SUCCESS != SHGetValue(MU_GetCurrentUserHKey(), c_szRegInternational, c_szDefaultCodePage, NULL, (LPBYTE)&cpiWindows, &cb))
  669. cpiWindows = GetACP();
  670. // Open the CodePage Key
  671. wnsprintf(szCodePage, ARRAYSIZE(szCodePage), TEXT("%s\\%d"), c_szRegInternational, cpiWindows);
  672. cb = sizeof(cpiInternet);
  673. if (ERROR_SUCCESS != SHGetValue(MU_GetCurrentUserHKey(), szCodePage, c_szDefaultEncoding, NULL, (LPBYTE)&cpiInternet, &cb))
  674. cpiInternet = GetICP(cpiWindows);
  675. // Get information about current default charset
  676. _GetMimeCharsetLangString(FALSE, GetMapCP(cpiInternet, TRUE), &Idm, szBuffer, MIMEINFO_NAME_MAX - 1);
  677. // Set the String
  678. SetWindowText(GetDlgItem(hwndDlg, idcStatic1), szBuffer);
  679. // Set the Default
  680. CheckDlgButton(hwndDlg, idcLangCheck, DwGetOption(OPT_INCOMDEFENCODE) ? BST_CHECKED:BST_UNCHECKED);
  681. break ;
  682. }
  683. case WM_COMMAND:
  684. {
  685. int id = GET_WM_COMMAND_ID(wParam, lParam);
  686. if (id == IDCANCEL || id == IDOK )
  687. {
  688. if(id == IDOK)
  689. {
  690. SetDwOption(OPT_INCOMDEFENCODE, IsDlgButtonChecked(hwndDlg, idcLangCheck), NULL, 0);
  691. #if 0
  692. // hack: we should call these only if OpenFontsDialog tells us user has changed the font.
  693. g_lpIFontCache->OnOptionChange();
  694. SendTridentOptionsChange();
  695. // Re-Read Default Character Set
  696. SetDefaultCharset(NULL);
  697. // Reset g_uiCodePage
  698. DWORD dwVal = 0;
  699. DWORD dwType = 0;
  700. DWORD cb = sizeof(dwVal);
  701. if (ERROR_SUCCESS == SHGetValue(MU_GetCurrentUserHKey(), c_szRegInternational, REGSTR_VAL_DEFAULT_CODEPAGE, &dwType, &dwVal, &cb))
  702. g_uiCodePage = (UINT)dwVal;
  703. #endif // 0
  704. }
  705. EndDialog(hwndDlg, id);
  706. return TRUE;
  707. }
  708. break ;
  709. }
  710. case WM_HELP:
  711. case WM_CONTEXTMENU:
  712. return OnContextHelp(hwndDlg, msg, wParam, lParam, g_rgCtxMapCharSetMap);
  713. default:
  714. break ;
  715. }
  716. return FALSE;
  717. }
  718. BOOL CheckIntlCharsetMap(HCHARSET hCharset, DWORD *pdwCodePage)
  719. {
  720. INETCSETINFO CsetInfo ;
  721. LPSTR lpCharsetName, lpStr;
  722. ULONG i;
  723. UINT uiCodePage ;
  724. if ( hCharset == NULL )
  725. return FALSE ;
  726. if (!pdwCodePage)
  727. return FALSE ;
  728. else
  729. *pdwCodePage = 0 ;
  730. // get Code page from HCHARSET
  731. MimeOleGetCharsetInfo(hCharset,&CsetInfo);
  732. *pdwCodePage = GetMapCP(CsetInfo.cpiInternet, TRUE); // This func always called for Read note (?!)
  733. return(*pdwCodePage != CsetInfo.cpiInternet);
  734. }
  735. UINT CustomGetCPFromCharset(HCHARSET hCharset, BOOL bReadNote)
  736. {
  737. INETCSETINFO CsetInfo = {0};
  738. UINT uiCodePage = 0 ;
  739. // get CodePage from HCHARSET
  740. MimeOleGetCharsetInfo(hCharset,&CsetInfo);
  741. uiCodePage = GetMapCP(CsetInfo.cpiInternet, bReadNote);
  742. // Bug #51636
  743. // Check that code page supported by OE
  744. if(GetMimeCharsetFromCodePage(uiCodePage) == NULL)
  745. {
  746. HCHARSET hChar = NULL;
  747. if(bReadNote)
  748. {
  749. if(SUCCEEDED(HGetDefaultCharset(&hChar)))
  750. {
  751. if(FAILED(MimeOleGetCharsetInfo(hChar, &CsetInfo)))
  752. return(0);
  753. }
  754. else
  755. return(0);
  756. }
  757. else
  758. {
  759. if(FAILED(MimeOleGetCharsetInfo(g_hDefaultCharsetForMail, &CsetInfo)))
  760. return(0);
  761. }
  762. return(GetMapCP(CsetInfo.cpiInternet, bReadNote));
  763. }
  764. return(uiCodePage);
  765. }
  766. BOOL IntlCharsetMapDialogBox(HWND hwndDlg)
  767. {
  768. DialogBox(g_hLocRes, MAKEINTRESOURCE(iddIntlSetting), hwndDlg, ReadCharsetDlgProc) ;
  769. return TRUE ;
  770. }
  771. int IntlCharsetConflictDialogBox(void)
  772. {
  773. return (int) DialogBox(g_hLocRes, MAKEINTRESOURCE(iddCharsetConflict), g_hwndInit, CharsetChgDlgProc);
  774. }
  775. int GetIntlCharsetLanguageCount(void)
  776. {
  777. if ( g_pMimeCPInfo == NULL)
  778. _InitMultiLanguage();
  779. return g_cMimeCPInfoCount ;
  780. }
  781. HCHARSET GetListViewCharset()
  782. {
  783. HCHARSET hCharset;
  784. if(g_uiCodePage == GetACP() || 0 == g_uiCodePage)
  785. hCharset = NULL;
  786. else
  787. hCharset = GetMimeCharsetFromCodePage(g_uiCodePage);
  788. return hCharset;
  789. }
  790. // =================================================================================
  791. // SetListViewFont
  792. // =================================================================================
  793. VOID SetListViewFont (HWND hwndList, HCHARSET hCharset, BOOL fUpdate)
  794. {
  795. // Locals
  796. HFONT hFont;
  797. // Check Params
  798. Assert (IsWindow (hwndList));
  799. hFont = HGetCharSetFont(FNT_SYS_ICON,hCharset);
  800. // If we got a font, set the list view
  801. if (hFont)
  802. {
  803. // Set the list view font - Dont redraw quite yet
  804. SendMessage (hwndList, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(fUpdate, 0));
  805. // Try to reset header back to system icon font...
  806. // Get header
  807. HWND hwndHeader = GetWindow (hwndList, GW_CHILD);
  808. // Update Header
  809. hFont = HGetSystemFont(FNT_SYS_ICON);
  810. // If font
  811. if (hFont && hwndHeader)
  812. SendMessage (hwndHeader, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(fUpdate, 0));
  813. // Refresh
  814. if (fUpdate)
  815. {
  816. InvalidateRect (hwndList, NULL, TRUE);
  817. InvalidateRect (GetWindow(hwndList, GW_CHILD), NULL, TRUE);
  818. }
  819. }
  820. }
  821. // =================================================================================
  822. // HGetSystemFont
  823. // =================================================================================
  824. HFONT HGetSystemFont(FNTSYSTYPE fnttype)
  825. {
  826. HFONT hFont;
  827. Assert (g_lpIFontCache);
  828. if (g_lpIFontCache)
  829. g_lpIFontCache->GetFont(fnttype, 0, &hFont);
  830. else
  831. hFont = NULL;
  832. return hFont;
  833. }
  834. // =================================================================================
  835. // HGetCharSetFont
  836. // =================================================================================
  837. HFONT HGetCharSetFont(FNTSYSTYPE fnttype, HCHARSET hCharset)
  838. {
  839. HFONT hFont;
  840. Assert (g_lpIFontCache);
  841. if (g_lpIFontCache)
  842. g_lpIFontCache->GetFont(fnttype, hCharset, &hFont);
  843. else
  844. hFont = NULL;
  845. return hFont;
  846. }
  847. // ******************************************************
  848. // HrGetComposeFontString
  849. //
  850. // Purpose: builds the compose font string based on user settings ready for execing to Trident
  851. //
  852. // the format of the string is:
  853. //
  854. // "[Bold],[Italic],[Underline],[size],[FGRed.FGGreen.FGBlue],[BGRed.BGGreen.BGBlue],[FontFace]"
  855. //
  856. // Bold, Italic, Underline are either 0/1, indicating on or off. If none specified, 0 assumed.
  857. // Size is a number between 1 and 7. If none specified, 3 assumed
  858. // [FG|BG][Red|Green|Blue] are numbers between 0 and 255. For FG, if none specified black assumed,
  859. // for BG if none specified then undefined assumed.
  860. // Font Face is a valid font name string
  861. // For example an underline, blue text color, arial setting would be:
  862. //
  863. // ,,1,,0.0.255,,Arial
  864. //
  865. // and a bold, 5 size, black, comic sans MS would be
  866. //
  867. // 1,0,0,5,,,Comic Sans MS
  868. // ******************************************************
  869. static const TCHAR c_szOn[] = "1,",
  870. c_szOff[] = "0,";
  871. HRESULT HrGetComposeFontString(LPSTR rgchFont, DWORD cchFont, BOOL fMail)
  872. {
  873. DWORD dw = 0,
  874. dwSize = 2;
  875. TCHAR szFontFace[LF_FACESIZE+1];
  876. TCHAR szTmp[50];
  877. if (rgchFont==NULL)
  878. return E_INVALIDARG;
  879. // "[Bold],[Italic],[Underline],[size],[FGRed.FGGreen.FGBlue],[BGRed.BGGreen.BGBlue],[FontFace]"
  880. *szFontFace = 0;
  881. *rgchFont=0;
  882. // bold
  883. StrCatBuff(rgchFont, DwGetOption(fMail ? OPT_MAIL_FONTBOLD : OPT_NEWS_FONTBOLD) ? c_szOn : c_szOff, cchFont);
  884. // italic
  885. StrCatBuff(rgchFont, DwGetOption(fMail ? OPT_MAIL_FONTITALIC : OPT_NEWS_FONTITALIC) ? c_szOn : c_szOff, cchFont);
  886. // underline
  887. StrCatBuff(rgchFont, DwGetOption(fMail ? OPT_MAIL_FONTUNDERLINE : OPT_NEWS_FONTUNDERLINE) ? c_szOn : c_szOff, cchFont);
  888. dw = DwGetOption(fMail ? OPT_MAIL_FONTSIZE : OPT_NEWS_FONTSIZE);
  889. // map points to HTML size
  890. dwSize = PointSizeToHTMLSize(dw);
  891. // font size
  892. wnsprintf(szTmp, ARRAYSIZE(szTmp), "%d,", dwSize);
  893. StrCatBuff(rgchFont, szTmp, cchFont);
  894. // font foregroundcolor
  895. if(fMail)
  896. dw = DwGetOption(OPT_MAIL_FONTCOLOR);
  897. else
  898. dw = DwGetOption(OPT_NEWS_FONTCOLOR);
  899. // write out RGB string
  900. wnsprintf(szTmp, ARRAYSIZE(szTmp), "%d.%d.%d,", GetRValue(dw), GetGValue(dw), GetBValue(dw));
  901. StrCatBuff(rgchFont, szTmp, cchFont);
  902. // default background color
  903. StrCatBuff(rgchFont, ",", cchFont);
  904. GetOption(fMail ? OPT_MAIL_FONTFACE : OPT_NEWS_FONTFACE, szFontFace, LF_FACESIZE);
  905. if(*szFontFace == 0)
  906. LoadString(g_hLocRes, idsComposeFontFace, szFontFace, LF_FACESIZE);
  907. StrCatBuff(rgchFont, szFontFace, cchFont);
  908. return S_OK;
  909. }
  910. INT PointSizeToHTMLSize(INT iPointSize)
  911. {
  912. INT iHTMLSize;
  913. // 1 ----- 8
  914. // 2 ----- 10
  915. // 3 ----- 12
  916. // 4 ----- 14
  917. // 5 ----- 18
  918. // 6 ----- 24
  919. // 7 ----- 36
  920. if(iPointSize>=8 && iPointSize<9)
  921. iHTMLSize = 1;
  922. else if(iPointSize>=9 && iPointSize<12)
  923. iHTMLSize = 2;
  924. else if(iPointSize>=12 && iPointSize<14)
  925. iHTMLSize = 3;
  926. else if(iPointSize>=14 && iPointSize<18)
  927. iHTMLSize = 4;
  928. else if(iPointSize>=18 && iPointSize<24)
  929. iHTMLSize = 5;
  930. else if(iPointSize>=24 && iPointSize<36)
  931. iHTMLSize = 6;
  932. else if(iPointSize>=36)
  933. iHTMLSize = 7;
  934. else
  935. iHTMLSize = DEFAULT_FONTSIZE;
  936. return iHTMLSize;
  937. }
  938. INT HTMLSizeToPointSize(INT iHTMLSize)
  939. {
  940. INT iPointSize;
  941. // 1 ----- 8
  942. // 2 ----- 10
  943. // 3 ----- 12
  944. // 4 ----- 14
  945. // 5 ----- 18
  946. // 6 ----- 24
  947. // 7 ----- 36
  948. switch (iHTMLSize)
  949. {
  950. case 1:
  951. iPointSize = 8;
  952. break;
  953. case 2:
  954. iPointSize = 10;
  955. break;
  956. case 3:
  957. iPointSize = 12;
  958. break;
  959. case 4:
  960. iPointSize = 14;
  961. break;
  962. case 5:
  963. iPointSize = 18;
  964. break;
  965. case 6:
  966. iPointSize = 24;
  967. break;
  968. case 7:
  969. iPointSize = 36;
  970. break;
  971. default:
  972. iPointSize = 10;
  973. }
  974. return iPointSize;
  975. }
  976. HRESULT HrGetStringRBG(INT rgb, LPWSTR pwszColor)
  977. {
  978. HRESULT hr = S_OK;
  979. INT i;
  980. DWORD crTemp;
  981. if(NULL == pwszColor)
  982. return E_INVALIDARG;
  983. rgb = ((rgb & 0x00ff0000) >> 16 ) | (rgb & 0x0000ff00) | ((rgb & 0x000000ff) << 16);
  984. for(i = 0; i < 6; i++)
  985. {
  986. crTemp = (rgb & (0x00f00000 >> (4*i))) >> (4*(5-i));
  987. pwszColor[i] = (WCHAR)((crTemp < 10)? (crTemp+L'0') : (crTemp+ L'a' - 10));
  988. }
  989. pwszColor[6] = L'\0';
  990. return hr;
  991. }
  992. HRESULT HrGetRBGFromString(INT* pRBG, LPWSTR pwszColor)
  993. {
  994. HRESULT hr = S_OK;
  995. INT i, rbg = 0, len, n;
  996. WCHAR ch;
  997. if(NULL == pRBG)
  998. return E_INVALIDARG;
  999. *pRBG = 0;
  1000. len = lstrlenW(pwszColor);
  1001. for(i=0; i<len; i++)
  1002. {
  1003. n = -1;
  1004. ch = pwszColor[i];
  1005. if(ch >= L'0' && ch <= L'9')
  1006. n = ch - L'0';
  1007. else if(ch >= L'a' && ch <= L'f')
  1008. n = ch - L'a' + 10;
  1009. else if(ch >= L'A' && ch <= L'F')
  1010. n = ch - L'A' + 10;
  1011. if(n < 0)
  1012. continue;
  1013. rbg = rbg*16 + n;
  1014. }
  1015. *pRBG = rbg;
  1016. return hr;
  1017. }
  1018. // ***************************************************
  1019. HRESULT FontToCharformat(HFONT hFont, CHARFORMAT *pcf)
  1020. {
  1021. DWORD dwOldEffects;
  1022. HDC hdc;
  1023. LOGFONT lf;
  1024. INT yPerInch;
  1025. if (FAILED(GetObject(hFont, sizeof(lf), &lf)))
  1026. return E_FAIL;
  1027. hdc=GetDC(NULL);
  1028. yPerInch=GetDeviceCaps(hdc, LOGPIXELSY);
  1029. ReleaseDC(NULL, hdc);
  1030. // Set Struct Size
  1031. ZeroMemory(pcf, sizeof (CHARFORMAT));
  1032. pcf->cbSize = sizeof (CHARFORMAT);
  1033. // Set mask
  1034. pcf->dwMask = CFM_CHARSET | CFM_BOLD | CFM_FACE | CFM_ITALIC |
  1035. CFM_SIZE | CFM_STRIKEOUT | CFM_UNDERLINE | CFM_COLOR;
  1036. // Clear all the bits we are about to set. We restore any bits we can not get from the LOGFONT using dwOldEffects.
  1037. pcf->dwEffects = CFE_AUTOCOLOR;
  1038. pcf->dwEffects |= (lf.lfWeight >= 700) ? CFE_BOLD : 0;
  1039. pcf->dwEffects |= (lf.lfItalic) ? CFE_ITALIC : 0;
  1040. pcf->dwEffects |= (lf.lfStrikeOut) ? CFE_STRIKEOUT : 0;
  1041. pcf->dwEffects |= (lf.lfUnderline) ? CFE_UNDERLINE : 0;
  1042. pcf->yHeight = -(int)((1440*lf.lfHeight)/yPerInch); // I think this is he conversion?
  1043. pcf->crTextColor = 0; // use autocolor
  1044. pcf->bCharSet = lf.lfCharSet;
  1045. pcf->bPitchAndFamily = lf.lfPitchAndFamily;
  1046. StrCpyN(pcf->szFaceName, lf.lfFaceName, LF_FACESIZE - 1);
  1047. return S_OK;
  1048. }
  1049. static const HELPMAP g_rgCtxMapSendCharSetMap[] =
  1050. {
  1051. {idcLangCombo, 50910},
  1052. {IDC_RTL_MSG_DIR_CHECK, 50912},
  1053. {IDC_ENGLISH_HDR_CHECK, 50915},
  1054. {0, 0}
  1055. };
  1056. INT_PTR CALLBACK SetSendCharsetDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  1057. {
  1058. HWND hWndCombo;
  1059. ULONG i ;
  1060. ULONG cchXlated ;
  1061. UINT uiCodePage;
  1062. CHAR szBuffer[MIMEINFO_NAME_MAX];
  1063. UINT uiACP = GetACP();
  1064. INETCSETINFO CsetInfo ;
  1065. int index = 0;
  1066. int SelIndex = 0;
  1067. hWndCombo = GetDlgItem(hwndDlg, idcLangCombo);
  1068. switch (msg)
  1069. {
  1070. case WM_INITDIALOG:
  1071. {
  1072. CenterDialog(hwndDlg);
  1073. // Init global CPs structire, if it was not inited yet
  1074. if ( g_pMimeCPInfo == NULL)
  1075. _InitMultiLanguage();
  1076. // Get information about current default charset
  1077. MimeOleGetCharsetInfo(g_hDefaultCharsetForMail,&CsetInfo);
  1078. uiCodePage = CsetInfo.cpiInternet ;
  1079. // Fill combo box with available charsets for Send
  1080. for (i = 0; i < g_cMimeCPInfoCount ; i++)
  1081. {
  1082. if(!fCheckEncodeMenu(g_pMimeCPInfo[i].uiCodePage, FALSE))
  1083. continue ;
  1084. cchXlated = WideCharToMultiByte(uiACP,
  1085. 0,
  1086. g_pMimeCPInfo[i].wszDescription,
  1087. -1,
  1088. szBuffer,
  1089. ARRAYSIZE(szBuffer),
  1090. NULL,
  1091. NULL);
  1092. szBuffer[ARRAYSIZE(szBuffer) - 1] = '\0'; //better safe than not null-terminated
  1093. index = (int) SendMessage(hWndCombo, CB_ADDSTRING, 0, ((LPARAM) szBuffer));
  1094. if(index != CB_ERR)
  1095. SendMessage(hWndCombo, CB_SETITEMDATA, index, ((LPARAM) (g_pMimeCPInfo[i].uiCodePage)));
  1096. if(g_pMimeCPInfo[i].uiCodePage == uiCodePage)
  1097. {
  1098. EnableWindow(GetDlgItem(hwndDlg, IDC_RTL_MSG_DIR_CHECK),
  1099. ((g_pMimeCPInfo[i].uiFamilyCodePage == 1255) ||
  1100. (g_pMimeCPInfo[i].uiFamilyCodePage == 1256) ||
  1101. (g_pMimeCPInfo[i].uiFamilyCodePage == 1200)));
  1102. }
  1103. }
  1104. //Set current selection to default charset, we can't detect this in the above
  1105. //loop because the combobox sorting may change the index
  1106. for (i = 0; i < g_cMimeCPInfoCount ; i++)
  1107. {
  1108. if(uiCodePage == (UINT)SendMessage(hWndCombo, CB_GETITEMDATA, i, NULL))
  1109. {
  1110. SelIndex = i;
  1111. break;
  1112. }
  1113. }
  1114. SendMessage(hWndCombo, CB_SETCURSEL, SelIndex, 0L);
  1115. CheckDlgButton(hwndDlg, IDC_ENGLISH_HDR_CHECK, DwGetOption(OPT_HARDCODEDHDRS) ? BST_CHECKED:BST_UNCHECKED);
  1116. CheckDlgButton(hwndDlg, IDC_RTL_MSG_DIR_CHECK, DwGetOption(OPT_RTL_MSG_DIR) ? BST_CHECKED:BST_UNCHECKED);
  1117. break ;
  1118. }
  1119. case WM_COMMAND:
  1120. {
  1121. int id = GET_WM_COMMAND_ID(wParam, lParam);
  1122. HCHARSET hCharset = NULL ;
  1123. if ((id == idcLangCombo) && (GET_WM_COMMAND_CMD(wParam,lParam) == CBN_SELCHANGE))
  1124. {
  1125. index = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0L);
  1126. if(index != CB_ERR)
  1127. {
  1128. uiCodePage = (UINT) SendMessage(hWndCombo, CB_GETITEMDATA, index, 0);
  1129. if(((int) uiCodePage) != CB_ERR)
  1130. {
  1131. for (i = 0; i < g_cMimeCPInfoCount ; i++)
  1132. {
  1133. if(g_pMimeCPInfo[i].uiCodePage == uiCodePage)
  1134. {
  1135. EnableWindow(GetDlgItem(hwndDlg, IDC_RTL_MSG_DIR_CHECK),
  1136. ((g_pMimeCPInfo[i].uiFamilyCodePage == 1255) ||
  1137. (g_pMimeCPInfo[i].uiFamilyCodePage == 1256) ||
  1138. (g_pMimeCPInfo[i].uiFamilyCodePage == 1200)));
  1139. }
  1140. }
  1141. }
  1142. }
  1143. }
  1144. else if (id == IDCANCEL || id == IDOK )
  1145. {
  1146. if (id == IDOK )
  1147. {
  1148. index = (int) SendMessage(hWndCombo, CB_GETCURSEL, 0, 0L);
  1149. if(index != CB_ERR)
  1150. {
  1151. uiCodePage = (UINT) SendMessage(hWndCombo, CB_GETITEMDATA, index, 0);
  1152. if(((int) uiCodePage) != CB_ERR)
  1153. {
  1154. AthUserSetValue(c_szRegPathMail, c_szDefaultCodePage,
  1155. REG_DWORD, (LPBYTE)&uiCodePage, sizeof(uiCodePage));
  1156. g_hDefaultCharsetForMail = GetMimeCharsetFromCodePage(uiCodePage );
  1157. WriteSendMailDefaultCharset();
  1158. }
  1159. }
  1160. SetDwOption(OPT_HARDCODEDHDRS, IsDlgButtonChecked(hwndDlg, IDC_ENGLISH_HDR_CHECK), NULL, 0);
  1161. SetDwOption(OPT_RTL_MSG_DIR, (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_RTL_MSG_DIR_CHECK)) && IsDlgButtonChecked(hwndDlg, IDC_RTL_MSG_DIR_CHECK)), NULL, 0);
  1162. }
  1163. EndDialog(hwndDlg, id);
  1164. return TRUE;
  1165. }
  1166. break ;
  1167. }
  1168. case WM_HELP:
  1169. case WM_CONTEXTMENU:
  1170. return OnContextHelp(hwndDlg, msg, wParam, lParam, g_rgCtxMapSendCharSetMap);
  1171. default:
  1172. break ;
  1173. }
  1174. return FALSE;
  1175. }
  1176. BOOL SetSendCharSetDlg(HWND hwndDlg)
  1177. {
  1178. DialogBox(g_hLocRes, MAKEINTRESOURCE(iddSendIntlSetting), hwndDlg, SetSendCharsetDlgProc) ;
  1179. return TRUE ;
  1180. }