|
|
//
// FONTS.C - Selecting character set default fonts dialog
//
// Copyright(c) Microsoft Corp., 1996 All rights reserved.
//
// History:
// 7/11/96 t-gpease trashed old International subdialog to create the new
// improved codepage compatiable Fonts dialog.
// WAS
//
// INTL.C - international dialog proc for inetcpl applet.
//
// Copyright(c) Microsoft Corp., 1996 All rights reserved.
//
// HISTORY:
// 2/2/96 yutakan created.
// 2/6/96 yutakan ported most of functions from IE2.0i.
// 8/20/98 weiwu add script base font dialog proc (UNICODE version only)
#include "inetcplp.h"
#include <mlang.h>
#include <mluisupp.h>
#ifdef UNIX
#include <mainwin.h>
#endif /*UNIX */
// Used for window property to remember the font created
static const TCHAR c_szPropDlgFont[] = TEXT("DefaultDlgFont");
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#ifdef UNICODE
PMIMECPINFO g_pCPInfo = NULL; #else
PMIMECPINFO g_pCPInfoW = NULL;
typedef struct tagMIMECPINFOA { DWORD dwFlags; UINT uiCodePage; UINT uiFamilyCodePage; CHAR wszDescription[MAX_MIMECP_NAME]; // NOTE:
CHAR wszWebCharset[MAX_MIMECSET_NAME]; // To make it simple, it has wsz
CHAR wszHeaderCharset[MAX_MIMECSET_NAME]; // prefix even though it's CHAR. So,
CHAR wszBodyCharset[MAX_MIMECSET_NAME]; // we don't need to put #ifdef UNICODE
CHAR wszFixedWidthFont[MAX_MIMEFACE_NAME]; // in below code anymore except
CHAR wszProportionalFont[MAX_MIMEFACE_NAME]; // conversion time.
BYTE bGDICharset; } MIMECPINFOA, *PMIMECPINFOA;
PMIMECPINFOA g_pCPInfo = NULL; #endif
ULONG g_cCPInfo = 0; ULONG g_cSidInfo = 0; IMLangFontLink2 *g_pMLFlnk2 = NULL;
typedef HRESULT (* PCOINIT) (LPVOID); typedef VOID (* PCOUNINIT) (VOID); typedef VOID (* PCOMEMFREE) (LPVOID); typedef HRESULT (* PCOCREINST) (REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID * );
extern HMODULE hOLE32; extern PCOINIT pCoInitialize; extern PCOUNINIT pCoUninitialize; extern PCOMEMFREE pCoTaskMemFree; extern PCOCREINST pCoCreateInstance;
BOOL _StartOLE32();
#define IsVerticalFont(p) (*(p) == '@')
typedef struct { TCHAR szPropFont[MAX_MIMEFACE_NAME]; TCHAR szFixedFont[MAX_MIMEFACE_NAME]; TCHAR szFriendlyName[MAX_MIMECP_NAME]; TCHAR szMIMEFont[MAX_MIMECP_NAME]; DWORD dwFontSize; } CODEPAGEDATA;
typedef struct { HWND hDlg; HWND hwndPropCB; HWND hwndFixedCB; HWND hwndSizeCB; HWND hwndMIMECB; HWND hwndNamesLB;
DWORD dwDefaultCodePage;
BOOL bChanged;
CODEPAGEDATA *page;
LPCTSTR lpszKeyPath;
} FONTSDATA, *LPFONTSDATA;
typedef struct { HWND hDlg; HWND hwndPropLB; HWND hwndFixedLB; HWND hwndNamesCB;
SCRIPT_ID sidDefault;
BOOL bChanged;
PSCRIPTINFO pSidInfo;
LPCTSTR lpszKeyPath;
} FONTSCRIPTDATA, *LPFONTSCRIPTDATA;
const struct { SCRIPT_ID Sid; BYTE nCharSet; UINT uiCp; } g_CharSetTransTable[] = { sidAsciiLatin, ANSI_CHARSET, 1252, sidLatin, ANSI_CHARSET, 1252, sidCyrillic, RUSSIAN_CHARSET, 1251, sidGreek, GREEK_CHARSET, 1253, sidHebrew, HEBREW_CHARSET, 1255, sidArabic, ARABIC_CHARSET, 1256, sidThai, THAI_CHARSET, 874, sidKana, SHIFTJIS_CHARSET, 932, sidHan, GB2312_CHARSET, 936, sidBopomofo, CHINESEBIG5_CHARSET,950, sidHangul, HANGEUL_CHARSET, 949, };
//
// Map script ID to charset
// We should use MLang service when it is available
//
BYTE CharSetFromSid(SCRIPT_ID Sid) { for (int i=0; i<ARRAYSIZE(g_CharSetTransTable); i++) { if (Sid == g_CharSetTransTable[i].Sid) return g_CharSetTransTable[i].nCharSet; }
return DEFAULT_CHARSET; }
// SHLWAPI StrCmp/StrCmpI doesn't work.
// Make this simple function to tell if string is equal in character value
BOOL IsStringEqual(LPCTSTR lpString1, LPCTSTR lpString2) { if (lstrlen(lpString1) != lstrlen(lpString2)) return FALSE;
while(*lpString1 && *lpString2) { if (*lpString1 != *lpString2) { return FALSE; } lpString1++; lpString2++; }
return TRUE; }
//
// Initialize script table with resource string
//
BOOL InitScriptTable(LPFONTSCRIPTDATA pFnt) {
HRESULT hr; BOOL bRet = FALSE; IMultiLanguage2 * pML2;
ASSERT(IS_VALID_CODE_PTR(pCoInitialize, PCOINIT)); ASSERT(IS_VALID_CODE_PTR(pCoUninitialize, PCOUNINIT)); ASSERT(IS_VALID_CODE_PTR(pCoTaskMemFree, PCOMEMFREE)); ASSERT(IS_VALID_CODE_PTR(pCoCreateInstance, PCOCREINST));
hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (LPVOID *) &pML2);
if (SUCCEEDED(hr)) { hr = pML2->QueryInterface(IID_IMLangFontLink2, (LPVOID *) &g_pMLFlnk2);
if (SUCCEEDED(hr)) { IEnumScript *pEnumScript;
if (SUCCEEDED(pML2->EnumScripts(SCRIPTCONTF_SCRIPT_USER, INETCPL_GetUILanguage(), &pEnumScript))) { UINT cNum = 0;
pML2->GetNumberOfScripts(&cNum);
pFnt->pSidInfo = (PSCRIPTINFO)LocalAlloc(LPTR, sizeof(SCRIPTINFO) * cNum); if (NULL != pFnt->pSidInfo) { hr = pEnumScript->Next(cNum, pFnt->pSidInfo, &g_cSidInfo); if (SUCCEEDED(hr)) { bRet = TRUE; } else { LocalFree(pFnt->pSidInfo); pFnt->pSidInfo = NULL; } } pEnumScript->Release(); } }
if (pML2) pML2->Release(); }
return bRet; }
//
// DrawSampleString()
//
// Draw the sample string with current font
//
void DrawSampleString(LPFONTSDATA pFnt, int idSample, LPCTSTR lpFace, SCRIPT_ID ScriptId) { HDC hDC; HFONT hFont, hTemp; LOGFONT lf = {0}; DWORD rgbText, rgbBack; RECT rc; SIZE TextExtent; TEXTMETRIC tm; int len, x, y; TCHAR szFontSample[1024];
if (!lpFace) return;
MLLoadString(IDS_FONT_SAMPLE_DEFAULT+ScriptId, szFontSample, ARRAYSIZE(szFontSample));
GetWindowRect(GetDlgItem(pFnt->hDlg, idSample), &rc); // Use MapWindowPoints() as it works for mirrored windows as well.
MapWindowRect(NULL, pFnt->hDlg, &rc); // ScreenToClient(pFnt->hDlg, (LPPOINT)&rc.left);
// ScreenToClient(pFnt->hDlg, (LPPOINT)&rc.right);
hDC = GetDC(pFnt->hDlg);
rgbBack = SetBkColor(hDC, GetSysColor(COLOR_3DFACE)); rgbText = GetSysColor(COLOR_WINDOWTEXT); rgbText = SetTextColor(hDC, rgbText);
hFont = GetWindowFont(pFnt->hDlg); GetObject(hFont, sizeof(LOGFONT), &lf);
lf.lfCharSet = CharSetFromSid(ScriptId); lf.lfHeight += lf.lfHeight/2; lf.lfWidth += lf.lfWidth/2;
StrCpyN(lf.lfFaceName, lpFace, LF_FACESIZE); hFont = CreateFontIndirect(&lf); hTemp = (HFONT)SelectObject(hDC, hFont);
GetTextMetrics(hDC, &tm);
len = lstrlen(szFontSample); GetTextExtentPoint32(hDC, szFontSample, len, &TextExtent); TextExtent.cy = tm.tmAscent - tm.tmInternalLeading;
DrawEdge(hDC, &rc, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
if ((TextExtent.cx >= (rc.right - rc.left)) || (TextExtent.cx <= 0)) x = rc.left; else x = rc.left + ((rc.right - rc.left) - TextExtent.cx) / 2;
y = min(rc.bottom, rc.bottom - ((rc.bottom - rc.top) - TextExtent.cy) / 2);
if (lpFace[0]) ExtTextOut(hDC, x, y - (tm.tmAscent), ETO_OPAQUE | ETO_CLIPPED, &rc, szFontSample, len, NULL ); else ExtTextOut(hDC, x, y - (tm.tmAscent), ETO_OPAQUE | ETO_CLIPPED, &rc, TEXT(" "), 1, NULL );
SetBkColor(hDC, rgbBack); SetTextColor(hDC, rgbText);
if (hTemp) DeleteObject(SelectObject(hDC, hTemp));
ReleaseDC(pFnt->hDlg, hDC); }
//
// FillCharsetListBoxes()
//
// Fills the Web page and Plain text ListBoxes with the appropriate
// font data
//
BOOL FillScriptListBoxes(LPFONTSCRIPTDATA pFnt, SCRIPT_ID sid) {
UINT i; UINT nFonts = 0; int iSidInfo = -1; PSCRIPTFONTINFO pSidFont = NULL;
if (!pFnt->pSidInfo) return FALSE;
// erase all the listboxes to start fresh
SendMessage(pFnt->hwndPropLB, LB_RESETCONTENT, 0, 0); SendMessage(pFnt->hwndFixedLB, LB_RESETCONTENT, 0, 0);
for(i=0; i < g_cSidInfo; i++) { if (pFnt->pSidInfo[i].ScriptId == sid) { iSidInfo = i; break; } }
if (-1 == iSidInfo) return FALSE;
if (g_pMLFlnk2) {
g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_PROPORTIONAL_FONT, &nFonts, NULL);
if (nFonts) {
pSidFont = (PSCRIPTFONTINFO) LocalAlloc(LPTR, sizeof(SCRIPTFONTINFO)*nFonts); if (pSidFont) { g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_PROPORTIONAL_FONT, &nFonts, pSidFont); for (i=0; i<nFonts; i++) { if (LB_ERR == SendMessage(pFnt->hwndPropLB, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((pSidFont+i)->wszFont))) { // add the font name to the combobox
SendMessage(pFnt->hwndPropLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont)); }
} // Hack PRC font problems on Win9x and NT4 (Bug #24641, #39946)
// Win9x does not ship with GBK-supporting fixed-pitch fonts,
// We provide user proportional fonts as plain text font candidates.
if (sid == sidHan && GetACP() == 936 && !IsOS(OS_WIN2000ORGREATER)) { for (i=0; i<nFonts; i++) { // add the font name to the combobox
SendMessage(pFnt->hwndFixedLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont)); } }
LocalFree(pSidFont); pSidFont = NULL; } }
// Get number of available fonts
g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_FIXED_FONT, &nFonts, NULL); if (nFonts) { pSidFont = (PSCRIPTFONTINFO) LocalAlloc(LPTR, sizeof(SCRIPTFONTINFO)*nFonts); if (pSidFont) { g_pMLFlnk2->GetScriptFontInfo(sid, SCRIPTCONTF_FIXED_FONT, &nFonts, pSidFont);
if (!pFnt->pSidInfo[iSidInfo].wszFixedWidthFont[0]) { StrCpyN(pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, pSidFont->wszFont, LF_FACESIZE); pFnt->bChanged = TRUE; }
// All fixedwidth and proportional fonts are web page font candidates
for (i=0; i<nFonts; i++) { if (LB_ERR == SendMessage(pFnt->hwndFixedLB, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((pSidFont+i)->wszFont))) { // add the font name to the combobox
SendMessage(pFnt->hwndFixedLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont)); } if (LB_ERR == SendMessage(pFnt->hwndPropLB, LB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)((pSidFont+i)->wszFont))) { // add the font name to the combobox
SendMessage(pFnt->hwndPropLB, LB_ADDSTRING, 0, (LPARAM)((pSidFont+i)->wszFont)); } }
LocalFree(pSidFont); } } }
// Add fonts to combobox
#ifdef UNIX
/* We would have called EnumFontFamiliesEx wherein we would have
* have populated the fonts list boxes with substitute fonts if any * * So, before we populate the proportional and the fixed fonts below, * we must query and use substitute fonts if avbl. */ { CHAR szSubstFont[MAX_MIMEFACE_NAME+1]; DWORD cchSubstFont = MAX_MIMEFACE_NAME + 1; CHAR szFont[MAX_MIMEFACE_NAME + 1]; WideCharToMultiByte(CP_ACP, 0, pFnt->pSidInfo[iSidInfo].wszProportionalFont, -1, szFont, MAX_MIMEFACE_NAME + 1, NULL, NULL); if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) && cchSubstFont) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1, pFnt->pSidInfo[iSidInfo].wszProportionalFont, MAX_MIMEFACE_NAME + 1); }
WideCharToMultiByte(CP_ACP, 0, pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, -1, szFont, MAX_MIMEFACE_NAME + 1, NULL, NULL); cchSubstFont = MAX_MIMEFACE_NAME + 1; if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) && cchSubstFont) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1, pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, MAX_MIMEFACE_NAME + 1); } } #endif /* UNIX */
// select the current prop default
if (pFnt->pSidInfo[iSidInfo].wszProportionalFont[0]) { if (LB_ERR == SendMessage(pFnt->hwndPropLB, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->pSidInfo[iSidInfo].wszProportionalFont)) pFnt->pSidInfo[iSidInfo].wszProportionalFont[0] = 0; } // Draw sample strings with current font
DrawSampleString((FONTSDATA *)pFnt, IDC_FONTS_PROP_SAMPLE, pFnt->pSidInfo[iSidInfo].wszProportionalFont, pFnt->pSidInfo[iSidInfo].ScriptId);
// select the current fixed default
if (pFnt->pSidInfo[iSidInfo].wszFixedWidthFont[0]) { if (LB_ERR == SendMessage(pFnt->hwndFixedLB, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->pSidInfo[iSidInfo].wszFixedWidthFont)) pFnt->pSidInfo[iSidInfo].wszFixedWidthFont[0] = 0; } // Draw sample strings with current font
DrawSampleString((FONTSDATA *)pFnt, IDC_FONTS_FIXED_SAMPLE, pFnt->pSidInfo[iSidInfo].wszFixedWidthFont, pFnt->pSidInfo[iSidInfo].ScriptId);
// we handled it
return TRUE;
} // FillScriptListBoxes()
//
// FontsDlgInitEx()
//
// Initializes the script based font dialog, use same dialog box template.
//
BOOL FontsDlgInitEx(IN HWND hDlg, LPCTSTR lpszKeyPath) { HKEY hkey; // DWORD dw;
DWORD cb; DWORD i;
TCHAR szKey[1024];
LPFONTSCRIPTDATA pFnt; // localize data
if (!hDlg) return FALSE; // nothing to initialize
// get some space to store local data
// NOTE: LocalAlloc already zeroes the memory
pFnt = (LPFONTSCRIPTDATA)LocalAlloc(LPTR, sizeof(*pFnt)); if (!pFnt) { EndDialog(hDlg, 0); return FALSE; }
if (!InitScriptTable(pFnt)) { EndDialog(hDlg, 0); return FALSE; }
// associate the memory with the dialog window
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pFnt);
// save the dialog handle
pFnt->hDlg = hDlg;
// get the dialog items
pFnt->hwndPropLB = GetDlgItem(pFnt->hDlg, IDC_FONTS_PROP_FONT_LIST); pFnt->hwndFixedLB = GetDlgItem(pFnt->hDlg, IDC_FONTS_FIXED_FONT_LIST); pFnt->hwndNamesCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_CHAR_SET_COMBO); pFnt->lpszKeyPath = lpszKeyPath ? lpszKeyPath: REGSTR_PATH_INTERNATIONAL_SCRIPTS;
if (!g_pMLFlnk2 || FAILED(g_pMLFlnk2->CodePageToScriptID(GetACP(), &(pFnt->sidDefault)))) pFnt->sidDefault = sidAsciiLatin; // We shouldn't consider default script in registry since we no longer have UI to allow user to change default script
#if 0
// get values from registry
if (RegOpenKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, KEY_READ, &hkey) == ERROR_SUCCESS) { cb = sizeof(dw); if (RegQueryValueEx(hkey, REGSTR_VAL_DEFAULT_SCRIPT, NULL, NULL, (LPBYTE)&dw, &cb) == ERROR_SUCCESS) { pFnt->sidDefault = (SCRIPT_ID)dw; } RegCloseKey(hkey); } #endif
for (i = 0; i < g_cSidInfo; i++) { wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("%s\\%u"), pFnt->lpszKeyPath, pFnt->pSidInfo[i].ScriptId); if (RegOpenKeyEx(HKEY_CURRENT_USER, szKey, NULL, KEY_READ, &hkey) == ERROR_SUCCESS) { TCHAR szFont[MAX_MIMEFACE_NAME];
cb = sizeof(szFont);
if (RegQueryValueEx(hkey, REGSTR_VAL_FIXED_FONT, NULL, NULL, (LPBYTE)szFont, &cb) == ERROR_SUCCESS) { StrCpyN(pFnt->pSidInfo[i].wszFixedWidthFont, szFont, ARRAYSIZE(pFnt->pSidInfo[i].wszFixedWidthFont)); } cb = sizeof(szFont); if (RegQueryValueEx(hkey, REGSTR_VAL_PROP_FONT, NULL, NULL, (LPBYTE)szFont, &cb) == ERROR_SUCCESS) { StrCpyN(pFnt->pSidInfo[i].wszProportionalFont, szFont, ARRAYSIZE(pFnt->pSidInfo[i].wszProportionalFont)); } RegCloseKey(hkey);
}
// add the name to the listbox
SendMessage(pFnt->hwndNamesCB, CB_ADDSTRING, 0, (LPARAM)pFnt->pSidInfo[i].wszDescription);
// check to see if it is the default code page
if (pFnt->sidDefault == pFnt->pSidInfo[i].ScriptId) { SendMessage(pFnt->hwndNamesCB, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->pSidInfo[i].wszDescription); }
}
pFnt->bChanged = FALSE;
FillScriptListBoxes(pFnt, pFnt->sidDefault);
if( g_restrict.fFonts ) { EnableWindow( GetDlgItem( hDlg, IDC_FONTS_PROP_FONT_LIST ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_FONTS_FIXED_FONT_LIST ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_FONTS_CHAR_SET_COMBO ), FALSE); #ifdef UNIX
EnableWindow( GetDlgItem( hDlg, IDC_FONTS_UPDATE_BUTTON ), FALSE); #endif
}
// everything ok
return TRUE;
} // FontsDlgInit()
//
// SaveFontsDataEx()
//
// Save the new fonts settings into regestry
//
void SaveFontsDataEx(LPFONTSCRIPTDATA pFnt) { HKEY hkeyScript; TCHAR szScript[MAX_SCRIPT_NAME];
HKEY hkey; DWORD dw;
// get values from registry
if (RegCreateKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, NULL, NULL, KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS) { UINT i; RegSetValueEx(hkey, REGSTR_VAL_DEFAULT_SCRIPT, NULL, REG_BINARY, (LPBYTE)&pFnt->sidDefault, sizeof(pFnt->sidDefault)); for(i = 0; i < g_cSidInfo; i++) { wnsprintf(szScript, ARRAYSIZE(szScript), TEXT("%u"), pFnt->pSidInfo[i].ScriptId); if (RegCreateKeyEx(hkey, szScript, NULL, NULL, NULL, KEY_WRITE, NULL, &hkeyScript, &dw) == ERROR_SUCCESS) { // Currently, no need for script name, save registry space
#if 0
RegSetValueEx(hkeyScript, REGSTR_VAL_FONT_SCRIPT_NAME, NULL, REG_SZ, (LPBYTE)&pFnt->pSidInfo[i].wszDescription, (lstrlen(pFnt->pSidInfo[i].wszDescription)+1)*sizeof(TCHAR)); #endif
RegSetValueEx(hkeyScript, REGSTR_VAL_SCRIPT_FIXED_FONT, NULL, REG_SZ, (LPBYTE)pFnt->pSidInfo[i].wszFixedWidthFont, (lstrlen(pFnt->pSidInfo[i].wszFixedWidthFont)+1)*sizeof(TCHAR)); RegSetValueEx(hkeyScript, REGSTR_VAL_SCRIPT_PROP_FONT, NULL, REG_SZ, (LPBYTE)pFnt->pSidInfo[i].wszProportionalFont, (lstrlen(pFnt->pSidInfo[i].wszProportionalFont)+1)*sizeof(TCHAR));
RegCloseKey(hkeyScript); } // if RegCreateKeyEx
} // for
RegCloseKey(hkey); } // if RegCreateKeyEx
} // SaveFontsDataEx()
//
// FontsOnCommandEx()
//
// Handles WM_COMMAND message for the script based Fonts subdialog
//
BOOL FontsOnCommandEx(LPFONTSCRIPTDATA pFnt, UINT id, UINT nCmd) { switch(id) { case IDOK: if (pFnt->bChanged) { SaveFontsDataEx(pFnt); // tell MSHTML to pick up changes and update
UpdateAllWindows(); } return TRUE; // exit dialog
case IDCANCEL: return TRUE; // exit dialog
case IDC_FONTS_PROP_FONT_LIST: case IDC_FONTS_FIXED_FONT_LIST: if (nCmd==LBN_SELCHANGE) { UINT i; TCHAR szScript[MAX_SCRIPT_NAME];
pFnt->bChanged = TRUE; // we need to save
// find the currently selected item in the list box
GetDlgItemText(pFnt->hDlg, IDC_FONTS_CHAR_SET_COMBO, szScript, ARRAYSIZE(szScript)); // find the code page from the text
for(i=0; i < g_cSidInfo; i++) { INT_PTR j; if (IsStringEqual(szScript, pFnt->pSidInfo[i].wszDescription)) { // grab the new values
j = SendMessage(pFnt->hwndPropLB, LB_GETCURSEL, 0, 0); SendMessage(pFnt->hwndPropLB, LB_GETTEXT, j, (LPARAM)(pFnt->pSidInfo[i].wszProportionalFont)); j = SendMessage(pFnt->hwndFixedLB, LB_GETCURSEL, 0, 0); SendMessage(pFnt->hwndFixedLB, LB_GETTEXT, j, (LPARAM)(pFnt->pSidInfo[i].wszFixedWidthFont)); break; } }
// Redraw sample strings
DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_PROP_SAMPLE, pFnt->pSidInfo[i].wszProportionalFont, pFnt->pSidInfo[i].ScriptId); DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_FIXED_SAMPLE, pFnt->pSidInfo[i].wszFixedWidthFont, pFnt->pSidInfo[i].ScriptId);
// if we don't find it... we are going to keep the default
ASSERT(i < g_cSidInfo); // something went wrong
} break;
case IDC_FONTS_CHAR_SET_COMBO: if (nCmd==CBN_SELCHANGE) { UINT i; TCHAR szScript[MAX_SCRIPT_NAME];
GetDlgItemText(pFnt->hDlg, IDC_FONTS_CHAR_SET_COMBO, szScript, ARRAYSIZE(szScript)); // find the code page from the text
for(i=0; i < g_cSidInfo; i++) { if (IsStringEqual(szScript, pFnt->pSidInfo[i].wszDescription)) { FillScriptListBoxes(pFnt, pFnt->pSidInfo[i].ScriptId); break; } } } break; #ifdef UNIX
case IDC_FONTS_UPDATE_BUTTON: { HCURSOR hOldCursor = NULL; HCURSOR hNewCursor = NULL;
hNewCursor = LoadCursor(NULL, IDC_WAIT); if (hNewCursor) hOldCursor = SetCursor(hNewCursor);
DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTUPD_PROG), pFnt->hDlg,FontUpdDlgProc, NULL);
if(hOldCursor) SetCursor(hOldCursor); } break; #endif
} // don't exit dialog
return FALSE; }
//
// FontsDlgProcEx()
//
// Message handler for the script based "Fonts" subdialog.
//
INT_PTR CALLBACK FontsDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPFONTSCRIPTDATA pFnt = (LPFONTSCRIPTDATA) GetWindowLongPtr(hDlg, DWLP_USER); PAINTSTRUCT ps;
switch (uMsg) { case WM_INITDIALOG: return FontsDlgInitEx(hDlg, (LPTSTR)lParam); break;
case WM_DESTROY: // Free memory
if (pFnt) { if (pFnt->pSidInfo) LocalFree(pFnt->pSidInfo); LocalFree(pFnt); }
break; case WM_PAINT:
if (BeginPaint(hDlg, &ps)) { UINT i; SCRIPT_ID sid = 0; TCHAR szScript[MAX_SCRIPT_NAME];
GetDlgItemText(hDlg, IDC_FONTS_CHAR_SET_COMBO, szScript, ARRAYSIZE(szScript)); // find the script id from the text
for(i = 0; i < g_cSidInfo; i++) { if (IsStringEqual(szScript, pFnt->pSidInfo[i].wszDescription)) { sid = pFnt->pSidInfo[i].ScriptId; break; } }
if (i < g_cSidInfo) { // show sample strings with current font
DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_PROP_SAMPLE, pFnt->pSidInfo[i].wszProportionalFont, pFnt->pSidInfo[i].ScriptId); DrawSampleString((LPFONTSDATA)pFnt, IDC_FONTS_FIXED_SAMPLE, pFnt->pSidInfo[i].wszFixedWidthFont, pFnt->pSidInfo[i].ScriptId); } EndPaint(hDlg, &ps); } break;
case WM_COMMAND: if (FontsOnCommandEx(pFnt, LOWORD(wParam), HIWORD(wParam))) EndDialog(hDlg, LOWORD(wParam) == IDOK? 1: 0); break;
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE, HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break;
#ifdef UNIX
case WM_DRAWITEM: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_FONTS_UPDATE_BUTTON: DrawXFontButton(hDlg, (LPDRAWITEMSTRUCT)lParam); return TRUE; } return FALSE; #endif
default: return FALSE; } return TRUE; }
//
// Back out old font dialog for OE4
//
//
// InitMimeCsetTable()
//
// Initialize MimeCharsetTable[]'s string field with resource string
//
BOOL InitMimeCsetTable(BOOL bIsOE5) { IMultiLanguage *pML=NULL; IMultiLanguage2 *pML2=NULL; HRESULT hr;
if(!hOLE32) { if(!_StartOLE32()) { ASSERT(FALSE); return FALSE; } } hr = pCoInitialize(NULL); if (FAILED(hr)) return FALSE;
if (bIsOE5) hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage2, (LPVOID *) &pML2); else hr = pCoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage, (LPVOID *) &pML); if (SUCCEEDED(hr)) { IEnumCodePage *pEnumCP;
if (bIsOE5) { // Ignore MUI if cross code page, otherwise, we won't be able to save data in registry
char szUICP[1024] = {0}; LANGID uiLangId = INETCPL_GetUILanguage();
// We always support English (US)
if (uiLangId != 0x0409) GetLocaleInfoA(MAKELCID(uiLangId, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szUICP, ARRAYSIZE(szUICP));
if (szUICP[0] && (UINT)StrToIntA(szUICP) != GetACP()) hr = pML2->EnumCodePages(MIMECONTF_VALID, GetSystemDefaultLangID(), &pEnumCP); else hr = pML2->EnumCodePages(MIMECONTF_VALID, uiLangId, &pEnumCP);
} else hr = pML->EnumCodePages(MIMECONTF_VALID, &pEnumCP);
if (SUCCEEDED(hr)) { UINT cNum = 0; if (bIsOE5) pML2->GetNumberOfCodePageInfo(&cNum); else pML->GetNumberOfCodePageInfo(&cNum);
#ifdef UNICODE
g_pCPInfo = (PMIMECPINFO)LocalAlloc(LPTR, sizeof(MIMECPINFO) * cNum); if (NULL != g_pCPInfo) { hr = pEnumCP->Next(cNum, g_pCPInfo, &g_cCPInfo); if (SUCCEEDED(hr)) { g_pCPInfo = (PMIMECPINFO)LocalReAlloc(g_pCPInfo, sizeof(MIMECPINFO) * g_cCPInfo, LMEM_MOVEABLE); } else { LocalFree(g_pCPInfo); g_pCPInfo = NULL; } #else
g_pCPInfoW = (PMIMECPINFO)LocalAlloc(LPTR, sizeof(MIMECPINFO) * cNum); if (NULL != g_pCPInfoW) { hr = pEnumCP->Next(cNum, g_pCPInfoW, &g_cCPInfo); if (SUCCEEDED(hr)) { g_pCPInfo = (PMIMECPINFOA)LocalAlloc(LPTR, sizeof(MIMECPINFOA) * g_cCPInfo); if (NULL != g_pCPInfo) { UINT i;
for (i = 0; i < g_cCPInfo; i++) { g_pCPInfo[i].dwFlags = g_pCPInfoW[i].dwFlags; g_pCPInfo[i].uiCodePage = g_pCPInfoW[i].uiCodePage; g_pCPInfo[i].uiFamilyCodePage = g_pCPInfoW[i].uiFamilyCodePage; WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszDescription, -1, g_pCPInfo[i].wszDescription, sizeof(g_pCPInfo[i].wszDescription), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszWebCharset, -1, g_pCPInfo[i].wszWebCharset, sizeof(g_pCPInfo[i].wszWebCharset), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszHeaderCharset, -1, g_pCPInfo[i].wszHeaderCharset, sizeof(g_pCPInfo[i].wszHeaderCharset), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszBodyCharset, -1, g_pCPInfo[i].wszBodyCharset, sizeof(g_pCPInfo[i].wszBodyCharset), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszFixedWidthFont, -1, g_pCPInfo[i].wszFixedWidthFont, sizeof(g_pCPInfo[i].wszFixedWidthFont), NULL, NULL); WideCharToMultiByte(CP_ACP, 0, (WCHAR *)g_pCPInfoW[i].wszProportionalFont, -1, g_pCPInfo[i].wszProportionalFont, sizeof(g_pCPInfo[i].wszProportionalFont), NULL, NULL); g_pCPInfo[i].bGDICharset = g_pCPInfoW[i].bGDICharset; } } } LocalFree(g_pCPInfoW); g_pCPInfoW = NULL; #endif
} pEnumCP->Release(); } if (bIsOE5) pML2->Release(); else pML->Release(); } pCoUninitialize();
return TRUE; }
//
// FreeMimeCsetTable()
//
// Free string buffer of MimeCharsetTable[]'s string field
//
void FreeMimeCsetTable(void) { if (NULL != g_pCPInfo) { LocalFree(g_pCPInfo); g_pCPInfo = NULL; g_cCPInfo = 0; } }
//
// EnumFontsProc()
//
// Selects only one font per style
//
int CALLBACK EnumFontsProc( ENUMLOGFONTEX FAR* elf, // address of logical-font data
TEXTMETRIC FAR* tm, // address of physical-font data
DWORD dwFontType, // type of font
LPARAM lParam // address of application-defined data
) { LOGFONT FAR* lf; LPFONTSDATA pFnt;
ASSERT(lParam); ASSERT(elf); pFnt = (LPFONTSDATA)lParam;
lf = &(elf->elfLogFont); if ( dwFontType == DEVICE_FONTTYPE || dwFontType == RASTER_FONTTYPE ) return TRUE; // keep going but don't use this font
/* We don't use the SYMBOL fonts */ if( lf->lfCharSet == SYMBOL_CHARSET ) return TRUE;
// we don't handle Mac Charset
if (lf->lfCharSet == MAC_CHARSET ) return TRUE;
if ( IsVerticalFont(lf->lfFaceName) ) return TRUE; // keep going but don't use this font
if ( lf->lfPitchAndFamily & FIXED_PITCH ) { if (CB_ERR == SendMessage(pFnt->hwndFixedCB, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)elf->elfLogFont.lfFaceName)) { // add the font name to the combobox
SendMessage(pFnt->hwndFixedCB, CB_ADDSTRING, 0, (LPARAM)elf->elfLogFont.lfFaceName); } }
if (CB_ERR == SendMessage(pFnt->hwndPropCB, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)elf->elfLogFont.lfFaceName)) { // add the font name to the combobox
SendMessage(pFnt->hwndPropCB, CB_ADDSTRING, 0, (LPARAM)elf->elfLogFont.lfFaceName); } return TRUE; }
//
// FillFontComboBox()
//
// Fills hwndCB with the names of fonts of family dwCodePage.
//
BOOL FillFontComboBox(IN LPFONTSDATA pFnt, IN BYTE CodePage) { HDC hDC; LOGFONT lf; HWND hWnd; BOOL fReturn = FALSE;
// get system font info
hWnd = GetTopWindow(GetDesktopWindow()); hDC = GetDC(hWnd);
if (hDC) { lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; lf.lfCharSet = CodePage;
EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)EnumFontsProc, (LPARAM)pFnt, 0);
// everthing went fine
fReturn = TRUE; }
ReleaseDC(hWnd, hDC);
return fReturn;
} // FillFontComboBox()
//
// FillSizeComboBox()
//
// Fills font size combobox with the size of fonts.
//
BOOL FillSizeComboBox(IN LPFONTSDATA pFnt) { int i;
for (i = IDS_FONT_SIZE_SMALLEST; i <= IDS_FONT_SIZE_LARGEST ; i++) { TCHAR szSize[MAX_MIMEFACE_NAME];
MLLoadString(i, szSize, sizeof(szSize)); SendMessage(pFnt->hwndSizeCB, CB_ADDSTRING, 0, (LPARAM)szSize); }
return TRUE; }
//
// FillCharsetComboBoxes()
//
// Fills the Fixed, Prop, and MIME comboboxes with the appropriate
// font data
//
BOOL FillCharsetComboBoxes(LPFONTSDATA pFnt, DWORD dwCodePage) { UINT i; int iPageInfo = -1; DWORD grfFlag;
// erase all the comboboxes to start fresh
SendMessage(pFnt->hwndPropCB, CB_RESETCONTENT, 0, 0); SendMessage(pFnt->hwndFixedCB, CB_RESETCONTENT, 0, 0); SendMessage(pFnt->hwndSizeCB, CB_RESETCONTENT, 0, 0); SendMessage(pFnt->hwndMIMECB, CB_RESETCONTENT, 0, 0);
// What happens if other one calls OpenFontDialog except Athena?
grfFlag = StrCmpI(pFnt->lpszKeyPath, REGSTR_PATH_INTERNATIONAL)? MIMECONTF_MAILNEWS: MIMECONTF_BROWSER;
for(i=0; i < g_cCPInfo; i++) { // find the codepage in our table
if (g_pCPInfo[i].uiFamilyCodePage == (UINT)dwCodePage) { //
// populate MIME combobox
//
if (g_pCPInfo[i].uiCodePage == (UINT)dwCodePage) iPageInfo = i; // we store info per family codepage here
// add mime type to combobox
if (grfFlag & g_pCPInfo[i].dwFlags) { // HACK: We need to remove Japanese JIS 1 Byte Kana and Korean for MAILNEWS.
// 949 : Korean. We are using Korean (Auto Detect) instead
// 50225 : Korean ISO
// 50221 : Japanese JIS 1 byte Kana-ESC
// 50222 : Japanese JIS 1 byte Kana-SIO
if (grfFlag & MIMECONTF_MAILNEWS) { if (g_pCPInfo[i].uiCodePage == 949 || g_pCPInfo[i].uiCodePage == 50221 || g_pCPInfo[i].uiCodePage == 50222 || g_pCPInfo[i].uiCodePage == 50225) continue; } SendMessage(pFnt->hwndMIMECB, CB_ADDSTRING, 0, (LPARAM)g_pCPInfo[i].wszDescription); }
} // if CodePage
} // for i
if (-1 != iPageInfo) { // if nothing is defined, then copy the first possible value that
// we know of from our table
if (!pFnt->page[iPageInfo].szMIMEFont[0]) { if (grfFlag & g_pCPInfo[iPageInfo].dwFlags) StrCpyN(pFnt->page[iPageInfo].szMIMEFont, g_pCPInfo[iPageInfo].wszDescription, ARRAYSIZE(pFnt->page[iPageInfo].szMIMEFont)); else { for (i = 0; i < g_cCPInfo; i++) { if (g_pCPInfo[iPageInfo].uiCodePage == g_pCPInfo[i].uiFamilyCodePage) { if (grfFlag & g_pCPInfo[i].dwFlags) { StrCpyN(pFnt->page[iPageInfo].szMIMEFont, g_pCPInfo[i].wszDescription, ARRAYSIZE(pFnt->page[iPageInfo].szMIMEFont)); break; } } } } }
// select the current default
SendMessage(pFnt->hwndMIMECB, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->page[iPageInfo].szMIMEFont);
// Enable/disable MIME is when there is only one possibility
EnableWindow(pFnt->hwndMIMECB, (1 < SendMessage(pFnt->hwndMIMECB, CB_GETCOUNT, 0, (LPARAM)0)) && !g_restrict.fFonts); // Add fonts to combobox
FillFontComboBox(pFnt, g_pCPInfo[iPageInfo].bGDICharset);
#ifdef UNIX
/* We would have called EnumFontFamiliesEx wherein we would have
* have populated the fonts list boxes with substitute fonts if any * * So, before we populate the proportional and the fixed fonts below, * we must query and use substitute fonts if avbl. */ { CHAR szSubstFont[MAX_MIMEFACE_NAME+1]; DWORD cchSubstFont = MAX_MIMEFACE_NAME + 1; CHAR szFont[MAX_MIMEFACE_NAME + 1]; WideCharToMultiByte(CP_ACP, 0, pFnt->page[iPageInfo].szPropFont, -1, szFont, MAX_MIMEFACE_NAME + 1, NULL, NULL); if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) && cchSubstFont) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1, pFnt->page[iPageInfo].szPropFont, MAX_MIMEFACE_NAME + 1); }
WideCharToMultiByte(CP_ACP, 0, pFnt->page[iPageInfo].szFixedFont, -1, szFont, MAX_MIMEFACE_NAME + 1, NULL, NULL); cchSubstFont = MAX_MIMEFACE_NAME + 1; if ((ERROR_SUCCESS == MwGetSubstituteFont(szFont, szSubstFont, &cchSubstFont)) && cchSubstFont) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szSubstFont, -1, pFnt->page[iPageInfo].szFixedFont, MAX_MIMEFACE_NAME + 1); } } #endif /* UNIX */
// select the current prop default
SendMessage(pFnt->hwndPropCB, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->page[iPageInfo].szPropFont);
// select the current fixed default
SendMessage(pFnt->hwndFixedCB, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->page[iPageInfo].szFixedFont);
// Add font sizes to combobox
FillSizeComboBox(pFnt);
// select the current size default
SendMessage(pFnt->hwndSizeCB, CB_SETCURSEL, (WPARAM)pFnt->page[iPageInfo].dwFontSize, (LPARAM)0);
// we handled it
return TRUE; }
return FALSE;
} // FillCharsetComboBoxes()
//
// FontsDlgInit()
//
// Initializes the Fonts dialog.
//
BOOL FontsDlgInit(IN HWND hDlg, LPCTSTR lpszKeyPath) { HKEY hkey; DWORD grfFlag; DWORD dw; DWORD cb; DWORD i; BOOL bIsOE5 = FALSE;
TCHAR szKey[1024];
LPFONTSDATA pFnt; // localize data
if (!hDlg) return FALSE; // nothing to initialize
// set system default character set where we possibly show
// the strings in native language.
SHSetDefaultDialogFont(hDlg, IDC_FONTS_PROP_FONT_COMBO); SHSetDefaultDialogFont(hDlg, IDC_FONTS_FIXED_FONT_COMBO); SHSetDefaultDialogFont(hDlg, IDC_FONTS_MIME_FONT_COMBO); SHSetDefaultDialogFont(hDlg, IDC_FONTS_DEFAULT_LANG_TEXT); SHSetDefaultDialogFont(hDlg, IDC_FONTS_CODE_PAGES_LIST);
// get some space to store local data
// NOTE: LocalAlloc already zeroes the memory
pFnt = (LPFONTSDATA)LocalAlloc(LPTR, sizeof(*pFnt)); if (!pFnt) { EndDialog(hDlg, 0); return FALSE; }
// We distinguish OE5 and OE4 by searching for "5.0" in its registry path,
// It works as long as there is no spec. change in OE5
if (NULL != StrStr(lpszKeyPath, TEXT("5.0"))) bIsOE5 = TRUE;
if (!InitMimeCsetTable(bIsOE5)) { EndDialog(hDlg, 0); return FALSE; }
if (NULL == pFnt->page) { pFnt->page = (CODEPAGEDATA*)LocalAlloc(LPTR, sizeof(CODEPAGEDATA) * g_cCPInfo); if (NULL == pFnt->page) { EndDialog(hDlg, 0); return FALSE; } }
// associate the memory with the dialog window
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) pFnt);
// save the dialog handle
pFnt->hDlg = hDlg;
// get the dialog items
pFnt->hwndPropCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_PROP_FONT_COMBO); pFnt->hwndFixedCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_FIXED_FONT_COMBO); pFnt->hwndSizeCB = GetDlgItem(pFnt->hDlg, IDC_FONTS_SIZE_FONT_COMBO); pFnt->hwndMIMECB = GetDlgItem(pFnt->hDlg, IDC_FONTS_MIME_FONT_COMBO); pFnt->hwndNamesLB = GetDlgItem(pFnt->hDlg, IDC_FONTS_CODE_PAGES_LIST); pFnt->lpszKeyPath = lpszKeyPath ? lpszKeyPath: REGSTR_PATH_INTERNATIONAL; pFnt->dwDefaultCodePage = GetACP(); // get values from registry
if (RegOpenKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, KEY_READ, &hkey) == ERROR_SUCCESS) { cb = sizeof(dw); if (RegQueryValueEx(hkey, REGSTR_VAL_DEFAULT_CODEPAGE, NULL, NULL, (LPBYTE)&dw, &cb) == ERROR_SUCCESS) { pFnt->dwDefaultCodePage = dw; } RegCloseKey(hkey); }
// What happens if other one calls OpenFontDialog except Athena?
grfFlag = StrCmpI(pFnt->lpszKeyPath, REGSTR_PATH_INTERNATIONAL)? MIMECONTF_MAILNEWS: MIMECONTF_BROWSER;
for (i = 0; i < g_cCPInfo; i++) { if (g_pCPInfo[i].uiCodePage == g_pCPInfo[i].uiFamilyCodePage) { int iDef; UINT j;
iDef = -1; if (0 == (grfFlag & g_pCPInfo[i].dwFlags)) { for (j = 0; j < g_cCPInfo; j++) { if (g_pCPInfo[i].uiCodePage == g_pCPInfo[j].uiFamilyCodePage) { if (grfFlag & g_pCPInfo[j].dwFlags) { iDef = j; break; } } } if (-1 == iDef) continue; }
if (g_pCPInfo[i].uiCodePage == 50001) // skip CP_AUTO
continue;
wnsprintf(szKey, ARRAYSIZE(szKey), TEXT("%s\\%u"), pFnt->lpszKeyPath, g_pCPInfo[i].uiCodePage); if (RegOpenKeyEx(HKEY_CURRENT_USER, szKey, NULL, KEY_READ, &hkey) == ERROR_SUCCESS) { cb = sizeof(pFnt->page[i].szFriendlyName); if (RegQueryValueEx(hkey, REGSTR_VAL_FONT_SCRIPT, NULL, NULL, (LPBYTE)&pFnt->page[i].szFriendlyName, &cb) != ERROR_SUCCESS) { TCHAR *p;
StrCpyN(pFnt->page[i].szFriendlyName, g_pCPInfo[i].wszDescription, ARRAYSIZE(pFnt->page[i].szFriendlyName)); for (p = pFnt->page[i].szFriendlyName; *p != TEXT('\0'); p = CharNext(p)) { // We'd better have a source of this string else where.
if (*p == TEXT('(')) { *p = TEXT('\0'); break; } } }
cb = sizeof(dw); if (RegQueryValueEx(hkey, REGSTR_VAL_DEF_INETENCODING, NULL, NULL, (LPBYTE)&dw, &cb) != ERROR_SUCCESS) { dw = (DWORD)g_pCPInfo[i].uiCodePage; // HACK ! It's only for Japanese Auto Select as Japanese default.
if (dw == 932) // 932 : Japanese Windows CodePage
dw = 50932; // 50932 : Japanese Auto Select InternetEncoding
} for (j = 0; j < g_cCPInfo; j++) { if (g_pCPInfo[j].uiCodePage == (UINT)dw) { if (grfFlag & g_pCPInfo[j].dwFlags) StrCpyN(pFnt->page[i].szMIMEFont, g_pCPInfo[j].wszDescription, ARRAYSIZE(pFnt->page[i].szMIMEFont)); else if (-1 != iDef) StrCpyN(pFnt->page[i].szMIMEFont, g_pCPInfo[iDef].wszDescription, ARRAYSIZE(pFnt->page[i].szMIMEFont)); else pFnt->page[i].szMIMEFont[0] = TEXT('\0'); break; } } cb = sizeof(pFnt->page[i].szFixedFont); if (RegQueryValueEx(hkey, REGSTR_VAL_FIXED_FONT, NULL, NULL, (LPBYTE)pFnt->page[i].szFixedFont, &cb) != ERROR_SUCCESS) { StrCpyN(pFnt->page[i].szFixedFont, g_pCPInfo[i].wszFixedWidthFont, ARRAYSIZE(pFnt->page[i].szFixedFont)); } cb = sizeof(pFnt->page[i].szPropFont); if (RegQueryValueEx(hkey, REGSTR_VAL_PROP_FONT, NULL, NULL, (LPBYTE)pFnt->page[i].szPropFont, &cb) != ERROR_SUCCESS) { StrCpyN(pFnt->page[i].szPropFont, g_pCPInfo[i].wszProportionalFont, ARRAYSIZE(pFnt->page[i].szPropFont)); }
cb = sizeof(pFnt->page[i].dwFontSize); if (RegQueryValueEx(hkey, REGSTR_VAL_FONT_SIZE, NULL, NULL, (LPBYTE)&pFnt->page[i].dwFontSize, &cb) != ERROR_SUCCESS) { pFnt->page[i].dwFontSize = REGSTR_VAL_FONT_SIZE_DEF; } RegCloseKey(hkey);
} else { UINT j; TCHAR *p;
StrCpyN(pFnt->page[i].szFriendlyName, g_pCPInfo[i].wszDescription, ARRAYSIZE(pFnt->page[i].szFriendlyName)); for (p = pFnt->page[i].szFriendlyName; *p != TEXT('\0'); p = CharNext(p)) { if (*p == TEXT('(')) { *p = TEXT('\0'); break; } } j = (grfFlag & g_pCPInfo[i].dwFlags)? i: iDef; // HACK ! It's only for Japanese Auto Select as Japanese default.
if (g_pCPInfo[j].uiCodePage == 932) // 932 : Japanese Windows CodePage
{ for (j = 0; j < g_cCPInfo; j++) { if (g_pCPInfo[j].uiCodePage == 50932) // 50932 : Japanese Auto Select InternetEncoding
break; } } StrCpyN(pFnt->page[i].szMIMEFont, g_pCPInfo[j].wszDescription, ARRAYSIZE(pFnt->page[i].szMIMEFont)); StrCpyN(pFnt->page[i].szFixedFont, g_pCPInfo[i].wszFixedWidthFont, ARRAYSIZE(pFnt->page[i].szFixedFont)); StrCpyN(pFnt->page[i].szPropFont, g_pCPInfo[i].wszProportionalFont, ARRAYSIZE(pFnt->page[i].szPropFont)); pFnt->page[i].dwFontSize = REGSTR_VAL_FONT_SIZE_DEF; }
// add the name to the listbox
SendMessage(pFnt->hwndNamesLB, LB_ADDSTRING, 0, (LPARAM)pFnt->page[i].szFriendlyName);
// check to see if it is the default code page
if (pFnt->dwDefaultCodePage == g_pCPInfo[i].uiCodePage) { if (LB_ERR == SendMessage(pFnt->hwndNamesLB, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)pFnt->page[i].szFriendlyName)) { // Hack shlwapi problems for Win9x.
CHAR szAnsiString[1024] = {0}; WideCharToMultiByte(CP_ACP, 0, pFnt->page[i].szFriendlyName, -1, szAnsiString, 1024, NULL, NULL); SendMessageA(pFnt->hwndNamesLB, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)szAnsiString); }
SetDlgItemText(pFnt->hDlg, IDC_FONTS_DEFAULT_LANG_TEXT, pFnt->page[i].szFriendlyName); } } } FillCharsetComboBoxes(pFnt, pFnt->dwDefaultCodePage);
pFnt->bChanged = FALSE;
if( g_restrict.fFonts ) { EnableWindow( GetDlgItem( hDlg, IDC_FONTS_PROP_FONT_COMBO ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_FONTS_FIXED_FONT_COMBO ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_FONTS_SIZE_FONT_COMBO ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_FONTS_MIME_FONT_COMBO ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_FONTS_CODE_PAGES_LIST ), FALSE); EnableWindow( GetDlgItem( hDlg, IDC_FONTS_SETDEFAULT_BUTTON ), FALSE);
}
// everything ok
return TRUE;
} // FontsDlgInit()
//
// SaveFontsData()
//
// Save the new fonts settings into regestry
//
void SaveFontsData(LPFONTSDATA pFnt) { HKEY hkeyCodePage; TCHAR szCodePage [MAX_MIMEFACE_NAME];
HKEY hkey; DWORD dw;
// get values from registry
if (RegCreateKeyEx(HKEY_CURRENT_USER, pFnt->lpszKeyPath, NULL, NULL, NULL, KEY_WRITE, NULL, &hkey, &dw) == ERROR_SUCCESS) { UINT i; RegSetValueEx(hkey, REGSTR_VAL_DEFAULT_CODEPAGE, NULL, REG_BINARY, (LPBYTE)&pFnt->dwDefaultCodePage, sizeof(pFnt->dwDefaultCodePage)); for(i = 0; i < g_cCPInfo; i++) { if (g_pCPInfo[i].uiCodePage == g_pCPInfo[i].uiFamilyCodePage) { wnsprintf(szCodePage, ARRAYSIZE(szCodePage), TEXT("%u"), g_pCPInfo[i].uiCodePage); if (RegCreateKeyEx(hkey, szCodePage, NULL, NULL, NULL, KEY_WRITE, NULL, &hkeyCodePage, &dw) == ERROR_SUCCESS) { UINT j;
RegSetValueEx(hkeyCodePage, REGSTR_VAL_FONT_SCRIPT, NULL, REG_SZ, (LPBYTE)&pFnt->page[i].szFriendlyName, (lstrlen(pFnt->page[i].szFriendlyName)+1)*sizeof(TCHAR)); for (j = 0; j < g_cCPInfo; j++) { if (!StrCmpI(g_pCPInfo[j].wszDescription, pFnt->page[i].szMIMEFont)) { dw = g_pCPInfo[j].uiCodePage; break; } } RegSetValueEx(hkeyCodePage, REGSTR_VAL_DEF_INETENCODING, NULL, REG_BINARY, (LPBYTE)&dw, sizeof(dw)); RegSetValueEx(hkeyCodePage, REGSTR_VAL_FIXED_FONT, NULL, REG_SZ, (LPBYTE)pFnt->page[i].szFixedFont, (lstrlen(pFnt->page[i].szFixedFont)+1)*sizeof(TCHAR)); RegSetValueEx(hkeyCodePage, REGSTR_VAL_PROP_FONT, NULL, REG_SZ, (LPBYTE)pFnt->page[i].szPropFont, (lstrlen(pFnt->page[i].szPropFont)+1)*sizeof(TCHAR)); RegSetValueEx(hkeyCodePage, REGSTR_VAL_FONT_SIZE, NULL, REG_BINARY, (LPBYTE)&pFnt->page[i].dwFontSize, sizeof(pFnt->page[i].dwFontSize));
RegCloseKey(hkeyCodePage); } // if RegCreateKeyEx
} // if uiCodePage == uiFamilyCodePage
} // for
RegCloseKey(hkey);
} // if RegCreateKeyEx
} // SaveFontsData()
//
// FontsOnCommand()
//
// Handles WM_COMMAN Dmessage for the Fonts subdialog
//
BOOL FontsOnCommand(LPFONTSDATA pFnt, UINT id, UINT nCmd) { switch(id) { case IDOK: if (pFnt->bChanged) { SaveFontsData(pFnt); // tell MSHTML to pick up changes and update
UpdateAllWindows(); } return TRUE; // exit dialog
case IDCANCEL: return TRUE; // exit dialog
case IDC_FONTS_MIME_FONT_COMBO: if (nCmd==CBN_SELCHANGE) { g_fChangedMime = TRUE; // tell MSHTML that the Mime has changed
} // fall thru...
case IDC_FONTS_PROP_FONT_COMBO: case IDC_FONTS_FIXED_FONT_COMBO: case IDC_FONTS_SIZE_FONT_COMBO: if (nCmd==CBN_SELCHANGE) { UINT i; TCHAR szCodePage[MAX_MIMECP_NAME];
pFnt->bChanged = TRUE; // we need to save
// find the currently selected item in the list box
INT_PTR itmp = SendMessage(pFnt->hwndNamesLB, LB_GETCURSEL, 0, 0); SendMessage(pFnt->hwndNamesLB, LB_GETTEXT, itmp, (LPARAM)szCodePage); // find the code page from the text
for(i=0; i < g_cCPInfo; i++) { if (!StrCmpI(szCodePage, pFnt->page[i].szFriendlyName)) { // grab the new values
GetDlgItemText(pFnt->hDlg, IDC_FONTS_PROP_FONT_COMBO, pFnt->page[i].szPropFont, ARRAYSIZE(pFnt->page[i].szPropFont)); GetDlgItemText(pFnt->hDlg, IDC_FONTS_FIXED_FONT_COMBO, pFnt->page[i].szFixedFont, ARRAYSIZE(pFnt->page[i].szFixedFont)); pFnt->page[i].dwFontSize = (int) SendMessage(pFnt->hwndSizeCB, CB_GETCURSEL, 0, 0); GetDlgItemText(pFnt->hDlg, IDC_FONTS_MIME_FONT_COMBO, pFnt->page[i].szMIMEFont, ARRAYSIZE(pFnt->page[i].szMIMEFont)); break; } } // if we don't find it... we are going to keep the default
ASSERT(i < g_cCPInfo); // something went wrong
} break;
case IDC_FONTS_SETDEFAULT_BUTTON: { UINT i; TCHAR szCodePage[MAX_MIMECP_NAME];
pFnt->bChanged = TRUE; // we need to save
// get the newly selected charset
INT_PTR itmp = SendMessage(pFnt->hwndNamesLB, LB_GETCURSEL, 0, 0); SendMessage(pFnt->hwndNamesLB, LB_GETTEXT, itmp, (LPARAM)szCodePage);
// set the newly selected charset text
SetDlgItemText(pFnt->hDlg, IDC_FONTS_DEFAULT_LANG_TEXT, szCodePage);
// find the code page from the text
for (i = 0; i < g_cCPInfo; i++) { if (!StrCmpI(szCodePage, pFnt->page[i].szFriendlyName)) { pFnt->dwDefaultCodePage = g_pCPInfo[i].uiFamilyCodePage; g_fChangedMime = TRUE; break; } } // if we don't find it... we are going to keep the default
ASSERT(i < g_cCPInfo); // something went wrong
} break; case IDC_FONTS_CODE_PAGES_LIST: if (nCmd==LBN_SELCHANGE) { UINT i; TCHAR szCodePage[MAX_MIMECP_NAME];
INT_PTR itmp = SendMessage(pFnt->hwndNamesLB, LB_GETCURSEL, 0, 0); SendMessage(pFnt->hwndNamesLB, LB_GETTEXT, itmp, (LPARAM)szCodePage); // find the code page from the text
for(i=0; i < g_cCPInfo; i++) { if (!StrCmpI(szCodePage, pFnt->page[i].szFriendlyName)) { FillCharsetComboBoxes(pFnt, g_pCPInfo[i].uiFamilyCodePage); break; } } } break;
} // don't exit dialog
return FALSE; }
//
// FontsDlgProc()
//
// Message handler for the "Fonts" subdialog.
//
INT_PTR CALLBACK FontsDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPFONTSDATA pFnt = (LPFONTSDATA) GetWindowLongPtr(hDlg, DWLP_USER);
switch (uMsg) { case WM_INITDIALOG: return FontsDlgInit(hDlg, (LPTSTR)lParam); case WM_DESTROY: // give back the memory
FreeMimeCsetTable();
// destroy font if we created
SHRemoveDefaultDialogFont(hDlg);
if (pFnt) { if (pFnt->page) LocalFree(pFnt->page); LocalFree(pFnt); } break;
case WM_COMMAND: if (FontsOnCommand(pFnt, LOWORD(wParam), HIWORD(wParam))) EndDialog(hDlg, LOWORD(wParam) == IDOK? 1: 0); break;
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE, HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs); break;
default: return FALSE; } return TRUE; }
//
// EXTERNAL API
//
STDAPI_(INT_PTR) OpenFontsDialog(HWND hDlg, LPCSTR lpszKeyPath) { #ifdef UNICODE
WCHAR wszKeyPath[1024]; MultiByteToWideChar(CP_ACP, 0, (char *)lpszKeyPath, -1, wszKeyPath, ARRAYSIZE(wszKeyPath)); return DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTS_IE4), hDlg, FontsDlgProc, (LPARAM) wszKeyPath); #else
return DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTS_IE4), hDlg, FontsDlgProc, (LPARAM) lpszKeyPath); #endif // UNICODE
}
// provide script based font dialog
STDAPI_(INT_PTR) OpenFontsDialogEx(HWND hDlg, LPCTSTR lpszKeyPath) { INT_PTR nRet = -1; HRESULT hr; BOOL fOLEPresent;
if (hOLE32 != NULL) { fOLEPresent = TRUE; } else { fOLEPresent = _StartOLE32(); }
ASSERT(fOLEPresent); if (fOLEPresent) { ASSERT(IS_VALID_HANDLE(hOLE32, MODULE)); ASSERT(IS_VALID_CODE_PTR(pCoInitialize, PCOINIT));
hr = pCoInitialize(NULL); if (SUCCEEDED(hr)) { nRet = DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_FONTS), hDlg, FontsDlgProcEx, (LPARAM) lpszKeyPath); } }
// Release interface
if (g_pMLFlnk2) { g_pMLFlnk2->Release(); g_pMLFlnk2 = NULL; }
ASSERT(IS_VALID_CODE_PTR(pCoUninitialize, PCOUNIT)); pCoUninitialize();
return nRet; }
|