|
|
/*++
Copyright (c) 1990-1998, Microsoft Corporation All rights reserved.
Module Name:
font.c
Abstract:
This module implements the Win32 font dialog.
Revision History:
--*/
// precompiled headers
#include "precomp.h"
#pragma hdrstop
#include "font.h"
#include "cdids.h"
#include "util.h"
BOOL IsSimplifiedChineseUI(void) { BOOL bRet = FALSE; if (staticIsOS(OS_WIN2000ORGREATER)) // If NT5 or higher, we use system UI Language
{ static LANGID (CALLBACK* pfnGetUserDefaultUILanguage)(void) = NULL;
if (pfnGetUserDefaultUILanguage == NULL) { HMODULE hmod = GetModuleHandle(TEXT("KERNEL32"));
if (hmod) pfnGetUserDefaultUILanguage = (LANGID (CALLBACK*)(void))GetProcAddress(hmod, "GetUserDefaultUILanguage"); } if (pfnGetUserDefaultUILanguage) { LANGID LangID = pfnGetUserDefaultUILanguage();
if (LangID == MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)) bRet = TRUE; } } else // If Win9x and NT4, we use CP_ACP
{ if (936 == GetACP()) bRet = TRUE; }
return bRet; }
#ifdef UNICODE
////////////////////////////////////////////////////////////////////////////
//
// ChooseFontA
//
// ANSI entry point for ChooseFont when this code is built UNICODE.
//
////////////////////////////////////////////////////////////////////////////
BOOL WINAPI ChooseFontA( LPCHOOSEFONTA pCFA) { LPCHOOSEFONTW pCFW; BOOL result; LPBYTE pStrMem; UNICODE_STRING usStyle; ANSI_STRING asStyle; int cchTemplateName = 0; FONTINFO FI;
ZeroMemory(&FI, sizeof(FI));
if (!pCFA) { StoreExtendedError(CDERR_INITIALIZATION); return (FALSE); }
if (pCFA->lStructSize != sizeof(CHOOSEFONTA)) { StoreExtendedError(CDERR_STRUCTSIZE); return (FALSE); }
//
// Setup and allocate CHOOSEFONTW structure.
//
if (!pCFA->lpLogFont && (pCFA->Flags & CF_INITTOLOGFONTSTRUCT)) { StoreExtendedError(CDERR_INITIALIZATION); return (FALSE); }
if (!(pCFW = (LPCHOOSEFONTW)LocalAlloc( LPTR, sizeof(CHOOSEFONTW) + sizeof(LOGFONTW) ))) { StoreExtendedError(CDERR_MEMALLOCFAILURE); return (FALSE); }
pCFW->lStructSize = sizeof(CHOOSEFONTW);
pCFW->lpLogFont = (LPLOGFONTW)((LPCHOOSEFONTW)pCFW + 1);
if (pCFA->Flags & CF_ENABLETEMPLATE) { if (!IS_INTRESOURCE(pCFA->lpTemplateName)) { cchTemplateName = (lstrlenA(pCFA->lpTemplateName) + 1); if (!(pCFW->lpTemplateName = (LPWSTR)LocalAlloc( LPTR, cchTemplateName * sizeof(WCHAR)))) { LocalFree(pCFW); StoreExtendedError(CDERR_MEMALLOCFAILURE); return (FALSE); } else { SHAnsiToUnicode(pCFA->lpTemplateName, (LPWSTR)pCFW->lpTemplateName, cchTemplateName); } } else { (DWORD_PTR)pCFW->lpTemplateName = (DWORD_PTR)pCFA->lpTemplateName; } } else { pCFW->lpTemplateName = NULL; }
if ((pCFA->Flags & CF_USESTYLE) && (!IS_INTRESOURCE(pCFA->lpszStyle))) { asStyle.MaximumLength = LF_FACESIZE; asStyle.Length = (USHORT) (lstrlenA(pCFA->lpszStyle)); if (asStyle.Length >= asStyle.MaximumLength) { asStyle.MaximumLength = asStyle.Length; } } else { asStyle.Length = usStyle.Length = 0; asStyle.MaximumLength = LF_FACESIZE; } usStyle.MaximumLength = asStyle.MaximumLength * sizeof(WCHAR); usStyle.Length = asStyle.Length * sizeof(WCHAR);
if (!(pStrMem = (LPBYTE)LocalAlloc( LPTR, asStyle.MaximumLength + usStyle.MaximumLength ))) { if (cchTemplateName) { LocalFree((LPWSTR)(pCFW->lpTemplateName)); } LocalFree(pCFW); StoreExtendedError(CDERR_MEMALLOCFAILURE); return (FALSE); }
asStyle.Buffer = pStrMem; pCFW->lpszStyle = usStyle.Buffer = (LPWSTR)(asStyle.Buffer + asStyle.MaximumLength);
if ((pCFA->Flags & CF_USESTYLE) && (!IS_INTRESOURCE(pCFA->lpszStyle))) { // strcpy okay, Buffer is allocated to exact size
lstrcpyA(asStyle.Buffer, pCFA->lpszStyle); }
FI.pCF = pCFW; FI.pCFA = pCFA; FI.ApiType = COMDLG_ANSI; FI.pasStyle = &asStyle; FI.pusStyle = &usStyle;
ThunkChooseFontA2W(&FI);
if (result = ChooseFontX(&FI)) { ThunkChooseFontW2A(&FI);
//
// Doesn't say how many characters there are here.
//
if ((pCFA->Flags & CF_USESTYLE) && (!IS_INTRESOURCE(pCFA->lpszStyle))) { LPSTR psz = pCFA->lpszStyle; LPSTR pszT = asStyle.Buffer;
try { while (*psz++ = *pszT++); } except (EXCEPTION_ACCESS_VIOLATION) { //
// Not enough space in the passed in string.
//
*--psz = '\0'; } } }
if (cchTemplateName) { LocalFree((LPWSTR)(pCFW->lpTemplateName)); } LocalFree(pCFW); LocalFree(pStrMem);
return (result); }
#else
////////////////////////////////////////////////////////////////////////////
//
// ChooseFontW
//
// Stub UNICODE function for ChooseFont when this code is built ANSI.
//
////////////////////////////////////////////////////////////////////////////
BOOL WINAPI ChooseFontW( LPCHOOSEFONTW lpCFW) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return (FALSE); }
#endif
////////////////////////////////////////////////////////////////////////////
//
// ChooseFont
//
// The ChooseFont function creates a system-defined dialog box from which
// the user can select a font, a font style (such as bold or italic), a
// point size, an effect (such as strikeout or underline), and a text
// color.
//
////////////////////////////////////////////////////////////////////////////
BOOL WINAPI ChooseFont( LPCHOOSEFONT lpCF) { FONTINFO FI;
ZeroMemory(&FI, sizeof(FI));
FI.pCF = lpCF; FI.ApiType = COMDLG_WIDE;
return ( ChooseFontX(&FI) ); }
////////////////////////////////////////////////////////////////////////////
//
// ChooseFontX
//
// Invokes the font picker dialog, which lets the user specify common
// character format attributes: facename, point size, text color and
// attributes (bold, italic, strikeout or underline).
//
// lpCF - ptr to structure that will hold character attributes
// ApiType - api type (COMDLG_WIDE or COMDLG_ANSI) so that the dialog
// can remember which message to send to the user.
//
// Returns: TRUE - user pressed IDOK
// FALSE - user pressed IDCANCEL
//
////////////////////////////////////////////////////////////////////////////
BOOL ChooseFontX( PFONTINFO pFI) { INT_PTR iRet; // font picker dialog return value
HANDLE hDlgTemplate; // handle to loaded dialog resource
HANDLE hRes; // handle of res. block with dialog
int id; LPCHOOSEFONT lpCF = pFI->pCF; BOOL fAllocLogFont = FALSE; #ifdef UNICODE
UINT uiWOWFlag = 0; #endif
LANGID LangID;
SetCursor(LoadCursor(NULL, IDC_WAIT));
StoreExtendedError(0); g_bUserPressedCancel = FALSE;
if (!lpCF) { StoreExtendedError(CDERR_INITIALIZATION); return (FALSE); }
if (lpCF->lStructSize != sizeof(CHOOSEFONT)) { StoreExtendedError(CDERR_STRUCTSIZE); return (FALSE); }
if (!lpCF->lpLogFont) { if (!(lpCF->lpLogFont = (LPLOGFONT)LocalAlloc(LPTR, sizeof(LOGFONT)))) { StoreExtendedError(CDERR_MEMALLOCFAILURE); return (FALSE); }
fAllocLogFont = TRUE; } //
// Get the process version of the app for later use.
//
pFI->ProcessVersion = GetProcessVersion(0);
//
// Get the default user language id for later use.
//
g_bIsSimplifiedChineseUI = IsSimplifiedChineseUI();
//
// Verify that lpfnHook is not null if CF_ENABLEHOOK is specified.
//
if (lpCF->Flags & CF_ENABLEHOOK) { if (!lpCF->lpfnHook) { if (fAllocLogFont) { LocalFree(lpCF->lpLogFont); lpCF->lpLogFont = NULL; } StoreExtendedError(CDERR_NOHOOK); return (FALSE); } } else { lpCF->lpfnHook = NULL; }
if (lpCF->Flags & CF_ENABLETEMPLATE) { //
// Both custom instance handle and the dialog template name are
// user specified. Locate the dialog resource in the specified
// instance block and load it.
//
if (!(hRes = FindResource(lpCF->hInstance, lpCF->lpTemplateName, RT_DIALOG))) { if (fAllocLogFont) { LocalFree(lpCF->lpLogFont); lpCF->lpLogFont = NULL; } StoreExtendedError(CDERR_FINDRESFAILURE); return (FALSE); } if (!(hDlgTemplate = LoadResource(lpCF->hInstance, hRes))) { if (fAllocLogFont) { LocalFree(lpCF->lpLogFont); lpCF->lpLogFont = NULL; } StoreExtendedError(CDERR_LOADRESFAILURE); return (FALSE); } LangID = GetDialogLanguage(lpCF->hwndOwner, hDlgTemplate); } else if (lpCF->Flags & CF_ENABLETEMPLATEHANDLE) { //
// A handle to the pre-loaded resource has been specified.
//
hDlgTemplate = lpCF->hInstance; LangID = GetDialogLanguage(lpCF->hwndOwner, hDlgTemplate); } else {
id = FORMATDLGORD31; LangID = GetDialogLanguage(lpCF->hwndOwner, NULL);
if (!(hRes = FindResourceExFallback(g_hinst, RT_DIALOG, MAKEINTRESOURCE(id), LangID))) { if (fAllocLogFont) { LocalFree(lpCF->lpLogFont); lpCF->lpLogFont = NULL; } StoreExtendedError(CDERR_FINDRESFAILURE); return (FALSE); } if (!(hDlgTemplate = LoadResource(g_hinst, hRes))) { if (fAllocLogFont) { LocalFree(lpCF->lpLogFont); lpCF->lpLogFont = NULL; } StoreExtendedError(CDERR_LOADRESFAILURE); return (FALSE); } }
//
// Warning! Warning! Warning!
//
// We have to set g_tlsLangID before any call for CDLoadString
//
TlsSetValue(g_tlsLangID, (LPVOID) LangID);
if (LockResource(hDlgTemplate)) { if (lpCF->Flags & CF_ENABLEHOOK) { glpfnFontHook = GETHOOKFN(lpCF); }
#ifdef UNICODE
if (IS16BITWOWAPP(lpCF)) { uiWOWFlag = SCDLG_16BIT; }
iRet = DialogBoxIndirectParamAorW( g_hinst, (LPDLGTEMPLATE)hDlgTemplate, lpCF->hwndOwner, FormatCharDlgProc, (LPARAM)pFI, uiWOWFlag ); #else
iRet = DialogBoxIndirectParam( g_hinst, (LPDLGTEMPLATE)hDlgTemplate, lpCF->hwndOwner, FormatCharDlgProc, (LPARAM)pFI ); #endif
glpfnFontHook = 0;
if (iRet == -1 || ((iRet == 0) && (!g_bUserPressedCancel) && (!GetStoredExtendedError()))) { StoreExtendedError(CDERR_DIALOGFAILURE); } } else { iRet = -1; StoreExtendedError(CDERR_LOCKRESFAILURE); }
if (fAllocLogFont) { LocalFree(lpCF->lpLogFont); lpCF->lpLogFont = NULL; }
return (iRet == IDOK); }
////////////////////////////////////////////////////////////////////////////
//
// SetStyleSelection
//
////////////////////////////////////////////////////////////////////////////
VOID SetStyleSelection( HWND hDlg, LPCHOOSEFONT lpcf, BOOL bInit) { if (!(lpcf->Flags & CF_NOSTYLESEL)) { if (bInit && (lpcf->Flags & CF_USESTYLE)) { PLOGFONT plf; int iSel;
iSel = CBSetSelFromText(GetDlgItem(hDlg, cmb2), lpcf->lpszStyle); if (iSel >= 0) { LPITEMDATA lpItemData = (LPITEMDATA)SendDlgItemMessage( hDlg, cmb2, CB_GETITEMDATA, iSel, 0L ); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { plf = lpItemData->pLogFont;
lpcf->lpLogFont->lfWeight = plf->lfWeight; lpcf->lpLogFont->lfItalic = plf->lfItalic; } else { lpcf->lpLogFont->lfWeight = FW_NORMAL; lpcf->lpLogFont->lfItalic = 0; } } else { lpcf->lpLogFont->lfWeight = FW_NORMAL; lpcf->lpLogFont->lfItalic = 0; } } else { SelectStyleFromLF(GetDlgItem(hDlg, cmb2), lpcf->lpLogFont); }
CBSetTextFromSel(GetDlgItem(hDlg, cmb2)); } }
////////////////////////////////////////////////////////////////////////////
//
// HideDlgItem
//
////////////////////////////////////////////////////////////////////////////
VOID HideDlgItem( HWND hDlg, int id) { EnableWindow(GetDlgItem(hDlg, id), FALSE); ShowWindow(GetDlgItem(hDlg, id), SW_HIDE); }
////////////////////////////////////////////////////////////////////////////
//
// FixComboHeights
//
// Fixes the ownerdraw combo boxes to match the height of the non
// ownerdraw combo boxes.
//
////////////////////////////////////////////////////////////////////////////
VOID FixComboHeights( HWND hDlg) { LPARAM height;
height = SendDlgItemMessage(hDlg, cmb2, CB_GETITEMHEIGHT, (WPARAM)-1, 0L); SendDlgItemMessage(hDlg, cmb1, CB_SETITEMHEIGHT, (WPARAM)-1, height); SendDlgItemMessage(hDlg, cmb3, CB_SETITEMHEIGHT, (WPARAM)-1, height); }
BOOL_PTR HandleFontDlgInitialize(FONTINFO *pFI, HWND hDlg, WPARAM wParam) { TCHAR szPoints[20]; HDC hdc; HWND hWndHelp; // handle to Help... pushbutton
LPCHOOSEFONT pCF;
if (!CDLoadString(g_hinst, iszRegular, (LPTSTR)szRegular, ARRAYSIZE(szRegular)) || !CDLoadString(g_hinst, iszBold, (LPTSTR)szBold, ARRAYSIZE(szBold)) || !CDLoadString(g_hinst, iszItalic, (LPTSTR)szItalic, ARRAYSIZE(szItalic)) || !CDLoadString(g_hinst, iszBoldItalic, (LPTSTR)szBoldItalic, ARRAYSIZE(szBoldItalic))) { StoreExtendedError(CDERR_LOADSTRFAILURE); EndDialog(hDlg, FALSE); return (FALSE); }
pCF = pFI->pCF; if ((pCF->Flags & CF_LIMITSIZE) && (pCF->nSizeMax < pCF->nSizeMin)) { StoreExtendedError(CFERR_MAXLESSTHANMIN); EndDialog(hDlg, FALSE); return (FALSE); }
//
// Save ptr to CHOOSEFONT struct in the dialog's prop list.
// Alloc a temp LOGFONT struct to be used for the length of
// the dialog session, the contents of which will be copied
// over to the final LOGFONT (pointed to by CHOOSEFONT)
// only if <OK> is selected.
//
SetProp(hDlg, FONTPROP, (HANDLE)pFI); glpfnFontHook = 0;
hDlgFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
if (!hbmFont) { hbmFont = LoadBitmaps(BMFONT); }
if (!(pCF->Flags & CF_APPLY)) { HideDlgItem(hDlg, psh3); }
if (!(pCF->Flags & CF_EFFECTS)) { HideDlgItem(hDlg, stc4); HideDlgItem(hDlg, cmb4); } else { short nIndex;
// Fill color list.
FillColorCombo(hDlg); for (nIndex = CCHCOLORS - 1; nIndex > 0; nIndex--) { DWORD dw = (DWORD) SendDlgItemMessage(hDlg, cmb4, CB_GETITEMDATA, nIndex, 0); if (pCF->rgbColors == dw) { break; } } SendDlgItemMessage(hDlg, cmb4, CB_SETCURSEL, nIndex, 0); }
GetWindowRect(GetDlgItem (hDlg, stc5), &pFI->rcText); MapWindowPoints(NULL, hDlg, (POINT *)(&pFI->rcText), 2); FixComboHeights(hDlg);
// Init our LOGFONT.
if (!(pCF->Flags & CF_INITTOLOGFONTSTRUCT)) { InitLF(pCF->lpLogFont); }
// Init effects.
if (!(pCF->Flags & CF_EFFECTS)) { HideDlgItem(hDlg, grp1); HideDlgItem(hDlg, chx1); HideDlgItem(hDlg, chx2); } else { CheckDlgButton(hDlg, chx1, pCF->lpLogFont->lfStrikeOut); CheckDlgButton(hDlg, chx2, pCF->lpLogFont->lfUnderline); }
pFI->nLastFontType = 0;
if (!GetFontFamily( hDlg, pCF->hDC, pCF->Flags, pCF->lpLogFont->lfCharSet )) { StoreExtendedError(CFERR_NOFONTS); if (pCF->Flags & CF_ENABLEHOOK) { glpfnFontHook = GETHOOKFN(pCF); } EndDialog(hDlg, FALSE); return (FALSE); }
if (!(pCF->Flags & CF_NOFACESEL) && *pCF->lpLogFont->lfFaceName) { BOOL bContinueChecking; LPTSTR lpRealFontName, lpSubFontName;
// We want to select the font the user has requested.
int iResult = CBSetSelFromText(GetDlgItem(hDlg, cmb1), pCF->lpLogFont->lfFaceName);
// If iResult == CB_ERR, then we could be working with a
// font subsitution name (eg: MS Shell Dlg).
if (iResult == CB_ERR) { lpSubFontName = pCF->lpLogFont->lfFaceName; }
// Allocate a buffer to store the real font name in.
lpRealFontName = GlobalAlloc(GPTR, MAX_PATH * sizeof(TCHAR));
if (!lpRealFontName) { StoreExtendedError(CDERR_MEMALLOCFAILURE); EndDialog(hDlg, FALSE); return (FALSE); }
// The while loop is necessary in order to resolve
// substitions pointing to subsitutions.
// eg: Helv->MS Shell Dlg->MS Sans Serif
bContinueChecking = TRUE; while ((iResult == CB_ERR) && bContinueChecking) { bContinueChecking = LookUpFontSubs(lpSubFontName, lpRealFontName, MAX_PATH);
// If bContinueChecking is TRUE, then we have a font
// name. Try to select that in the list.
if (bContinueChecking) { iResult = CBSetSelFromText(GetDlgItem(hDlg, cmb1), lpRealFontName ); }
lpSubFontName = lpRealFontName; }
//
// Free our buffer.
//
GlobalFree(lpRealFontName);
//
// Set the edit control text if appropriate.
//
if (iResult != CB_ERR) { CBSetTextFromSel(GetDlgItem(hDlg, cmb1)); } }
hdc = GetDC(NULL);
if (pCF->Flags & CF_NOSCRIPTSEL) { hWndHelp = GetDlgItem(hDlg, cmb5); if (hWndHelp) { CDLoadString( g_hinst, iszNoScript, szPoints, ARRAYSIZE(szPoints)); CBAddScript(hWndHelp, szPoints, DEFAULT_CHARSET); EnableWindow(hWndHelp, FALSE); } DefaultCharset = DEFAULT_CHARSET; pFI->iCharset = DEFAULT_CHARSET; } else if (pCF->Flags & (CF_SELECTSCRIPT | CF_INITTOLOGFONTSTRUCT)) { //
// We could come in here with a bogus value, if the app is
// NOT 4.0, that would result in the bogus charset not
// being found for the facename, and the default would be
// put back again anyway.
//
pFI->iCharset = pCF->lpLogFont->lfCharSet; } else { DefaultCharset = GetTextCharset(hdc); pFI->iCharset = DefaultCharset; }
GetFontStylesAndSizes(hDlg, pFI, pCF, TRUE);
if (!(pCF->Flags & CF_NOSTYLESEL)) { SetStyleSelection(hDlg, pCF, TRUE); }
if (!(pCF->Flags & CF_NOSIZESEL) && pCF->lpLogFont->lfHeight) { GetPointString(szPoints, ARRAYSIZE(szPoints), hdc, pCF->lpLogFont->lfHeight); CBSetSelFromText(GetDlgItem(hDlg, cmb3), szPoints); SetDlgItemText(hDlg, cmb3, szPoints); }
ReleaseDC(NULL, hdc);
//
// Hide the help button if it isn't needed.
//
if (!(pCF->Flags & CF_SHOWHELP)) { ShowWindow(hWndHelp = GetDlgItem(hDlg, pshHelp), SW_HIDE); EnableWindow(hWndHelp, FALSE); }
SendDlgItemMessage(hDlg, cmb1, CB_LIMITTEXT, LF_FACESIZE - 1, 0L); SendDlgItemMessage(hDlg, cmb2, CB_LIMITTEXT, LF_FACESIZE - 1, 0L); SendDlgItemMessage(hDlg, cmb3, CB_LIMITTEXT, 5, 0L);
//
// If hook function has been specified, let it do any additional
// processing of this message.
//
if (pCF->lpfnHook) { BOOL_PTR bRet; LPCFHOOKPROC lpfnHook = GETHOOKFN(pCF); #ifdef UNICODE
if (pFI->ApiType == COMDLG_ANSI) { ThunkChooseFontW2A(pFI); bRet = (*lpfnHook)(hDlg, WM_INITDIALOG, wParam, (LPARAM)pFI->pCFA); ThunkChooseFontA2W(pFI); } else #endif
{ bRet = (*lpfnHook)(hDlg, WM_INITDIALOG, wParam, (LPARAM)pCF); } return (bRet); }
SetCursor(LoadCursor(NULL, IDC_ARROW));
return TRUE;
}
////////////////////////////////////////////////////////////////////////////
//
// FormatCharDlgProc
//
// Message handler for font dlg
//
// chx1 - "underline" checkbox
// chx2 - "strikeout" checkbox
// psh4 - "help" pushbutton
//
// On WM_INITDIALOG message, the choosefont is accessed via lParam,
// and stored in the window's prop list. If a hook function has been
// specified, it is invoked AFTER the current function has processed
// WM_INITDIALOG.
//
// For all other messages, control is passed directly to the hook
// function first. Depending on the latter's return value, the message
// is processed by this function.
//
////////////////////////////////////////////////////////////////////////////
BOOL_PTR CALLBACK FormatCharDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { PFONTINFO pFI; LPCHOOSEFONT pCF = NULL; // ptr to struct passed to ChooseFont()
BOOL_PTR bRet;
//
// If CHOOSEFONT struct has already been accessed and if a hook
// function is specified, let it do the processing first.
//
if (pFI = (PFONTINFO)GetProp(hDlg, FONTPROP)) { if ((pCF = (LPCHOOSEFONT)pFI->pCF) && (pCF->lpfnHook)) { LPCFHOOKPROC lpfnHook = GETHOOKFN(pCF);
if ((bRet = (*lpfnHook)(hDlg, wMsg, wParam, lParam))) { if ((wMsg == WM_COMMAND) && (GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL)) { //
// Set global flag stating that the user pressed cancel.
//
g_bUserPressedCancel = TRUE; } return (bRet); } } } else { if (glpfnFontHook && (wMsg != WM_INITDIALOG) && (bRet = (* glpfnFontHook)(hDlg, wMsg, wParam, lParam))) { return (bRet); } }
switch (wMsg) { case ( WM_INITDIALOG ) : { return HandleFontDlgInitialize((PFONTINFO)lParam, hDlg, wParam); } case ( WM_DESTROY ) : { if (pCF) { RemoveProp(hDlg, FONTPROP); } break; } case ( WM_PAINT ) : { PAINTSTRUCT ps; if (!pFI) { return (FALSE); }
if (BeginPaint(hDlg, &ps)) { DrawSampleText(hDlg, pFI, pCF, ps.hdc); EndPaint(hDlg, &ps); } break; } case ( WM_MEASUREITEM ) : { TEXTMETRIC tm;
HDC hDC = GetDC(hDlg); HFONT hFont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L); if (hFont) { hFont = SelectObject(hDC, hFont); } GetTextMetrics(hDC, &tm); if (hFont) { SelectObject(hDC, hFont); } ReleaseDC(hDlg, hDC);
if (((LPMEASUREITEMSTRUCT)lParam)->itemID != -1) { ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = max(tm.tmHeight, DY_BITMAP); } else { //
// This is for 3.0 only. In 3.1, the CB_SETITEMHEIGHT
// will fix this. Note, this is off by one on 8514.
//
((LPMEASUREITEMSTRUCT)lParam)->itemHeight = tm.tmHeight + 1; }
break; } case ( WM_DRAWITEM ) : { #define lpdis ((LPDRAWITEMSTRUCT)lParam)
if (lpdis->itemID == (UINT)-1) { break; }
if (lpdis->CtlID == cmb4) { DrawColorComboItem(lpdis); } else if (lpdis->CtlID == cmb1) { DrawFamilyComboItem(lpdis); } else { DrawSizeComboItem(lpdis); } break;
#undef lpdis
} case ( WM_SYSCOLORCHANGE ) : { DeleteObject(hbmFont); hbmFont = LoadBitmaps(BMFONT); break; } case ( WM_COMMAND ) : { if (!pFI) { return (FALSE); }
return (ProcessDlgCtrlCommand(hDlg, pFI, GET_WM_COMMAND_ID(wParam, lParam), GET_WM_COMMAND_CMD(wParam, lParam), GET_WM_COMMAND_HWND(wParam, lParam))); break; } case ( WM_HELP ) : { if (IsWindowEnabled(hDlg)) { WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, NULL, HELP_WM_HELP, (ULONG_PTR)(LPVOID)aFontHelpIDs ); } break; } case ( WM_CONTEXTMENU ) : { if (IsWindowEnabled(hDlg)) { WinHelp( (HWND)wParam, NULL, HELP_CONTEXTMENU, (ULONG_PTR)(LPVOID)aFontHelpIDs ); } break; } case ( WM_CHOOSEFONT_GETLOGFONT ) : { Handle_WM_CHOOSEFONT_GETLOGFONT: if (!pFI) { return (FALSE); }
#ifdef UNICODE
if (pFI->ApiType == COMDLG_ANSI) { BOOL bRet; LOGFONT lf;
bRet = FillInFont(hDlg, pFI, pCF, &lf, TRUE);
ThunkLogFontW2A(&lf, (LPLOGFONTA)lParam);
return (bRet); } else #endif
{ return (FillInFont(hDlg, pFI, pCF, (LPLOGFONT)lParam, TRUE)); } } case ( WM_CHOOSEFONT_SETLOGFONT ) : { if (!pFI) { return (FALSE); }
#ifdef UNICODE
if (pFI->ApiType == COMDLG_ANSI) { LOGFONT lf;
ThunkLogFontA2W((LPLOGFONTA)lParam, &lf);
return (SetLogFont(hDlg, pCF, &lf)); } else #endif
{ return (SetLogFont(hDlg, pCF, (LPLOGFONT)lParam)); } break; }
case ( WM_CHOOSEFONT_SETFLAGS ) : { if (pCF) { DWORD dwFlags = pCF->Flags;
pCF->Flags = (DWORD) lParam; SetDlgMsgResult(hDlg, WM_CHOOSEFONT_SETFLAGS, dwFlags); } return (TRUE); } default : { if (wMsg == msgWOWCHOOSEFONT_GETLOGFONT) { goto Handle_WM_CHOOSEFONT_GETLOGFONT; } return (FALSE); } } return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// SelectStyleFromLF
//
// Given a logfont, selects the closest match in the style list.
//
////////////////////////////////////////////////////////////////////////////
void SelectStyleFromLF( HWND hwnd, LPLOGFONT lplf) { int ctr, count, iSel; PLOGFONT plf; int weight_delta, best_weight_delta = 1000; BOOL bIgnoreItalic; LPITEMDATA lpItemData;
count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L); iSel = 0; bIgnoreItalic = FALSE;
TryAgain: for (ctr = 0; ctr < count; ctr++) { lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L);
if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { plf = lpItemData->pLogFont;
if (bIgnoreItalic || (plf->lfItalic && lplf->lfItalic) || (!plf->lfItalic && !lplf->lfItalic)) { weight_delta = lplf->lfWeight - plf->lfWeight; if (weight_delta < 0) { weight_delta = -weight_delta; }
if (weight_delta < best_weight_delta) { best_weight_delta = weight_delta; iSel = ctr; } } } } if (!bIgnoreItalic && iSel == 0) { bIgnoreItalic = TRUE; goto TryAgain; }
SendMessage(hwnd, CB_SETCURSEL, iSel, 0L); }
////////////////////////////////////////////////////////////////////////////
//
// CBSetTextFromSel
//
// Makes the currently selected item the edit text for a combo box.
//
////////////////////////////////////////////////////////////////////////////
int CBSetTextFromSel( HWND hwnd) { int iSel; TCHAR szFace[LF_FACESIZE];
iSel = (int)SendMessage(hwnd, CB_GETCURSEL, 0, 0L); if (iSel >= 0) { // hwnd edits cmb1, cmb2, cmb3 which this is called for have been limited to LF_FACESIZE - 1 or less.
SendMessage(hwnd, CB_GETLBTEXT, iSel, (LONG_PTR)(LPTSTR)szFace); SetWindowText(hwnd, szFace); } return (iSel); }
////////////////////////////////////////////////////////////////////////////
//
// CBSetSelFromText
//
// Sets the selection based on lpszString. Sends notification messages
// if bNotify is TRUE.
//
////////////////////////////////////////////////////////////////////////////
int CBSetSelFromText( HWND hwnd, LPTSTR lpszString) { int iInd;
iInd = CBFindString(hwnd, lpszString);
if (iInd >= 0) { SendMessage(hwnd, CB_SETCURSEL, iInd, 0L); } return (iInd); }
////////////////////////////////////////////////////////////////////////////
//
// CBGetTextAndData
//
// Returns the text and item data for a combo box based on the current
// edit text. If the current edit text does not match anything in the
// listbox, then CB_ERR is returned.
//
////////////////////////////////////////////////////////////////////////////
int CBGetTextAndData( HWND hwnd, LPTSTR lpszString, int iSize, PULONG_PTR lpdw) { LRESULT Result; int iSel;
if (lpszString == NULL) { if ((Result = SendMessage(hwnd, CB_GETITEMDATA, 0, 0L)) < 0) { return ((int) Result); } else { *lpdw = Result; return (0); } }
GetWindowText(hwnd, lpszString, iSize); iSel = CBFindString(hwnd, lpszString); if (iSel < 0) { return (iSel); }
*lpdw = SendMessage(hwnd, CB_GETITEMDATA, iSel, 0L); return (iSel); }
////////////////////////////////////////////////////////////////////////////
//
// CBFindString
//
// Does an exact string find and returns the index.
//
////////////////////////////////////////////////////////////////////////////
int CBFindString( HWND hwnd, LPTSTR lpszString) { return ((int)SendMessage( hwnd, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)(LPCSTR)lpszString )); }
////////////////////////////////////////////////////////////////////////////
//
// GetPointSizeInRange
//
// Ensures that the point size edit field is in range.
//
// Returns: Point Size - of the edit field limitted by MIN/MAX size
// 0 - if the field is empty
//
////////////////////////////////////////////////////////////////////////////
#define GPS_COMPLAIN 0x0001
#define GPS_SETDEFSIZE 0x0002
BOOL GetPointSizeInRange( HWND hDlg, LPCHOOSEFONT lpcf, LPINT pts, WORD wFlags) { TCHAR szBuffer[90]; TCHAR szTitle[90]; int nTmp; int nTmpFr = 0; BOOL bOK;
*pts = 0;
if (GetDlgItemText(hDlg, cmb3, szBuffer, ARRAYSIZE(szBuffer))) { nTmp = GetDlgItemInt(hDlg, cmb3, &bOK, TRUE);
if (!bOK && g_bIsSimplifiedChineseUI) { int ctr; LPTSTR lpsz = szBuffer;
//
// Skip leading white space.
//
while (*lpsz == TEXT(' ')) { lpsz++; } for (ctr = 0; ctr < NUM_ZIHAO; ctr++) { if (!lstrcmpi(lpsz, stZihao[ctr].name)) { bOK = TRUE; nTmp = stZihao[ctr].size; nTmpFr = stZihao[ctr].sizeFr; break; } } }
if (!bOK) { nTmp = 0; } } else if (wFlags & GPS_SETDEFSIZE) { nTmp = DEF_POINT_SIZE; bOK = TRUE; } else { //
// We're just returning with 0 in *pts.
//
return (FALSE); }
//
// Check that we got a number in range.
//
if (wFlags & GPS_COMPLAIN) { if ((lpcf->Flags & CF_LIMITSIZE) && (!bOK || (nTmp > lpcf->nSizeMax) || (nTmp < lpcf->nSizeMin))) { bOK = FALSE; CDLoadString( g_hinst, iszSizeRange, szTitle, ARRAYSIZE(szTitle));
wnsprintf( (LPTSTR)szBuffer, ARRAYSIZE(szBuffer), (LPTSTR)szTitle, lpcf->nSizeMin, lpcf->nSizeMax ); } else if (!bOK) { CDLoadString( g_hinst, iszSizeNumber, szBuffer, ARRAYSIZE(szBuffer)); }
if (!bOK) { GetWindowText(hDlg, szTitle, ARRAYSIZE(szTitle)); MessageBox(hDlg, szBuffer, szTitle, MB_OK | MB_ICONINFORMATION); return (FALSE); } }
*pts = nTmp * 10 + nTmpFr; return (TRUE); }
const struct { int nCharSet; UINT uCodePage; } g_CharSetTransTable[] = { ANSI_CHARSET, 1252, EASTEUROPE_CHARSET, 1250, RUSSIAN_CHARSET, 1251, GREEK_CHARSET, 1253, TURKISH_CHARSET, 1254, HEBREW_CHARSET, 1255, ARABIC_CHARSET, 1256, BALTIC_CHARSET, 1257, VIETNAMESE_CHARSET, 1258, THAI_CHARSET, 874, SHIFTJIS_CHARSET, 932, GB2312_CHARSET, 936, HANGEUL_CHARSET, 949, CHINESEBIG5_CHARSET, 950, JOHAB_CHARSET, 1361, DEFAULT_CHARSET, 0, };
UINT CharsetToCodepage(int iCharset) { int i; for (i=0;i<ARRAYSIZE(g_CharSetTransTable);i++) if (iCharset == g_CharSetTransTable[i].nCharSet) return g_CharSetTransTable[i].uCodePage;
return 0; }
////////////////////////////////////////////////////////////////////////////
//
// ResetSampleFromScript
//
////////////////////////////////////////////////////////////////////////////
BOOL ResetSampleFromScript(HWND hDlg, HWND hwndScript, PFONTINFO pFI) { int iSel; TCHAR szScript[LF_FACESIZE]; LPITEMDATA lpItemData;
if (IsWindow(hwndScript) && IsWindowEnabled(hwndScript)) { iSel = (int)SendMessage(hwndScript, CB_GETCURSEL, 0, 0L); if (iSel >= 0) { lpItemData = (LPITEMDATA)SendMessage( hwndScript, CB_GETITEMDATA, iSel, 0L ); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { pFI->iCharset = lpItemData->nFontType; } } }
if (!CDLoadStringEx(CharsetToCodepage(pFI->iCharset), g_hinst, pFI->iCharset+iszFontSample, szScript, ARRAYSIZE(szScript))) { return (FALSE); }
SetDlgItemText(hDlg, stc5, szScript);
return (TRUE); }
BOOL DoKoreanHack(HWND hwnd) { // HACK: This is only for Korean input. Because Korean Edit control has
// level 3 implementation for DBCS input, we may have a problem if
// focus is moving like below with interim character.
// 0xE0000412 is Korean IME layout id.
//
// TIP keyboard layout is like 0x04120412, so the primary id checking
// more better.
LANGID langId = LOWORD(HandleToUlong(GetKeyboardLayout(0)));
if (PRIMARYLANGID(langId) == LANG_KOREAN) { HIMC hIMC = ImmGetContext(hwnd); LONG cb = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0); ImmReleaseContext(hwnd, hIMC); if (cb > 0) return TRUE; } return FALSE;
}
////////////////////////////////////////////////////////////////////////////
//
// ProcessDlgCtrlCommand
//
// Handles all WM_COMMAND messages for the font dialog.
//
// cmb1 - ID of font facename combobox
// cmb2 - style
// cmb3 - size
// chx1 - "Underline" checkbox
// chx2 - "Strikeout" checkbox
// stc5 - frame around text preview area
// psh4 - button that invokes the Help application
// IDOK - OK button to end dialog, retaining information
// IDCANCEL - button to cancel dialog, not doing anything
//
// Returns: TRUE - if message is processed successfully
// FALSE - otherwise
//
////////////////////////////////////////////////////////////////////////////
BOOL ProcessDlgCtrlCommand(HWND hDlg, PFONTINFO pFI, WORD wId, WORD wCmd, HWND hwnd) { int iSel; LPCHOOSEFONT pCF = (pFI ? pFI->pCF : NULL); TCHAR szStyle[LF_FACESIZE]; LPITEMDATA lpItemData;
if (pCF) { switch (wId) { case ( IDABORT ) : { //
// This is how a hook can cause the dialog to go away.
//
FreeAllItemData(hDlg, pFI); if (pCF->Flags & CF_ENABLEHOOK) { glpfnFontHook = GETHOOKFN(pCF); } // FEATURE: ARULK Why are we returning an HWND anyway?
// The caller (ChooseFontX) expects us to return a BOOL
EndDialog(hDlg, BOOLFROMPTR(hwnd)); break; } case ( IDOK ) : { WORD wCmbId;
// Make sure the focus is set to the OK button. Must do
// this so that when the user presses Enter from one of
// the combo boxes, the kill focus processing is done
// before the data is captured.
SetFocus(GetDlgItem(hDlg, IDOK));
if (!GetPointSizeInRange(hDlg, pCF, &iSel, GPS_COMPLAIN | GPS_SETDEFSIZE )) { PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, cmb3), 1L); break; } pCF->iPointSize = iSel;
FillInFont(hDlg, pFI, pCF, pCF->lpLogFont, TRUE);
if (pCF->Flags & CF_FORCEFONTEXIST) { if (pCF->Flags & CF_NOFACESEL) { wCmbId = cmb1; } else if (pCF->Flags & CF_NOSTYLESEL) { wCmbId = cmb2; } else { wCmbId = 0; }
// Error found.
if (wCmbId) { TCHAR szMsg[160], szTitle[160];
CDLoadString(g_hinst, (wCmbId == cmb1) ? iszNoFaceSel: iszNoStyleSel, szMsg, ARRAYSIZE(szMsg));
GetWindowText(hDlg, szTitle, ARRAYSIZE(szTitle)); MessageBox(hDlg, szMsg, szTitle, MB_OK | MB_ICONINFORMATION ); PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, wCmbId), 1); break; } }
if (pCF->Flags & CF_EFFECTS) { //
// Get currently selected item in color combo box and
// the 32 bit color rgb value associated with it.
//
iSel = (int)SendDlgItemMessage(hDlg, cmb4, CB_GETCURSEL, 0, 0); pCF->rgbColors = (DWORD) SendDlgItemMessage(hDlg, cmb4, CB_GETITEMDATA, iSel, 0); }
//
// Get a valid nFontType.
//
iSel = CBGetTextAndData(GetDlgItem(hDlg, cmb2), szStyle, ARRAYSIZE(szStyle), (PULONG_PTR)&lpItemData ); if (iSel < 0) { lpItemData = 0; iSel = CBGetTextAndData(GetDlgItem(hDlg, cmb2), (LPTSTR)NULL, 0, (PULONG_PTR)&lpItemData); }
if (iSel >= 0 && lpItemData) { pCF->nFontType = (WORD)lpItemData->nFontType; } else { pCF->nFontType = 0; }
if (pCF->Flags & CF_USESTYLE) { // strcpy apparently okay, lpszStyle is inited to a string bigger than szStyle.
// no good way to pass around buffer size anyway.
lstrcpy(pCF->lpszStyle, szStyle); }
goto LeaveDialog; } case ( IDCANCEL ) : { g_bUserPressedCancel = TRUE;
LeaveDialog: FreeAllItemData(hDlg, pFI); if (pCF->Flags & CF_ENABLEHOOK) { glpfnFontHook = GETHOOKFN(pCF); } EndDialog(hDlg, wId == IDOK); break; } case ( cmb1 ) : // facenames combobox
{ switch (wCmd) { case ( CBN_SELCHANGE ) : { TCHAR szPoints[10];
CBSetTextFromSel(hwnd); FillStyles: //
// Try to maintain the current point size and style.
//
GetDlgItemText( hDlg, cmb3, szPoints, ARRAYSIZE(szPoints)); GetFontStylesAndSizes(hDlg, pFI, pCF, FALSE); SetStyleSelection(hDlg, pCF, FALSE);
//
// Preserve the point size selection or put it in
// the edit control if it is not in the list for
// this font.
//
iSel = CBFindString(GetDlgItem(hDlg, cmb3), szPoints); if (iSel < 0) { SetDlgItemText(hDlg, cmb3, szPoints); } else { SendDlgItemMessage(hDlg, cmb3, CB_SETCURSEL, iSel, 0); }
goto DrawSample; break; } case ( CBN_EDITUPDATE ) : { PostMessage( hDlg, WM_COMMAND, GET_WM_COMMAND_MPS(wId, hwnd, CBN_MYEDITUPDATE)); break; } case ( CBN_MYEDITUPDATE ) : { GetWindowText(hwnd, szStyle, ARRAYSIZE(szStyle)); iSel = CBFindString(hwnd, szStyle); if (iSel >= 0) { if (DoKoreanHack(hwnd)) break;
SendMessage(hwnd, CB_SETCURSEL, (WPARAM)iSel, 0); SendMessage(hwnd, CB_SETEDITSEL, 0, 0x0000FFFF); goto FillStyles; } break; } } break; } case ( cmb2 ) : // styles combobox
case ( cmb3 ) : // point sizes combobox
{ switch (wCmd) { case ( CBN_EDITUPDATE ) : { PostMessage( hDlg, WM_COMMAND, GET_WM_COMMAND_MPS(wId,hwnd,CBN_MYEDITUPDATE) ); break; } case ( CBN_MYEDITUPDATE ) : { GetWindowText(hwnd, szStyle, ARRAYSIZE(szStyle)); iSel = CBFindString(hwnd, szStyle); if (iSel >= 0) { if (DoKoreanHack(hwnd)) break;
SendMessage(hwnd, CB_SETCURSEL, iSel, 0); SendMessage(hwnd, CB_SETEDITSEL, 0, 0x0000FFFF); goto DrawSample; } break; } case ( CBN_SELCHANGE ) : { iSel = CBSetTextFromSel(hwnd);
//
// Make the style selection stick.
//
if ((iSel >= 0) && (wId == cmb2)) { LPITEMDATA lpItemData; PLOGFONT plf;
lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, iSel, 0);
if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { plf = lpItemData->pLogFont; pCF->lpLogFont->lfWeight = plf->lfWeight; pCF->lpLogFont->lfItalic = plf->lfItalic; } else { pCF->lpLogFont->lfWeight = FW_NORMAL; pCF->lpLogFont->lfItalic = 0; } }
goto DrawSample; } case ( CBN_KILLFOCUS ) : { DrawSample: #ifdef UNICODE
if (pFI->ApiType == COMDLG_ANSI) { //
// Send special WOW message to indicate the
// font style has changed.
//
LOGFONT lf;
if (FillInFont(hDlg, pFI, pCF, &lf, TRUE)) { memcpy(pCF->lpLogFont, &lf, sizeof(LOGFONT)); ThunkLogFontW2A(pCF->lpLogFont, pFI->pCFA->lpLogFont); SendMessage(hDlg, msgWOWLFCHANGE, 0, (LPARAM)(LPLOGFONT)pFI->pCFA->lpLogFont); } } #endif
//
// Force redraw of preview text for any size change.
//
InvalidateRect(hDlg, &pFI->rcText, FALSE); UpdateWindow(hDlg); } } break; } case ( cmb5 ) : // script combobox
{ //
// Need to change the sample text to reflect the new script.
//
if (wCmd != CBN_SELCHANGE) { break; } if (pFI->ProcessVersion < 0x40000) { // Enabled template also has a cmb5!
return (FALSE); } if (ResetSampleFromScript(hDlg, hwnd, pFI )) { goto FillStyles; } else { break; } } case ( cmb4 ) : { if (wCmd != CBN_SELCHANGE) { break; }
// fall thru...
} case ( chx1 ) : // bold
case ( chx2 ) : // italic
{ goto DrawSample; } case ( pshHelp ) : // help
{ #ifdef UNICODE
if (pFI->ApiType == COMDLG_ANSI) { if (msgHELPA && pCF->hwndOwner) { SendMessage(pCF->hwndOwner, msgHELPA, (WPARAM)hDlg, (LPARAM)pCF); } } else #endif
{ if (msgHELPW && pCF->hwndOwner) { SendMessage(pCF->hwndOwner, msgHELPW, (WPARAM)hDlg, (LPARAM)pCF); } } break; } default : { return (FALSE); } } }
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// CmpFontType
//
// Compares two font types. The values of the font type bits are
// monotonic except the low bit (RASTER_FONTTYPE). After flipping
// that bit the words can be compared directly.
//
// Returns the best of the two.
//
////////////////////////////////////////////////////////////////////////////
int CmpFontType( DWORD ft1, DWORD ft2) { ft1 &= ~(SCREEN_FONTTYPE | PRINTER_FONTTYPE); ft2 &= ~(SCREEN_FONTTYPE | PRINTER_FONTTYPE);
//
// Flip the RASTER_FONTTYPE bit so we can compare.
//
ft1 ^= RASTER_FONTTYPE; ft2 ^= RASTER_FONTTYPE;
return ( (int)ft1 - (int)ft2 ); }
////////////////////////////////////////////////////////////////////////////
//
// FontFamilyEnumProc
//
// nFontType bits
//
// SCALABLE DEVICE RASTER
// (TT) (not GDI) (not scalable)
// 0 0 0 vector, ATM screen
// 0 0 1 GDI raster font
// 0 1 0 PS/LJ III, ATM printer, ATI/LaserMaster
// 0 1 1 non scalable device font
// 1 0 x TT screen font
// 1 1 x TT dev font
//
////////////////////////////////////////////////////////////////////////////
int FontFamilyEnumProc( LPENUMLOGFONTEX lplf, LPNEWTEXTMETRIC lptm, DWORD nFontType, LPENUM_FONT_DATA lpData) { int iItem; DWORD nOldType, nNewType; LPITEMDATA lpItemData; LPITEMDATA lpOldItemData = NULL;
//
// Bounce non TT fonts.
//
if ((lpData->dwFlags & CF_TTONLY) && !(nFontType & TRUETYPE_FONTTYPE)) { return (TRUE); }
//
// Bounce non scalable fonts.
//
if ((lpData->dwFlags & CF_SCALABLEONLY) && (nFontType & RASTER_FONTTYPE)) { return (TRUE); }
//
// Bounce non ANSI fonts.
//
if ((lpData->dwFlags & CF_SCRIPTSONLY) && ((lplf->elfLogFont.lfCharSet == OEM_CHARSET) || (lplf->elfLogFont.lfCharSet == SYMBOL_CHARSET))) { return (TRUE); }
//
// Bounce vertical fonts.
//
if ((lpData->dwFlags & CF_NOVERTFONTS) && (lplf->elfLogFont.lfFaceName[0] == TEXT('@')) ) { return (TRUE); }
//
// Bounce proportional fonts.
//
if ((lpData->dwFlags & CF_FIXEDPITCHONLY) && (lplf->elfLogFont.lfPitchAndFamily & VARIABLE_PITCH)) { return (TRUE); }
//
// Bounce vector fonts.
//
if ((lpData->dwFlags & CF_NOVECTORFONTS) && (lplf->elfLogFont.lfCharSet == OEM_CHARSET)) { return (TRUE); }
if (lpData->bPrinterFont) { nFontType |= PRINTER_FONTTYPE; } else { nFontType |= SCREEN_FONTTYPE; }
//
// Test for a name collision.
//
iItem = CBFindString(lpData->hwndFamily, lplf->elfLogFont.lfFaceName); if (iItem >= 0) { lpItemData = (LPITEMDATA)SendMessage( lpData->hwndFamily, CB_GETITEMDATA, iItem, 0L ); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { nOldType = lpItemData->nFontType; lpOldItemData = lpItemData; } else { nOldType = 0; }
//
// If we don't want screen fonts, but do want printer fonts,
// the old font is a screen font and the new font is a
// printer font, take the new font regardless of other flags.
// Note that this means if a printer wants TRUETYPE fonts, it
// should enumerate them.
//
if (!(lpData->dwFlags & CF_SCREENFONTS) && (lpData->dwFlags & CF_PRINTERFONTS) && (nFontType & PRINTER_FONTTYPE) && (nOldType & SCREEN_FONTTYPE)) { nOldType = 0; // for setting nNewType below
goto SetNewType; }
if (CmpFontType(nFontType, nOldType) > 0) { SetNewType: nNewType = nFontType; SendMessage( lpData->hwndFamily, CB_INSERTSTRING, iItem, (LONG_PTR)(LPTSTR)lplf->elfLogFont.lfFaceName ); SendMessage( lpData->hwndFamily, CB_DELETESTRING, iItem + 1, 0L ); } else { nNewType = nOldType; }
//
// Accumulate the printer/screen ness of these fonts.
//
nNewType |= (nFontType | nOldType) & (SCREEN_FONTTYPE | PRINTER_FONTTYPE);
lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA)); if (!lpItemData) { return (FALSE); } lpItemData->pLogFont = 0L;
lpItemData->nFontType = nNewType; SendMessage( lpData->hwndFamily, CB_SETITEMDATA, iItem, (LONG_PTR)lpItemData );
if (lpOldItemData) { LocalFree(lpOldItemData); }
return (TRUE); }
iItem = (int)SendMessage( lpData->hwndFamily, CB_ADDSTRING, 0, (LONG_PTR)(LPTSTR)lplf->elfLogFont.lfFaceName ); if (iItem < 0) { return (FALSE); }
lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA)); if (!lpItemData) { return (FALSE); } lpItemData->pLogFont = 0L;
#ifdef WINNT
if (lptm->ntmFlags & NTM_PS_OPENTYPE) nFontType |= PS_OPENTYPE_FONTTYPE; if (lptm->ntmFlags & NTM_TYPE1) nFontType |= TYPE1_FONTTYPE; if (lptm->ntmFlags & NTM_TT_OPENTYPE) nFontType |= TT_OPENTYPE_FONTTYPE; #endif // WINNT
lpItemData->nFontType = nFontType;
SendMessage(lpData->hwndFamily, CB_SETITEMDATA, iItem, (LONG_PTR)lpItemData);
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// GetFontFamily
//
// Fills the screen and/or printer font facenames into the font facenames
// combobox depending on the CF_?? flags passed in.
//
// cmb1 is the ID for the font facename combobox
//
// Both screen and printer fonts are listed into the same combobox
//
// Returns: TRUE if successful
// FALSE otherwise.
//
////////////////////////////////////////////////////////////////////////////
BOOL GetFontFamily( HWND hDlg, HDC hDC, DWORD dwEnumCode, UINT iCharset) { ENUM_FONT_DATA data; int iItem, iCount; DWORD nFontType; TCHAR szMsg[200], szTitle[40]; LPITEMDATA lpItemData; LOGFONT lf;
data.hwndFamily = GetDlgItem(hDlg, cmb1); data.dwFlags = dwEnumCode;
//
// This is a bit strange. We have to get all the screen fonts
// so if they ask for the printer fonts we can tell which
// are really printer fonts. This is so we don't list the
// vector and raster fonts as printer device fonts.
//
data.hDC = GetDC(NULL); data.bPrinterFont = FALSE; lf.lfFaceName[0] = CHAR_NULL; lf.lfCharSet = (dwEnumCode & CF_SELECTSCRIPT) ? iCharset : DEFAULT_CHARSET; EnumFontFamiliesEx( data.hDC, &lf, (FONTENUMPROC)FontFamilyEnumProc, (LPARAM)&data, 0L ); ReleaseDC(NULL, data.hDC);
//
// List out printer font facenames.
//
if (dwEnumCode & CF_PRINTERFONTS) { data.hDC = hDC; data.bPrinterFont = TRUE; EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROC)FontFamilyEnumProc, (LPARAM)&data, 0L ); }
//
// Now we have to remove those screen fonts if they didn't
// ask for them.
//
if (!(dwEnumCode & CF_SCREENFONTS)) { iCount = (int)SendMessage(data.hwndFamily, CB_GETCOUNT, 0, 0L);
for (iItem = iCount - 1; iItem >= 0; iItem--) { lpItemData = (LPITEMDATA)SendMessage( data.hwndFamily, CB_GETITEMDATA, iItem, 0L ); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { nFontType = lpItemData->nFontType; } else { nFontType = 0; }
if ((nFontType & (SCREEN_FONTTYPE | PRINTER_FONTTYPE)) == SCREEN_FONTTYPE) { SendMessage(data.hwndFamily, CB_DELETESTRING, iItem, 0L); } } }
//
// For WYSIWYG mode we delete all the fonts that don't exist
// on the screen and the printer.
//
if (dwEnumCode & CF_WYSIWYG) { iCount = (int)SendMessage(data.hwndFamily, CB_GETCOUNT, 0, 0L);
for (iItem = iCount - 1; iItem >= 0; iItem--) { nFontType = ((LPITEMDATA)SendMessage( data.hwndFamily, CB_GETITEMDATA, iItem, 0L ))->nFontType;
if ((nFontType & (SCREEN_FONTTYPE | PRINTER_FONTTYPE)) != (SCREEN_FONTTYPE | PRINTER_FONTTYPE)) { SendMessage(data.hwndFamily, CB_DELETESTRING, iItem, 0L); } } }
if ((int)SendMessage(data.hwndFamily, CB_GETCOUNT, 0, 0L) <= 0) { CDLoadString( g_hinst, iszNoFontsTitle, szTitle, ARRAYSIZE(szTitle)); CDLoadString( g_hinst, iszNoFontsMsg, szMsg, ARRAYSIZE(szMsg)); MessageBox(hDlg, szMsg, szTitle, MB_OK | MB_ICONINFORMATION);
return (FALSE); }
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// CBAddSize
//
////////////////////////////////////////////////////////////////////////////
VOID CBAddSize( HWND hwnd, int pts, LPCHOOSEFONT lpcf) { int iInd; TCHAR szSize[10]; int count, test_size; LPITEMDATA lpItemData;
//
// See if the size is limited.
//
if ((lpcf->Flags & CF_LIMITSIZE) && ((pts > lpcf->nSizeMax) || (pts < lpcf->nSizeMin))) { return; }
//
// Convert the point size to a string.
//
wnsprintf(szSize, ARRAYSIZE(szSize), szPtFormat, pts);
//
// Figure out where in the list the item should be added.
// All values should be in increasing order in the list box.
//
count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L); test_size = -1; for (iInd = 0; iInd < count; iInd++) { lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, iInd, 0L); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { test_size = (int)lpItemData->nFontType; } else { test_size = 0; }
if (pts <= test_size) { break; } }
//
// Don't add duplicates.
//
if (pts == test_size) { return; }
//
// Add the string and the associated item data to the list box.
//
iInd = (int) SendMessage(hwnd, CB_INSERTSTRING, iInd, (LPARAM)szSize); if (iInd >= 0) { lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA)); if (!lpItemData) { return; }
lpItemData->pLogFont = 0L; lpItemData->nFontType = (DWORD)pts; SendMessage(hwnd, CB_SETITEMDATA, iInd, (LONG_PTR)lpItemData); } }
////////////////////////////////////////////////////////////////////////////
//
// CBAddChineseSize
//
////////////////////////////////////////////////////////////////////////////
VOID CBAddChineseSize( HWND hwnd, LPCHOOSEFONT lpcf) { int ctr, iInd = 0; TCHAR szSize[10]; LPITEMDATA lpItemData;
//
// Look at each item in the Zihao structure to see if it should be
// added.
//
for (ctr = 0; ctr < NUM_ZIHAO; ctr++) { //
// See if the size is limited.
//
if ((lpcf->Flags & CF_LIMITSIZE) && ((stZihao[ctr].size > lpcf->nSizeMax) || (stZihao[ctr].size < lpcf->nSizeMin))) { continue; }
//
// Convert the point size to a string.
//
wnsprintf(szSize, ARRAYSIZE(szSize), TEXT("%s"), stZihao[ctr].name);
//
// Add the string and the associated item data to the list box.
//
iInd = (int) SendMessage(hwnd, CB_INSERTSTRING, iInd, (LPARAM)szSize); if (iInd >= 0) { lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA)); if (!lpItemData) { return; }
lpItemData->pLogFont = 0L; lpItemData->nFontType = (DWORD)(stZihao[ctr].size * 10 + stZihao[ctr].sizeFr); SendMessage(hwnd, CB_SETITEMDATA, iInd, (LONG_PTR)lpItemData); } } }
////////////////////////////////////////////////////////////////////////////
//
// InsertStyleSorted
//
// Sort styles by weight first, then by italics.
//
// Returns the index of the place this was inserted.
//
////////////////////////////////////////////////////////////////////////////
int InsertStyleSorted( HWND hwnd, LPTSTR lpszStyle, LPLOGFONT lplf) { int count, ctr; PLOGFONT plf; LPITEMDATA lpItemData;
count = (int) SendMessage(hwnd, CB_GETCOUNT, 0, 0L);
for (ctr = 0; ctr < count; ctr++) { lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { plf = lpItemData->pLogFont;
if (lplf->lfWeight < plf->lfWeight) { break; } else if (lplf->lfWeight == plf->lfWeight) { if (lplf->lfItalic && !plf->lfItalic) { ctr++; } break; } } }
return ((int)SendMessage(hwnd, CB_INSERTSTRING, ctr, (LONG_PTR)lpszStyle)); }
////////////////////////////////////////////////////////////////////////////
//
// CBAddStyle
//
////////////////////////////////////////////////////////////////////////////
PLOGFONT CBAddStyle( HWND hwnd, LPTSTR lpszStyle, DWORD nFontType, LPLOGFONT lplf) { int iItem; PLOGFONT plf; LPITEMDATA lpItemData;
//
// Don't add duplicates.
//
if (CBFindString(hwnd, lpszStyle) >= 0) { return (NULL); }
iItem = (int)InsertStyleSorted(hwnd, lpszStyle, lplf); if (iItem < 0) { return (NULL); }
plf = (PLOGFONT)LocalAlloc(LMEM_FIXED, sizeof(LOGFONT)); if (!plf) { SendMessage(hwnd, CB_DELETESTRING, iItem, 0L); return (NULL); }
*plf = *lplf;
lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA)); if (!lpItemData) { LocalFree(plf); SendMessage(hwnd, CB_DELETESTRING, iItem, 0L); return (NULL); }
lpItemData->pLogFont = plf; lpItemData->nFontType = nFontType; SendMessage(hwnd, CB_SETITEMDATA, iItem, (LONG_PTR)lpItemData);
return (plf); }
////////////////////////////////////////////////////////////////////////////
//
// CBAddScript
//
////////////////////////////////////////////////////////////////////////////
int CBAddScript( HWND hwnd, LPTSTR lpszScript, UINT iCharset) { int iItem; LPITEMDATA lpItemData;
//
// Don't add duplicates or empty strings.
//
if (!IsWindow(hwnd) || !IsWindowEnabled(hwnd) || (!*lpszScript) || (CBFindString(hwnd, lpszScript) >= 0)) { return (-1); }
iItem = (int)SendMessage(hwnd, CB_ADDSTRING, 0, (LONG_PTR)(LPTSTR)lpszScript); if (iItem < 0) { return (-1); }
lpItemData = (LPITEMDATA)LocalAlloc(LMEM_FIXED, sizeof(ITEMDATA)); if (!lpItemData) { SendMessage(hwnd, CB_DELETESTRING, iItem, 0L); return (-1); }
lpItemData->pLogFont = 0L; lpItemData->nFontType = (DWORD)iCharset; SendMessage(hwnd, CB_SETITEMDATA, iItem, (LONG_PTR)lpItemData);
return (iItem); }
////////////////////////////////////////////////////////////////////////////
//
// FillInMissingStyles
//
// Generates simulated forms from those that we have.
//
// reg -> bold
// reg -> italic
// bold || italic || reg -> bold italic
//
////////////////////////////////////////////////////////////////////////////
VOID FillInMissingStyles( HWND hwnd) { PLOGFONT plf, plf_reg, plf_bold, plf_italic; DWORD nFontType; int ctr, count; BOOL bBold, bItalic, bBoldItalic; LPITEMDATA lpItemData; LOGFONT lf;
bBold = bItalic = bBoldItalic = FALSE; plf_reg = plf_bold = plf_italic = NULL;
count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L); for (ctr = 0; ctr < count; ctr++) { lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { plf = lpItemData->pLogFont; nFontType = lpItemData->nFontType; } else { plf = NULL; nFontType = 0; }
if ((nFontType & BOLD_FONTTYPE) && (nFontType & ITALIC_FONTTYPE)) { bBoldItalic = TRUE; } else if (nFontType & BOLD_FONTTYPE) { bBold = TRUE; plf_bold = plf; } else if (nFontType & ITALIC_FONTTYPE) { bItalic = TRUE; plf_italic = plf; } else { plf_reg = plf; } }
nFontType |= SIMULATED_FONTTYPE;
if (!bBold && plf_reg) { lf = *plf_reg; lf.lfWeight = FW_BOLD; CBAddStyle(hwnd, szBold, (nFontType | BOLD_FONTTYPE), &lf); }
if (!bItalic && plf_reg) { lf = *plf_reg; lf.lfItalic = TRUE; CBAddStyle(hwnd, szItalic, (nFontType | ITALIC_FONTTYPE), &lf); } if (!bBoldItalic && (plf_bold || plf_italic || plf_reg)) { if (plf_italic) { plf = plf_italic; } else if (plf_bold) { plf = plf_bold; } else { plf = plf_reg; }
lf = *plf; lf.lfItalic = (BYTE)TRUE; lf.lfWeight = FW_BOLD; CBAddStyle(hwnd, szBoldItalic, (nFontType | BOLD_FONTTYPE | ITALIC_FONTTYPE), &lf); } }
////////////////////////////////////////////////////////////////////////////
//
// FillScalableSizes
//
////////////////////////////////////////////////////////////////////////////
VOID FillScalableSizes( HWND hwnd, LPCHOOSEFONT lpcf) { if (g_bIsSimplifiedChineseUI) { CBAddChineseSize(hwnd, lpcf); }
CBAddSize(hwnd, 8, lpcf); CBAddSize(hwnd, 9, lpcf); CBAddSize(hwnd, 10, lpcf); CBAddSize(hwnd, 11, lpcf); CBAddSize(hwnd, 12, lpcf); CBAddSize(hwnd, 14, lpcf); CBAddSize(hwnd, 16, lpcf); CBAddSize(hwnd, 18, lpcf); CBAddSize(hwnd, 20, lpcf); CBAddSize(hwnd, 22, lpcf); CBAddSize(hwnd, 24, lpcf); CBAddSize(hwnd, 26, lpcf); CBAddSize(hwnd, 28, lpcf); CBAddSize(hwnd, 36, lpcf); CBAddSize(hwnd, 48, lpcf); CBAddSize(hwnd, 72, lpcf); }
////////////////////////////////////////////////////////////////////////////
//
// FontStyleEnumProc
//
////////////////////////////////////////////////////////////////////////////
int FontStyleEnumProc( LPENUMLOGFONTEX lplf, LPNEWTEXTMETRIC lptm, DWORD nFontType, LPENUM_FONT_DATA lpData) { int height, pts; TCHAR szBuf[10];
if (!(nFontType & RASTER_FONTTYPE)) { //
// Vector or TT font.
//
if (lpData->bFillSize && (int)SendMessage(lpData->hwndSizes, CB_GETCOUNT, 0, 0L) == 0) { FillScalableSizes(lpData->hwndSizes, lpData->lpcf); } } else { height = lptm->tmHeight - lptm->tmInternalLeading; pts = GetPointString(szBuf, ARRAYSIZE(szBuf), lpData->hDC, height);
//
// Filter devices same size of multiple styles.
//
if (CBFindString(lpData->hwndSizes, szBuf) < 0) { CBAddSize(lpData->hwndSizes, pts, lpData->lpcf); } }
//
// Keep the printer/screen bits from the family list here too.
//
nFontType |= (lpData->nFontType & (SCREEN_FONTTYPE | PRINTER_FONTTYPE));
#ifdef WINNT
if (lptm->ntmFlags & NTM_PS_OPENTYPE) nFontType |= PS_OPENTYPE_FONTTYPE; if (lptm->ntmFlags & NTM_TYPE1) nFontType |= TYPE1_FONTTYPE; if (lptm->ntmFlags & NTM_TT_OPENTYPE) nFontType |= TT_OPENTYPE_FONTTYPE; #endif // WINNT
if (nFontType & TRUETYPE_FONTTYPE) { //
// If (lptm->ntmFlags & NTM_REGULAR)
//
if (!(lptm->ntmFlags & (NTM_BOLD | NTM_ITALIC))) { nFontType |= REGULAR_FONTTYPE; }
if (lptm->ntmFlags & NTM_ITALIC) { nFontType |= ITALIC_FONTTYPE; }
if (lptm->ntmFlags & NTM_BOLD) { nFontType |= BOLD_FONTTYPE; }
//
// After the LOGFONT.lfFaceName there are 2 more names
// lfFullName[LF_FACESIZE * 2]
// lfStyle[LF_FACESIZE]
//
// If the font has one of the standard style strings in English,
// use the localized string instead.
//
if (!lstrcmp(c_szBoldItalic, lplf->elfStyle) || ((nFontType & BOLD_FONTTYPE) && (nFontType & ITALIC_FONTTYPE))) { CBAddStyle( lpData->hwndStyle, szBoldItalic, nFontType, &lplf->elfLogFont); } else if (!lstrcmp(c_szRegular, lplf->elfStyle) || (nFontType & REGULAR_FONTTYPE)) { CBAddStyle( lpData->hwndStyle, szRegular, nFontType, &lplf->elfLogFont ); } else if (!lstrcmp(c_szBold, lplf->elfStyle) || (nFontType & BOLD_FONTTYPE)) { CBAddStyle( lpData->hwndStyle, szBold, nFontType, &lplf->elfLogFont ); } else if (!lstrcmp(c_szItalic, lplf->elfStyle) || (nFontType & ITALIC_FONTTYPE)) { CBAddStyle( lpData->hwndStyle, szItalic, nFontType, &lplf->elfLogFont); } } else { if ((lplf->elfLogFont.lfWeight >= FW_BOLD) && lplf->elfLogFont.lfItalic) { CBAddStyle( lpData->hwndStyle, szBoldItalic, (nFontType | BOLD_FONTTYPE | ITALIC_FONTTYPE), &lplf->elfLogFont ); } else if (lplf->elfLogFont.lfWeight >= FW_BOLD) { CBAddStyle( lpData->hwndStyle, szBold, (nFontType | BOLD_FONTTYPE), &lplf->elfLogFont ); } else if (lplf->elfLogFont.lfItalic) { CBAddStyle( lpData->hwndStyle, szItalic, (nFontType | ITALIC_FONTTYPE), &lplf->elfLogFont ); } else { CBAddStyle( lpData->hwndStyle, szRegular, (nFontType | REGULAR_FONTTYPE), &lplf->elfLogFont ); } }
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// FreeFonts
//
////////////////////////////////////////////////////////////////////////////
VOID FreeFonts( HWND hwnd) { int ctr, count; LPITEMDATA lpItemData;
count = (int)SendMessage(hwnd, CB_GETCOUNT, 0, 0L);
for (ctr = 0; ctr < count; ctr++) { lpItemData = (LPITEMDATA)SendMessage(hwnd, CB_GETITEMDATA, ctr, 0L); if (!IS_INTRESOURCE(lpItemData) && (lpItemData != (LPITEMDATA)CB_ERR)) { if (!IS_INTRESOURCE(lpItemData->pLogFont)) { LocalFree((HANDLE)lpItemData->pLogFont); } LocalFree((HANDLE)lpItemData); } SendMessage(hwnd, CB_SETITEMDATA, ctr, 0L); }
SendMessage(hwnd, CB_RESETCONTENT, 0, 0L); }
////////////////////////////////////////////////////////////////////////////
//
// FreeAllItemData
//
////////////////////////////////////////////////////////////////////////////
VOID FreeAllItemData( HWND hDlg, PFONTINFO pFI) { HWND hwndTemp;
if (hwndTemp = GetDlgItem(hDlg, cmb1)) { FreeFonts(hwndTemp); } if (hwndTemp = GetDlgItem(hDlg, cmb2)) { FreeFonts(hwndTemp); } if (hwndTemp = GetDlgItem(hDlg, cmb3)) { FreeFonts(hwndTemp); } if (((pFI->ProcessVersion >= 0x40000) || (pFI->pCF->Flags & CF_NOSCRIPTSEL)) && (hwndTemp = GetDlgItem(hDlg, cmb5))) { FreeFonts(hwndTemp); } }
////////////////////////////////////////////////////////////////////////////
//
// InitLF
//
// Initalize a LOGFONT structure to some base generic regular type font.
//
////////////////////////////////////////////////////////////////////////////
VOID InitLF( LPLOGFONT lplf) { HDC hdc;
hdc = GetDC(NULL); lplf->lfEscapement = 0; lplf->lfOrientation = 0; lplf->lfCharSet = (BYTE) GetTextCharset(hdc); lplf->lfOutPrecision = OUT_DEFAULT_PRECIS; lplf->lfClipPrecision = CLIP_DEFAULT_PRECIS; lplf->lfQuality = DEFAULT_QUALITY; lplf->lfPitchAndFamily = DEFAULT_PITCH; lplf->lfItalic = 0; lplf->lfWeight = FW_NORMAL; lplf->lfStrikeOut = 0; lplf->lfUnderline = 0; lplf->lfWidth = 0; // otherwise we get independant x-y scaling
lplf->lfFaceName[0] = 0; lplf->lfHeight = -MulDiv( DEF_POINT_SIZE, GetDeviceCaps(hdc, LOGPIXELSY), POINTS_PER_INCH ); ReleaseDC(NULL, hdc); }
////////////////////////////////////////////////////////////////////////////
//
// FontScriptEnumProc
//
// Gets all of the charsets for the face we are enumerating.
//
// Fills in the script window if any, and sets the script property to
// the correct charset. If there is no window, then the first value
// enumerated is set into the script, and contol returned. If there is a
// window, then the scripts will all be filled in. If the correct value
// is found, then that will be filled in. If its not found, such as when
// the user changes from TimesNewRoman to WingDings, then the caller will
// fill in the property to be the first one.
//
////////////////////////////////////////////////////////////////////////////
int FontScriptEnumProc( LPENUMLOGFONTEX lplf, LPNEWTEXTMETRIC lptm, DWORD nFontType, LPENUM_FONT_DATA lpData) { int script = -1;
//
// Need to check the charsets again as we have a face and are checking
// the family.
//
// Bounce non WANSI fonts.
//
if ( (lpData->dwFlags & CF_SCRIPTSONLY) && ((lplf->elfLogFont.lfCharSet == OEM_CHARSET) || (lplf->elfLogFont.lfCharSet == SYMBOL_CHARSET)) ) { return (TRUE); }
if (lpData->hwndScript) { script = CBAddScript( lpData->hwndScript, lplf->elfScript, lplf->elfLogFont.lfCharSet ); } else if (lpData->iCharset == FONT_INVALID_CHARSET) { lpData->iCharset = lplf->elfLogFont.lfCharSet; }
if (lplf->elfLogFont.lfCharSet == lpData->cfdCharset) { lpData->iCharset = lplf->elfLogFont.lfCharSet; if (script >= 0) { SendMessage(lpData->hwndScript, CB_SETCURSEL, script, 0L); } else if (!(lpData->hwndScript)) { return (FALSE); } }
if (lpData->lpcf->Flags & CF_SELECTSCRIPT) { //
// We just wanted the first one to fill in the script box, now stop.
//
return (FALSE); }
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// GetFontStylesAndSizes
//
// Fills the point sizes combo box with the point sizes for the current
// selection in the facenames combobox.
//
// cmb1 is the ID for the font facename combobox.
//
// Returns: TRUE if successful
// FALSE otherwise.
//
////////////////////////////////////////////////////////////////////////////
BOOL GetFontStylesAndSizes( HWND hDlg, PFONTINFO pFI, LPCHOOSEFONT lpcf, BOOL bForceSizeFill) { ENUM_FONT_DATA data; TCHAR szFace[LF_FACESIZE]; int iSel; int iMapMode; SIZE ViewportExt, WindowExt; LOGFONT lf; LPITEMDATA lpItemData;
FreeFonts(GetDlgItem(hDlg, cmb2));
data.hwndStyle = GetDlgItem(hDlg, cmb2); data.hwndSizes = GetDlgItem(hDlg, cmb3); data.hwndScript = (pFI->ProcessVersion >= 0x40000) ? GetDlgItem(hDlg, cmb5) : NULL; data.dwFlags = lpcf->Flags; data.lpcf = lpcf;
if (!IsWindow(data.hwndScript) || !IsWindowEnabled(data.hwndScript)) { data.hwndScript = NULL; }
iSel = (int)SendDlgItemMessage(hDlg, cmb1, CB_GETCURSEL, 0, 0L); if (iSel < 0) { //
// If we don't have a face name selected we will synthisize
// the standard font styles...
//
InitLF(&lf); CBAddStyle(data.hwndStyle, szRegular, REGULAR_FONTTYPE, &lf); lf.lfWeight = FW_BOLD; CBAddStyle(data.hwndStyle, szBold, BOLD_FONTTYPE, &lf); lf.lfWeight = FW_NORMAL; lf.lfItalic = TRUE; CBAddStyle(data.hwndStyle, szItalic, ITALIC_FONTTYPE, &lf); lf.lfWeight = FW_BOLD; CBAddStyle(data.hwndStyle, szBoldItalic, BOLD_FONTTYPE | ITALIC_FONTTYPE, &lf); FillScalableSizes(data.hwndSizes, lpcf);
return (TRUE); }
lpItemData = (LPITEMDATA)SendDlgItemMessage( hDlg, cmb1, CB_GETITEMDATA, iSel, 0L ); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { data.nFontType = lpItemData->nFontType; } else { data.nFontType = 0; }
data.bFillSize = TRUE;
//
// Free existing contents of font size combo box.
// Also sends CB_RESETCONTENT to control.
//
FreeFonts(data.hwndSizes);
SendMessage(data.hwndStyle, WM_SETREDRAW, FALSE, 0L);
GetDlgItemText(hDlg, cmb1, szFace, ARRAYSIZE(szFace)); lstrcpyn(lf.lfFaceName, szFace, ARRAYSIZE(lf.lfFaceName));
//
// Fill in the script box FIRST. That way we have something to play with.
//
if (data.hwndScript) { SendMessage(data.hwndScript, CB_RESETCONTENT, 0, 0L); } data.iCharset = FONT_INVALID_CHARSET; // impossible charset value.
data.cfdCharset = pFI->iCharset; // pass into enum procs
//
// If no script box exists, then we must get the appropriate charset
// based on the default ansi code page.
//
if (!data.hwndScript) { CHARSETINFO csi; DWORD dwCodePage = GetACP();
if (TranslateCharsetInfo(IntToPtr_(DWORD*, dwCodePage), &csi, TCI_SRCCODEPAGE)) { data.cfdCharset = csi.ciCharset; } }
lf.lfCharSet = (lpcf->Flags & CF_SELECTSCRIPT) ? pFI->iCharset : DEFAULT_CHARSET;
if (lpcf->Flags & CF_SCREENFONTS) { data.hDC = GetDC(NULL); data.bPrinterFont = FALSE; EnumFontFamiliesEx( data.hDC, &lf, (FONTENUMPROC)FontScriptEnumProc, (LPARAM)&data, 0L ); ReleaseDC(NULL, data.hDC); }
if (lpcf->Flags & CF_PRINTERFONTS) { data.hDC = lpcf->hDC; data.bPrinterFont = TRUE; EnumFontFamiliesEx( lpcf->hDC, &lf, (FONTENUMPROC)FontScriptEnumProc, (LPARAM)&data, 0L ); }
//
// Put it back into the main structure.
//
if ((data.iCharset == FONT_INVALID_CHARSET) && (data.hwndScript)) { //
// There MUST be a script window, and we didn't find the charset
// we were looking for.
//
SendMessage(data.hwndScript, CB_SETCURSEL, 0, 0L); lpItemData = (LPITEMDATA)SendMessage( data.hwndScript, CB_GETITEMDATA, 0, 0L ); if (lpItemData && (lpItemData != (LPITEMDATA)CB_ERR)) { data.iCharset = lpItemData->nFontType; } else { data.iCharset = DEFAULT_CHARSET; } } lf.lfCharSet = pFI->iCharset = data.iCharset;
if (lpcf->Flags & CF_SCREENFONTS) { data.hDC = GetDC(NULL); data.bPrinterFont = FALSE; EnumFontFamiliesEx( data.hDC, &lf, (FONTENUMPROC)FontStyleEnumProc, (LPARAM)&data, 0L ); ReleaseDC(NULL, data.hDC); }
if (lpcf->Flags & CF_PRINTERFONTS) { //
// Save and restore the DC's mapping mode (and extents if needed)
// if it's been set by the app to something other than MM_TEXT.
//
if ((iMapMode = GetMapMode(lpcf->hDC)) != MM_TEXT) { if ((iMapMode == MM_ISOTROPIC) || (iMapMode == MM_ANISOTROPIC)) { GetViewportExtEx(lpcf->hDC, &ViewportExt); GetWindowExtEx(lpcf->hDC, &WindowExt); } SetMapMode(lpcf->hDC, MM_TEXT); }
data.hDC = lpcf->hDC; data.bPrinterFont = TRUE; EnumFontFamiliesEx( lpcf->hDC, &lf, (FONTENUMPROC)FontStyleEnumProc, (LPARAM)&data, 0L );
if (iMapMode != MM_TEXT) { SetMapMode(lpcf->hDC, iMapMode); if ((iMapMode == MM_ISOTROPIC) || (iMapMode == MM_ANISOTROPIC)) { SetWindowExtEx( lpcf->hDC, WindowExt.cx, WindowExt.cy, &WindowExt ); SetViewportExtEx( lpcf->hDC, ViewportExt.cx, ViewportExt.cy, &ViewportExt ); } } }
if (!(lpcf->Flags & CF_NOSIMULATIONS)) { FillInMissingStyles(data.hwndStyle); }
SendMessage(data.hwndStyle, WM_SETREDRAW, TRUE, 0L); if (wWinVer < 0x030A) { InvalidateRect(data.hwndStyle, NULL, TRUE); }
if (data.bFillSize) { SendMessage(data.hwndSizes, WM_SETREDRAW, TRUE, 0L); if (wWinVer < 0x030A) { InvalidateRect(data.hwndSizes, NULL, TRUE); } }
ResetSampleFromScript(hDlg, data.hwndScript, pFI);
if (lpcf->Flags & CF_NOSCRIPTSEL) { pFI->iCharset = DEFAULT_CHARSET; }
bForceSizeFill; return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// FillColorCombo
//
// Adds the color name strings to the colors combobox.
//
// cmb4 is the ID for the color combobox.
//
// The color rectangles are drawn later in response to a WM_DRAWITEM msg.
//
////////////////////////////////////////////////////////////////////////////
VOID FillColorCombo( HWND hDlg) { int iT, item; TCHAR szT[CCHCOLORNAMEMAX];
for (iT = 0; iT < CCHCOLORS; ++iT) { *szT = 0; CDLoadString(g_hinst, iszBlack + iT, szT, ARRAYSIZE(szT)); item = (int) SendDlgItemMessage( hDlg, cmb4, CB_INSERTSTRING, iT, (LPARAM)szT ); if (item >= 0) { SendDlgItemMessage(hDlg, cmb4, CB_SETITEMDATA, item, rgbColors[iT]); } } }
////////////////////////////////////////////////////////////////////////////
//
// DrawSizeComboItem
//
////////////////////////////////////////////////////////////////////////////
BOOL DrawSizeComboItem( LPDRAWITEMSTRUCT lpdis) { HDC hDC; DWORD rgbBack, rgbText; TCHAR szFace[LF_FACESIZE + 10]; HFONT hFont;
hDC = lpdis->hDC;
//
// We must first select the dialog control font.
//
if (hDlgFont) { hFont = SelectObject(hDC, hDlgFont); }
if (lpdis->itemState & ODS_SELECTED) { rgbBack = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { rgbBack = SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); }
// this is cmb2 or cmb3 which are limited to LF_FACESIZE - 1 or less
SendMessage( lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, (LONG_PTR)(LPTSTR)szFace );
ExtTextOut( hDC, lpdis->rcItem.left + GetSystemMetrics(SM_CXBORDER), lpdis->rcItem.top, ETO_OPAQUE, &lpdis->rcItem, szFace, lstrlen(szFace), NULL ); //
// Reset font.
//
if (hFont) { SelectObject(hDC, hFont); }
SetTextColor(hDC, rgbText); SetBkColor(hDC, rgbBack);
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// DrawFamilyComboItem
//
////////////////////////////////////////////////////////////////////////////
BOOL DrawFamilyComboItem( LPDRAWITEMSTRUCT lpdis) { HDC hDC, hdcMem; DWORD rgbBack, rgbText; TCHAR szFace[LF_FACESIZE + 10]; HBITMAP hOld; int dy, x; HFONT hFont;
hDC = lpdis->hDC;
//
// We must first select the dialog control font.
//
if (hDlgFont) { hFont = SelectObject(hDC, hDlgFont); }
if (lpdis->itemState & ODS_SELECTED) { rgbBack = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { rgbBack = SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); }
// wsprintf(szFace, "%4.4X", LOWORD(lpdis->itemData));
// this is for cmb1 which is limited to LF_FACESIZE - 1
SendMessage( lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, (LONG_PTR)(LPTSTR)szFace ); ExtTextOut( hDC, lpdis->rcItem.left + DX_BITMAP, lpdis->rcItem.top, ETO_OPAQUE, &lpdis->rcItem, szFace, lstrlen(szFace), NULL ); //
// Reset font.
//
if (hFont) { SelectObject(hDC, hFont); }
hdcMem = CreateCompatibleDC(hDC); if (hdcMem) { if (hbmFont) { LPITEMDATA lpItemData = (LPITEMDATA)lpdis->itemData;
hOld = SelectObject(hdcMem, hbmFont);
if (!lpItemData) { goto SkipBlt; }
if (lpItemData->nFontType & TRUETYPE_FONTTYPE) { #ifdef WINNT
if (lpItemData->nFontType & TT_OPENTYPE_FONTTYPE) x = 2 * DX_BITMAP; else #endif
x = 0; } #ifdef WINNT
else if (lpItemData->nFontType & PS_OPENTYPE_FONTTYPE) { x = 3 * DX_BITMAP; } else if (lpItemData->nFontType & TYPE1_FONTTYPE) { x = 4 * DX_BITMAP; } #endif
else { if ((lpItemData->nFontType & (PRINTER_FONTTYPE | DEVICE_FONTTYPE)) == (PRINTER_FONTTYPE | DEVICE_FONTTYPE)) { //
// This may be a screen and printer font but
// we will call it a printer font here.
//
x = DX_BITMAP; } else { goto SkipBlt; } }
//If it a mirrored DC then the bitmaps are order from right to left.
if (IS_DC_RTL_MIRRORED(hdcMem)) { x = ((NUM_OF_BITMAP - 1) - (x / DX_BITMAP)) * DX_BITMAP; }
dy = ((lpdis->rcItem.bottom - lpdis->rcItem.top) - DY_BITMAP) / 2;
BitBlt( hDC, lpdis->rcItem.left, lpdis->rcItem.top + dy, DX_BITMAP, DY_BITMAP, hdcMem, x, lpdis->itemState & ODS_SELECTED ? DY_BITMAP : 0, SRCCOPY );
SkipBlt: SelectObject(hdcMem, hOld); } DeleteDC(hdcMem); }
SetTextColor(hDC, rgbText); SetBkColor(hDC, rgbBack);
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// DrawColorComboItem
//
// Computes and draws the color combo items.
// Called by main dialog function in response to a WM_DRAWITEM msg.
//
// All color name strings have already been loaded and filled into
// the combobox.
//
// Returns: TRUE if succesful
// FALSE otherwise.
//
////////////////////////////////////////////////////////////////////////////
BOOL DrawColorComboItem( LPDRAWITEMSTRUCT lpdis) { HDC hDC; HBRUSH hbr; int dx, dy; RECT rc; TCHAR szColor[CCHCOLORNAMEMAX]; DWORD rgbBack, rgbText, dw; HFONT hFont;
hDC = lpdis->hDC;
if (lpdis->itemState & ODS_SELECTED) { rgbBack = SetBkColor(hDC, GetSysColor(COLOR_HIGHLIGHT)); rgbText = SetTextColor(hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { rgbBack = SetBkColor(hDC, GetSysColor(COLOR_WINDOW)); rgbText = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); } ExtTextOut( hDC, lpdis->rcItem.left, lpdis->rcItem.top, ETO_OPAQUE, &lpdis->rcItem, NULL, 0, NULL );
//
// Compute coordinates of color rectangle and draw it.
//
dx = GetSystemMetrics(SM_CXBORDER); dy = GetSystemMetrics(SM_CYBORDER); rc.top = lpdis->rcItem.top + dy; rc.bottom = lpdis->rcItem.bottom - dy; rc.left = lpdis->rcItem.left + dx; rc.right = rc.left + 2 * (rc.bottom - rc.top);
dw = (DWORD) SendMessage(lpdis->hwndItem, CB_GETITEMDATA, lpdis->itemID, 0L);
hbr = CreateSolidBrush(dw); if (!hbr) { return (FALSE); }
hbr = SelectObject(hDC, hbr); Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); DeleteObject(SelectObject(hDC, hbr));
//
// Shift the color text right by the width of the color rectangle.
//
*szColor = 0; // items in cmb4 are limited to CCHCOLORNAMEMAX at population time
SendMessage( lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, (LONG_PTR)(LPTSTR)szColor );
//
// We must first select the dialog control font.
//
if (hDlgFont) { hFont = SelectObject(hDC, hDlgFont); }
TextOut( hDC, 2 * dx + rc.right, lpdis->rcItem.top, szColor, lstrlen(szColor) );
//
// Reset font.
//
if (hFont) { SelectObject(hDC, hFont); }
SetTextColor(hDC, rgbText); SetBkColor(hDC, rgbBack);
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// DrawSampleText
//
// Displays sample text with given attributes. Assumes rcText holds the
// coordinates of the area within the frame (relative to dialog client)
// which text should be drawn in.
//
////////////////////////////////////////////////////////////////////////////
VOID DrawSampleText( HWND hDlg, PFONTINFO pFI, LPCHOOSEFONT lpcf, HDC hDC) { DWORD rgbText; DWORD rgbBack; int iItem; HFONT hFont, hTemp; TCHAR szSample[50]; LOGFONT lf; SIZE TextExtent; int len, x, y; TEXTMETRIC tm; BOOL bCompleteFont; RECT rcText;
bCompleteFont = FillInFont(hDlg, pFI, lpcf, &lf, FALSE); lf.lfEscapement = 0; lf.lfOrientation = 0;
hFont = CreateFontIndirect(&lf); if (!hFont) { return; }
hTemp = SelectObject(hDC, hFont);
rgbBack = SetBkColor(hDC, GetSysColor((pFI->ProcessVersion < 0x40000) ? COLOR_WINDOW : COLOR_3DFACE));
if (lpcf->Flags & CF_EFFECTS) { iItem = (int)SendDlgItemMessage(hDlg, cmb4, CB_GETCURSEL, 0, 0L); if (iItem != CB_ERR) { rgbText = (DWORD) SendDlgItemMessage(hDlg, cmb4, CB_GETITEMDATA, iItem, 0L); } else { goto GetWindowTextColor; } } else { GetWindowTextColor: rgbText = GetSysColor(COLOR_WINDOWTEXT); }
rgbText = SetTextColor(hDC, rgbText); if (bCompleteFont) { if (GetUnicodeSampleText(hDC, szSample, ARRAYSIZE(szSample))) { //Empty Body
} else { GetDlgItemText(hDlg, stc5, szSample, ARRAYSIZE(szSample)); } } else { szSample[0] = 0; }
GetTextMetrics(hDC, &tm);
len = lstrlen(szSample); GetTextExtentPoint(hDC, szSample, len, &TextExtent); TextExtent.cy = tm.tmAscent - tm.tmInternalLeading;
rcText = pFI->rcText;
if (pFI->ProcessVersion >= 0x40000) { #ifdef UNICODE
if (!IS16BITWOWAPP(lpcf) || !(lpcf->Flags & CF_ENABLEHOOK)) #endif
{ DrawEdge(hDC, &rcText, EDGE_SUNKEN, BF_RECT | BF_ADJUST); } } #ifndef WINNT
else { //
// We only care about conforming if we have no border.
//
FORWARD_WM_CTLCOLORSTATIC(hDlg, hDC, NULL, SendMessage); } #endif
if ((TextExtent.cx >= (rcText.right - rcText.left)) || (TextExtent.cx <= 0)) { x = rcText.left; } else { x = rcText.left + ((rcText.right - rcText.left) - TextExtent.cx) / 2; }
y = min( rcText.bottom, rcText.bottom - ((rcText.bottom - rcText.top) - TextExtent.cy) / 2);
ExtTextOut( hDC, x, y - (tm.tmAscent), ETO_OPAQUE | ETO_CLIPPED, &rcText, szSample, len, NULL );
SetBkColor(hDC, rgbBack); SetTextColor(hDC, rgbText);
if (hTemp) { DeleteObject(SelectObject(hDC, hTemp)); } }
////////////////////////////////////////////////////////////////////////////
//
// FillInFont
//
// Fills in the LOGFONT structure based on the current selection.
//
// bSetBits - if TRUE the Flags fields in the lpcf are set to indicate
// what parts (face, style, size) are not selected
//
// lplf - LOGFONT filled in upon return
//
// Returns: TRUE if there was an unambiguous selection
// (the LOGFONT is filled in as per the enumeration)
// FALSE there was not a complete selection
// (fields set in the LOGFONT with default values)
//
////////////////////////////////////////////////////////////////////////////
BOOL FillInFont( HWND hDlg, PFONTINFO pFI, LPCHOOSEFONT lpcf, LPLOGFONT lplf, BOOL bSetBits) { HDC hdc; int iSel, id, pts; LPITEMDATA lpItemData; DWORD nFontType; PLOGFONT plf; TCHAR szStyle[LF_FACESIZE]; TCHAR szMessage[128]; BOOL bFontComplete = TRUE; CHARSETINFO csi; DWORD dwCodePage = GetACP();
if (!TranslateCharsetInfo(IntToPtr_(DWORD*, dwCodePage), &csi, TCI_SRCCODEPAGE)) { csi.ciCharset = ANSI_CHARSET; }
InitLF(lplf);
GetDlgItemText( hDlg, cmb1, lplf->lfFaceName, ARRAYSIZE(lplf->lfFaceName)); if (CBFindString(GetDlgItem(hDlg, cmb1), lplf->lfFaceName) >= 0) { if (bSetBits) { lpcf->Flags &= ~CF_NOFACESEL; } } else { bFontComplete = FALSE; if (bSetBits) { lpcf->Flags |= CF_NOFACESEL; } }
iSel = CBGetTextAndData( GetDlgItem(hDlg, cmb2), szStyle, ARRAYSIZE(szStyle), (PULONG_PTR)&lpItemData ); if ((iSel >= 0) && lpItemData) { nFontType = lpItemData->nFontType; plf = lpItemData->pLogFont; *lplf = *plf; // copy the LOGFONT
lplf->lfWidth = 0; // 1:1 x-y scaling
if (!lstrcmp(lplf->lfFaceName, TEXT("Small Fonts"))) { lplf->lfCharSet = (BYTE) csi.ciCharset; } if (bSetBits) { lpcf->Flags &= ~CF_NOSTYLESEL; } } else { //
// Even if the style is invalid, we still need the charset.
//
iSel = CBGetTextAndData( GetDlgItem(hDlg, cmb2), (LPTSTR)NULL, 0, (PULONG_PTR)&lpItemData ); if ((iSel >= 0) && lpItemData) { nFontType = lpItemData->nFontType; plf = lpItemData->pLogFont; *lplf = *plf; // copy the LOGFONT
lplf->lfWidth = 0; // 1:1 x-y scaling
if (!lstrcmp(lplf->lfFaceName, TEXT("Small Fonts")) || !lstrcmp(lplf->lfFaceName, TEXT("Lucida Sans Unicode"))) { lplf->lfCharSet = (BYTE) csi.ciCharset; } }
bFontComplete = FALSE; if (bSetBits) { lpcf->Flags |= CF_NOSTYLESEL; } nFontType = 0; }
//
// Now make sure the size is in range; pts will be 0 if not.
//
GetPointSizeInRange(hDlg, lpcf, &pts, 0);
hdc = GetDC(NULL); if (pts) { if (g_bIsSimplifiedChineseUI) { UINT iHeight; int iLogPixY = GetDeviceCaps(hdc, LOGPIXELSY); int ptsfr = pts % 10; // fractional point size
pts /= 10; // real point size
iHeight = pts * iLogPixY; if (ptsfr) { iHeight += MulDiv(ptsfr, iLogPixY, 10); } lplf->lfHeight = -((int)((iHeight + POINTS_PER_INCH / 2) / POINTS_PER_INCH)); } else { pts /= 10; lplf->lfHeight = -MulDiv( pts, GetDeviceCaps(hdc, LOGPIXELSY), POINTS_PER_INCH ); } if (bSetBits) { lpcf->Flags &= ~CF_NOSIZESEL; } } else { lplf->lfHeight = -MulDiv( DEF_POINT_SIZE, GetDeviceCaps(hdc, LOGPIXELSY), POINTS_PER_INCH ); bFontComplete = FALSE; if (bSetBits) { lpcf->Flags |= CF_NOSIZESEL; } } ReleaseDC(NULL, hdc);
//
// And the attributes we control.
//
lplf->lfStrikeOut = (BYTE)IsDlgButtonChecked(hDlg, chx1); lplf->lfUnderline = (BYTE)IsDlgButtonChecked(hDlg, chx2); lplf->lfCharSet = (BYTE) pFI->iCharset;
if (nFontType != pFI->nLastFontType) { if (lpcf->Flags & CF_PRINTERFONTS) { if (nFontType & SIMULATED_FONTTYPE) { id = iszSynth; } #ifdef WINNT
else if (nFontType & TT_OPENTYPE_FONTTYPE) { id = iszTTOpenType; } else if (nFontType & PS_OPENTYPE_FONTTYPE) { id = iszPSOpenType; } else if (nFontType & TYPE1_FONTTYPE) { id = iszType1; } #endif
else if (nFontType & TRUETYPE_FONTTYPE) { id = iszTrueType; } else if ((nFontType & (PRINTER_FONTTYPE | DEVICE_FONTTYPE)) == (PRINTER_FONTTYPE | DEVICE_FONTTYPE)) { //
// May be both screen and printer (ATM) but we'll just
// call this a printer font.
//
id = iszPrinterFont; } else if ((nFontType & (PRINTER_FONTTYPE | SCREEN_FONTTYPE)) == SCREEN_FONTTYPE) { id = iszGDIFont; } else { szMessage[0] = 0; goto SetText; } CDLoadString( g_hinst, id, szMessage, ARRAYSIZE(szMessage)); SetText: SetDlgItemText(hDlg, stc6, szMessage); } }
pFI->nLastFontType = nFontType;
return (bFontComplete); }
////////////////////////////////////////////////////////////////////////////
//
// SetLogFont
//
// Sets the current selection based on the LOGFONT structure passed in.
//
// lpcf - CHOOSEFONT structure for the current dialog
// lplf - LOGFONT filled in upon return
//
// Returns: TRUE if there was an unambiguous selection
// (the LOGFONT is filled in as per the enumeration)
// FALSE there was not a complete selection
// (fields set in the LOGFONT with default values)
//
////////////////////////////////////////////////////////////////////////////
BOOL SetLogFont( HWND hDlg, LPCHOOSEFONT lpcf, LPLOGFONT lplf) { *(lpcf->lpLogFont) = *lplf; // Copies data & FaceName
FORWARD_WM_COMMAND( hDlg, cmb1, GetDlgItem(hDlg, cmb1), CBN_SELCHANGE, SendMessage ); return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// TermFont
//
// Release any data required by functions in this module.
//
////////////////////////////////////////////////////////////////////////////
VOID TermFont() { if (hbmFont) { DeleteObject(hbmFont); } }
////////////////////////////////////////////////////////////////////////////
//
// GetPointString
//
// Converts font height into a string of digits representing point size.
//
// Returns: Size in points and fills in buffer with string
//
////////////////////////////////////////////////////////////////////////////
int GetPointString( LPTSTR buf, UINT cch, HDC hDC, int height) { int pts;
if (g_bIsSimplifiedChineseUI) { int ptsfr, iLogPixY, ctr; long lpts; BOOL IsZihao = FALSE;
lpts = ((height < 0) ? -height : height) * 72;
//
// Get real point size.
//
pts = (int)(lpts / (iLogPixY = GetDeviceCaps(hDC, LOGPIXELSY)));
//
// Get fractional point size.
//
ptsfr = MulDiv((int)(lpts % iLogPixY), 10, iLogPixY);
//
// See if it's Zihao.
//
for (ctr = 0; ctr < NUM_ZIHAO; ctr++) { if ((pts == stZihao[ctr].size) && (abs(ptsfr - stZihao[ctr].sizeFr) <= 3)) { IsZihao = TRUE; wnsprintf(buf, cch, TEXT("%s"), stZihao[ctr].name); break; } } if (!IsZihao) { pts = MulDiv((height < 0) ? -height : height, 72, iLogPixY); for (ctr = 0; ctr < NUM_ZIHAO; ctr++) { if ((pts == stZihao[ctr].size) && (!stZihao[ctr].sizeFr)) { IsZihao = TRUE; wnsprintf(buf, cch, TEXT("%s"), stZihao[ctr].name); break; } } } if (!IsZihao) { wnsprintf(buf, cch, szPtFormat, pts); } } else { pts = MulDiv( (height < 0) ? -height : height, 72, GetDeviceCaps(hDC, LOGPIXELSY) ); wnsprintf(buf, cch, szPtFormat, pts); }
return (pts); }
////////////////////////////////////////////////////////////////////////////
//
// FlipColor
//
////////////////////////////////////////////////////////////////////////////
DWORD FlipColor( DWORD rgb) { return ( RGB(GetBValue(rgb), GetGValue(rgb), GetRValue(rgb)) ); }
////////////////////////////////////////////////////////////////////////////
//
// LoadBitmaps
//
// This routine loads DIB bitmaps, and "fixes up" their color tables
// so that we get the desired result for the device we are on.
//
// This routine requires:
// the DIB is a 16 color DIB authored with the standard windows colors
// bright blue (00 00 FF) is converted to the background color
// light grey (C0 C0 C0) is replaced with the button face color
// dark grey (80 80 80) is replaced with the button shadow color
//
// This means you can't have any of these colors in your bitmap.
//
////////////////////////////////////////////////////////////////////////////
#define BACKGROUND 0x000000FF // bright blue
#define BACKGROUNDSEL 0x00FF00FF // bright blue
#define BUTTONFACE 0x00C0C0C0 // bright grey
#define BUTTONSHADOW 0x00808080 // dark grey
HBITMAP LoadBitmaps( int id) { HDC hdc; HANDLE h; DWORD *p; BYTE *lpBits; HANDLE hRes; LPBITMAPINFOHEADER lpBitmapInfo; int numcolors; DWORD rgbSelected; DWORD rgbUnselected; HBITMAP hbm; UINT cbBitmapSize; LPBITMAPINFOHEADER lpBitmapData;
rgbSelected = FlipColor(GetSysColor(COLOR_HIGHLIGHT)); rgbUnselected = FlipColor(GetSysColor(COLOR_WINDOW));
h = FindResource(g_hinst, MAKEINTRESOURCE(id), RT_BITMAP); hRes = LoadResource(g_hinst, h);
//
// Lock the bitmap and get a pointer to the color table.
//
lpBitmapInfo = (LPBITMAPINFOHEADER)LockResource(hRes);
if (!lpBitmapInfo) { return (FALSE); }
//
// Lock the bitmap data and make a copy of it for the mask and the
// bitmap.
//
cbBitmapSize = SizeofResource(g_hinst, h);
lpBitmapData = (LPBITMAPINFOHEADER)LocalAlloc(LPTR, cbBitmapSize);
if (!lpBitmapData) { return (NULL); }
memcpy((TCHAR *)lpBitmapData, (TCHAR *)lpBitmapInfo, cbBitmapSize);
p = (DWORD *)((LPTSTR)(lpBitmapData) + lpBitmapData->biSize);
//
// Search for the Solid Blue entry and replace it with the current
// background RGB.
//
numcolors = 16;
while (numcolors-- > 0) { if (*p == BACKGROUND) { *p = rgbUnselected; } else if (*p == BACKGROUNDSEL) { *p = rgbSelected; } #if 0
else if (*p == BUTTONFACE) { *p = FlipColor(GetSysColor(COLOR_BTNFACE)); } else if (*p == BUTTONSHADOW) { *p = FlipColor(GetSysColor(COLOR_BTNSHADOW)); } #endif
p++; }
//
// First skip over the header structure.
//
lpBits = (BYTE *)(lpBitmapData + 1);
//
// Skip the color table entries, if any.
//
lpBits += (1 << (lpBitmapData->biBitCount)) * sizeof(RGBQUAD);
//
// Create a color bitmap compatible with the display device.
//
hdc = GetDC(NULL); hbm = CreateDIBitmap( hdc, lpBitmapData, (DWORD)CBM_INIT, lpBits, (LPBITMAPINFO)lpBitmapData, DIB_RGB_COLORS ); ReleaseDC(NULL, hdc);
LocalFree(lpBitmapData);
return (hbm); }
////////////////////////////////////////////////////////////////////////////
//
// LookUpFontSubs
//
// Looks in the font substitute list for a real font name.
//
// lpSubFontName - substitute font name
// lpRealFontName - real font name buffer
//
// Returns: TRUE if lpRealFontName is filled in
// FALSE if not
//
////////////////////////////////////////////////////////////////////////////
BOOL LookUpFontSubs(LPCTSTR lpSubFontName, LPTSTR lpRealFontName, UINT cch) { LONG lResult; HKEY hKey; TCHAR szValueName[MAX_PATH]; TCHAR szValueData[MAX_PATH]; DWORD cchValueSize; DWORD dwIndex = 0; DWORD dwType, cbSize;
//
// Open the font substitution's key.
//
lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, KEY_FONT_SUBS, 0, KEY_READ, &hKey );
if (lResult != ERROR_SUCCESS) { return (FALSE); }
//
// Loop through the values in the key
//
cchValueSize = ARRAYSIZE(szValueName); cbSize = sizeof(szValueData); while (RegEnumValue( hKey, dwIndex, szValueName, &cchValueSize, NULL, &dwType, (LPBYTE)szValueData, &cbSize ) == ERROR_SUCCESS) { //
// If the value name matches the requested font name, then
// copy the real font name to the output buffer.
//
if (!lstrcmpi(szValueName, lpSubFontName)) { lstrcpyn(lpRealFontName, szValueData, cch); RegCloseKey(hKey); return (TRUE); }
//
// Re-initialize for the next time through the loop.
//
cchValueSize = ARRAYSIZE(szValueName); cbSize = sizeof(szValueData); dwIndex++; }
//
// Clean up.
//
*lpRealFontName = CHAR_NULL; RegCloseKey(hKey); return (FALSE); }
////////////////////////////////////////////////////////////////////////////
//
// GetUnicodeSampleText
//
// Gets the sample text for the font selected in the HDC
//
////////////////////////////////////////////////////////////////////////////
BOOL GetUnicodeSampleText(HDC hdc, LPTSTR lpString, int cchMaxCount) {
FONTSIGNATURE sig; int i, j; int iLang = 0; int base = 0; int mask;
if (!lpString || !cchMaxCount) { return FALSE; }
//Make sure return value is nulled
lpString[0] = 0;
//First Get the Font Signature
GetTextCharsetInfo(hdc, &sig, 0);
//Select the first unicode range supported by this font
//For each of Unicode dwords
for (i=0; i < 4; i++) { // See if a particular bit is set
for (j=0; j < sizeof(DWORD) * 8 ; j++) { mask = 1 << j;
if (sig.fsUsb[i] & mask) { //if set the get the language id for that bit
iLang = base + j; goto LoadString; } } base +=32; }
LoadString: //Do we have lang id and string for that language ?
if (iLang && LoadString(g_hinst, iszUnicode + iLang, lpString, cchMaxCount)) { return TRUE; }
return FALSE; }
/*========================================================================*/ /* Ansi->Unicode Thunk routines */ /*========================================================================*/
#ifdef UNICODE
////////////////////////////////////////////////////////////////////////////
//
// ThunkChooseFontA2W
//
////////////////////////////////////////////////////////////////////////////
void ThunkChooseFontA2W( PFONTINFO pFI) { LPCHOOSEFONTW pCFW = pFI->pCF; LPCHOOSEFONTA pCFA = pFI->pCFA;
pCFW->hwndOwner = pCFA->hwndOwner; pCFW->lCustData = pCFA->lCustData;
pCFW->Flags = pCFA->Flags;
//
// !!! hack, should not be based on flag value, since this could happen
// at any time.
//
if (pCFA->Flags & CF_INITTOLOGFONTSTRUCT) { ThunkLogFontA2W( pCFA->lpLogFont, pCFW->lpLogFont); }
pCFW->hInstance = pCFA->hInstance; pCFW->lpfnHook = pCFA->lpfnHook;
if (pCFW->Flags & CF_PRINTERFONTS) { pCFW->hDC = pCFA->hDC; }
if (pCFW->Flags & CF_USESTYLE) { RtlAnsiStringToUnicodeString(pFI->pusStyle, pFI->pasStyle, FALSE); }
pCFW->nSizeMin = pCFA->nSizeMin; pCFW->nSizeMax = pCFA->nSizeMax; pCFW->rgbColors = pCFA->rgbColors;
pCFW->iPointSize = pCFA->iPointSize; pCFW->nFontType = pCFA->nFontType;
}
////////////////////////////////////////////////////////////////////////////
//
// ThunkChooseFontW2A
//
////////////////////////////////////////////////////////////////////////////
void ThunkChooseFontW2A( PFONTINFO pFI) { LPCHOOSEFONTA pCFA = pFI->pCFA; LPCHOOSEFONTW pCFW = pFI->pCF;
ThunkLogFontW2A( pCFW->lpLogFont, pCFA->lpLogFont);
pCFA->hInstance = pCFW->hInstance; pCFA->lpfnHook = pCFW->lpfnHook;
if (pCFA->Flags & CF_USESTYLE) { pFI->pusStyle->Length = (USHORT)((lstrlen(pFI->pusStyle->Buffer) + 1) * sizeof(WCHAR)); RtlUnicodeStringToAnsiString(pFI->pasStyle, pFI->pusStyle, FALSE); }
pCFA->Flags = pCFW->Flags; pCFA->nSizeMin = pCFW->nSizeMin; pCFA->nSizeMax = pCFW->nSizeMax; pCFA->rgbColors = pCFW->rgbColors;
pCFA->iPointSize = pCFW->iPointSize; pCFA->nFontType = pCFW->nFontType; pCFA->lCustData = pCFW->lCustData;
}
////////////////////////////////////////////////////////////////////////////
//
// ThunkLogFontA2W
//
////////////////////////////////////////////////////////////////////////////
VOID ThunkLogFontA2W( LPLOGFONTA lpLFA, LPLOGFONTW lpLFW) { lpLFW->lfHeight = lpLFA->lfHeight; lpLFW->lfWidth = lpLFA->lfWidth; lpLFW->lfEscapement = lpLFA->lfEscapement; lpLFW->lfOrientation = lpLFA->lfOrientation; lpLFW->lfWeight = lpLFA->lfWeight; lpLFW->lfItalic = lpLFA->lfItalic; lpLFW->lfUnderline = lpLFA->lfUnderline; lpLFW->lfStrikeOut = lpLFA->lfStrikeOut; lpLFW->lfCharSet = lpLFA->lfCharSet; lpLFW->lfOutPrecision = lpLFA->lfOutPrecision; lpLFW->lfClipPrecision = lpLFA->lfClipPrecision; lpLFW->lfQuality = lpLFA->lfQuality; lpLFW->lfPitchAndFamily = lpLFA->lfPitchAndFamily;
SHAnsiToUnicode(lpLFA->lfFaceName, lpLFW->lfFaceName, ARRAYSIZE(lpLFW->lfFaceName)); }
////////////////////////////////////////////////////////////////////////////
//
// ThunkLogFontW2A
//
////////////////////////////////////////////////////////////////////////////
VOID ThunkLogFontW2A( LPLOGFONTW lpLFW, LPLOGFONTA lpLFA) {
if (lpLFW && lpLFA) { lpLFA->lfHeight = lpLFW->lfHeight; lpLFA->lfWidth = lpLFW->lfWidth; lpLFA->lfEscapement = lpLFW->lfEscapement; lpLFA->lfOrientation = lpLFW->lfOrientation; lpLFA->lfWeight = lpLFW->lfWeight; lpLFA->lfItalic = lpLFW->lfItalic; lpLFA->lfUnderline = lpLFW->lfUnderline; lpLFA->lfStrikeOut = lpLFW->lfStrikeOut; lpLFA->lfCharSet = lpLFW->lfCharSet; lpLFA->lfOutPrecision = lpLFW->lfOutPrecision; lpLFA->lfClipPrecision = lpLFW->lfClipPrecision; lpLFA->lfQuality = lpLFW->lfQuality; lpLFA->lfPitchAndFamily = lpLFW->lfPitchAndFamily;
SHUnicodeToAnsi(lpLFW->lfFaceName, lpLFA->lfFaceName, ARRAYSIZE(lpLFA->lfFaceName)); } }
#ifdef WINNT
////////////////////////////////////////////////////////////////////////////
//
// Ssync_ANSI_UNICODE_CF_For_WOW
//
// Function to allow NT WOW to keep the ANSI & UNICODE versions of
// the CHOOSEFONT structure in ssync as required by many 16-bit apps.
// See notes for Ssync_ANSI_UNICODE_Struct_For_WOW() in dlgs.c.
//
////////////////////////////////////////////////////////////////////////////
VOID Ssync_ANSI_UNICODE_CF_For_WOW( HWND hDlg, BOOL f_ANSI_to_UNICODE) { PFONTINFO pFI;
if (pFI = (PFONTINFO)GetProp(hDlg, FONTPROP)) { if (pFI->pCF && pFI->pCFA) { if (f_ANSI_to_UNICODE) { ThunkChooseFontA2W(pFI); } else { ThunkChooseFontW2A(pFI); } } } }
#endif // WINNT
#endif // UNICODE
|