462 lines
14 KiB
C++
462 lines
14 KiB
C++
|
/* CUSTFONT.C
|
||
|
**
|
||
|
** Copyright (C) Microsoft, 1993, All Rights Reserved.
|
||
|
**
|
||
|
** History:
|
||
|
**
|
||
|
*/
|
||
|
|
||
|
#include "priv.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
static struct
|
||
|
{
|
||
|
UINT wWidth;
|
||
|
UINT wHeight;
|
||
|
UINT wSizeFontId;
|
||
|
|
||
|
UINT wStartPos;
|
||
|
UINT wStartPix;
|
||
|
} g;
|
||
|
|
||
|
static UINT g_iCurPercent;
|
||
|
static RECT g_rcRuler;
|
||
|
static TCHAR g_szRulerDirections[200];
|
||
|
static TCHAR g_szSample[100];
|
||
|
static TCHAR g_szSampleFace[32];
|
||
|
|
||
|
static int g_cxRulerDirections;
|
||
|
|
||
|
static BOOL g_bTypeTimer = FALSE;
|
||
|
|
||
|
static TCHAR szPctD[] = TEXT("%d");
|
||
|
static TCHAR szPercentNum[] = TEXT("%d%%");
|
||
|
|
||
|
#define NUM_DEFPERCENTS 5
|
||
|
static UINT g_DefaultPercents[NUM_DEFPERCENTS] = {75, 100, 125, 150, 200};
|
||
|
|
||
|
#define MAX_PERCENT 500
|
||
|
#define MIN_PERCENT 20
|
||
|
|
||
|
#define GETPERCENT(dpi) ((dpi * 100 + 50) / 96)
|
||
|
#define GETDPI(percent) ((percent * 96 + 48) /100)
|
||
|
|
||
|
#define UPDATE_CURPER 0x0001
|
||
|
#define UPDATE_COMBO 0x0002
|
||
|
#define UPDATE_SAMPLE 0x0004
|
||
|
#define UPDATE_RULER 0x0008
|
||
|
#define UPDATE_ALL 0x000F
|
||
|
|
||
|
void NEAR PASCAL DrawRuler(HWND hDlg, LPDRAWITEMSTRUCT lpdis)
|
||
|
{
|
||
|
int nFact;
|
||
|
RECT rc;
|
||
|
HDC hdc;
|
||
|
int nPixInch;
|
||
|
int i, j;
|
||
|
TCHAR szTemp[10];
|
||
|
int nOldMode;
|
||
|
|
||
|
hdc = lpdis->hDC;
|
||
|
nOldMode = SetBkMode(hdc, TRANSPARENT);
|
||
|
// use g_rcRuler to draw the ruler. it's already been spaced
|
||
|
rc = g_rcRuler;
|
||
|
|
||
|
// first, draw the directions
|
||
|
i = rc.left + ((rc.right - rc.left) - g_cxRulerDirections)/2;
|
||
|
|
||
|
nPixInch = GETDPI(g_iCurPercent);
|
||
|
|
||
|
// draw the top and left edge of the ruler
|
||
|
DrawEdge(hdc, &rc, EDGE_ETCHED, BF_TOPLEFT);
|
||
|
// rest of drawing happens just below the top
|
||
|
rc.top += ClassicGetSystemMetrics(SM_CYEDGE);
|
||
|
|
||
|
nFact = 1;
|
||
|
// draw one of the etch heights (1", 1/2", 1/4") per iteration
|
||
|
for (j=0; j<3; ++j)
|
||
|
{
|
||
|
for (i=0; ; ++i)
|
||
|
{
|
||
|
rc.left = g_rcRuler.left + (j==0 ? i*nPixInch : (2*i+1)*nPixInch/nFact);
|
||
|
if (rc.left >= g_rcRuler.right)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
DrawEdge(hdc, &rc, EDGE_ETCHED, BF_LEFT | BF_ADJUST);
|
||
|
|
||
|
// dominant etch deserves a number
|
||
|
if (j == 0)
|
||
|
{
|
||
|
TextOut(hdc, rc.left+1, rc.bottom-g.wHeight,
|
||
|
szTemp, wsprintf(szTemp, szPctD, i));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
rc.bottom -= (rc.bottom - rc.top)/2;
|
||
|
nFact *= 2;
|
||
|
}
|
||
|
|
||
|
SetBkMode(hdc, nOldMode);
|
||
|
}
|
||
|
|
||
|
void NEAR PASCAL CF_UpdateRuler(HWND hDlg)
|
||
|
{
|
||
|
RECT rc;
|
||
|
HWND hwnd;
|
||
|
|
||
|
/* Don't do this stuff if the dialog is not
|
||
|
** visible yet, or other windows will flash.
|
||
|
*/
|
||
|
if (IsWindowVisible(hDlg))
|
||
|
{
|
||
|
// don't invalidate top and left because they never change.
|
||
|
rc = g_rcRuler;
|
||
|
rc.left += ClassicGetSystemMetrics(SM_CXEDGE);
|
||
|
rc.top += ClassicGetSystemMetrics(SM_CYEDGE);
|
||
|
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CUSTOMRULER);
|
||
|
InvalidateRect(hwnd, &rc, TRUE);
|
||
|
UpdateWindow(hwnd);
|
||
|
}
|
||
|
}
|
||
|
void NEAR PASCAL CF_ShowNewPercent(HWND hDlg, UINT uPer)
|
||
|
{
|
||
|
TCHAR szBuf[10];
|
||
|
|
||
|
g_iCurPercent = uPer;
|
||
|
|
||
|
wsprintf(szBuf, szPercentNum, uPer);
|
||
|
SetWindowText(GetDlgItem(hDlg, IDC_CUSTOMCOMBO), szBuf);
|
||
|
UpdateWindow(GetDlgItem(hDlg, IDC_CUSTOMCOMBO));
|
||
|
}
|
||
|
|
||
|
// Build lf with given face and height
|
||
|
//
|
||
|
int CALLBACK EnumProc(CONST LOGFONT *lplf, CONST TEXTMETRIC *lptm, DWORD nType, LPARAM lpData )
|
||
|
{
|
||
|
*(LPLOGFONT)lpData = *lplf;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
HFONT CreateFontWithFace(HWND hwnd, int nHeight, LPCTSTR lpszFace)
|
||
|
{
|
||
|
LOGFONT lf;
|
||
|
HDC hdc;
|
||
|
|
||
|
hdc = GetDC(hwnd);
|
||
|
if(hdc)
|
||
|
{
|
||
|
EnumFontFamilies(hdc, lpszFace, EnumProc, (LPARAM)&lf);
|
||
|
ReleaseDC(hwnd,hdc);
|
||
|
}
|
||
|
|
||
|
lf.lfHeight = nHeight;
|
||
|
lf.lfWidth = lf. lfEscapement = lf.lfOrientation = 0;
|
||
|
|
||
|
return CreateFontIndirect(&lf);
|
||
|
}
|
||
|
|
||
|
void NEAR PASCAL CF_UpdateData(HWND hDlg, UINT uPer, UINT flags)
|
||
|
{
|
||
|
TCHAR szBuf[100];
|
||
|
HFONT hfont;
|
||
|
int i;
|
||
|
HWND hwnd;
|
||
|
int iDPI;
|
||
|
|
||
|
if (flags & UPDATE_CURPER)
|
||
|
{
|
||
|
if (uPer == g_iCurPercent)
|
||
|
return;
|
||
|
|
||
|
if (uPer < MIN_PERCENT)
|
||
|
uPer = MIN_PERCENT;
|
||
|
else if (uPer > MAX_PERCENT)
|
||
|
uPer = MAX_PERCENT;
|
||
|
|
||
|
g_iCurPercent = uPer;
|
||
|
}
|
||
|
if (flags & UPDATE_COMBO)
|
||
|
{
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CUSTOMCOMBO);
|
||
|
wsprintf(szBuf, szPercentNum, g_iCurPercent);
|
||
|
i = (int)SendMessage(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)szBuf);
|
||
|
SendMessage(hwnd, CB_SETCURSEL, (WPARAM)i, 0L);
|
||
|
if (i == -1)
|
||
|
{
|
||
|
SetWindowText(hwnd, szBuf);
|
||
|
UpdateWindow(hwnd);
|
||
|
}
|
||
|
}
|
||
|
if (flags & UPDATE_RULER)
|
||
|
CF_UpdateRuler(hDlg);
|
||
|
|
||
|
if (flags & UPDATE_SAMPLE)
|
||
|
{
|
||
|
iDPI = GETDPI(g_iCurPercent);
|
||
|
|
||
|
// build and set string with DPI info
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CUSTOMSAMPLE);
|
||
|
wsprintf(szBuf, g_szSample, (LPTSTR)g_szSampleFace, iDPI);
|
||
|
SetWindowText(hwnd, szBuf);
|
||
|
|
||
|
hfont = CreateFontWithFace(hwnd, -10 * iDPI / 72, g_szSampleFace);
|
||
|
if (hfont)
|
||
|
{
|
||
|
hfont = (HFONT)SendMessage(hwnd, WM_SETFONT, (WPARAM)hfont, 1L);
|
||
|
if (hfont)
|
||
|
DeleteObject(hfont);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void NEAR PASCAL CF_ReadNewPercent(HWND hDlg)
|
||
|
{
|
||
|
TCHAR szBuf[10];
|
||
|
LPTSTR pstr;
|
||
|
UINT uPer = 0;
|
||
|
|
||
|
GetWindowText(GetDlgItem(hDlg, IDC_CUSTOMCOMBO), szBuf, ARRAYSIZE(szBuf));
|
||
|
|
||
|
pstr = szBuf;
|
||
|
while (*pstr && (*pstr != TEXT('%')))
|
||
|
{
|
||
|
if (*pstr >= TEXT('0') && *pstr <= TEXT('9'))
|
||
|
uPer = uPer * 10 + (*pstr - TEXT('0'));
|
||
|
|
||
|
pstr++;
|
||
|
}
|
||
|
|
||
|
CF_UpdateData(hDlg, uPer, UPDATE_ALL);
|
||
|
}
|
||
|
|
||
|
void NEAR PASCAL CF_InitDialog(HWND hDlg, UINT uDPI)
|
||
|
{
|
||
|
HWND hwnd;
|
||
|
HDC hdc;
|
||
|
HFONT hfont;
|
||
|
SIZE szSize;
|
||
|
int i;
|
||
|
TCHAR szBuf[10];
|
||
|
int iCurSel;
|
||
|
|
||
|
g_iCurPercent = GETPERCENT(uDPI);
|
||
|
|
||
|
hwnd = GetDlgItem(hDlg, IDC_CUSTOMCOMBO);
|
||
|
iCurSel = -1; // assume not in list
|
||
|
for (i = 0; i < NUM_DEFPERCENTS; i++)
|
||
|
{
|
||
|
wsprintf(szBuf, szPercentNum, g_DefaultPercents[i]);
|
||
|
SendMessage(hwnd, CB_INSERTSTRING, (WPARAM)i, (LPARAM)szBuf);
|
||
|
SendMessage(hwnd, CB_SETITEMDATA, (WPARAM)i, g_DefaultPercents[i]);
|
||
|
|
||
|
if (g_iCurPercent == g_DefaultPercents[i])
|
||
|
iCurSel = i;
|
||
|
}
|
||
|
SendMessage(hwnd, CB_SETCURSEL, (WPARAM)iCurSel, 0L);
|
||
|
if (iCurSel == -1)
|
||
|
{
|
||
|
wsprintf(szBuf, szPercentNum, g_iCurPercent);
|
||
|
SetWindowText(hwnd, szBuf);
|
||
|
}
|
||
|
|
||
|
hdc = GetDC(hDlg);
|
||
|
hfont = (HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0L);
|
||
|
if (hfont)
|
||
|
hfont = (HFONT) SelectObject(hdc, hfont);
|
||
|
|
||
|
//dwSize = GetTextExtentPoint32(hdc, TEXT("0"), 1);
|
||
|
GetTextExtentPoint32(hdc, TEXT("0"), 1, &szSize);
|
||
|
|
||
|
g.wWidth = szSize.cx;
|
||
|
g.wHeight = szSize.cy;
|
||
|
|
||
|
LoadString(HINST_THISDLL, IDS_RULERDIRECTION, g_szRulerDirections, ARRAYSIZE(g_szRulerDirections));
|
||
|
|
||
|
//g_cxRulerDirections = LOWORD(GetTextExtent(hdc, g_szRulerDirections, lstrlen(g_szRulerDirections)));
|
||
|
GetTextExtentPoint32(hdc, g_szRulerDirections, lstrlen(g_szRulerDirections), &szSize);
|
||
|
g_cxRulerDirections = szSize.cx;
|
||
|
|
||
|
if (hfont)
|
||
|
SelectObject(hdc, hfont);
|
||
|
ReleaseDC(hDlg, hdc);
|
||
|
|
||
|
// calculate the rectangle for the actual ruler drawing in relation
|
||
|
// to its window
|
||
|
GetClientRect(GetDlgItem(hDlg, IDC_CUSTOMRULER), &g_rcRuler);
|
||
|
g_rcRuler.left += g.wWidth;
|
||
|
g_rcRuler.right -= g.wWidth;
|
||
|
|
||
|
// bottom offset like the sides
|
||
|
g_rcRuler.bottom -= g.wWidth;
|
||
|
|
||
|
LoadString(HINST_THISDLL, IDS_10PTSAMPLE, g_szSample, ARRAYSIZE(g_szSample));
|
||
|
LoadString(HINST_THISDLL, IDS_10PTSAMPLEFACENAME, g_szSampleFace, ARRAYSIZE(g_szSampleFace));
|
||
|
CF_UpdateData(hDlg, 0, UPDATE_SAMPLE);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
const static DWORD FAR aCustFontHelpIds[] = {
|
||
|
// IDC_NO_HELP_1, IDH_COMM_GROUPBOX,
|
||
|
IDC_CUSTOMCOMBO, IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_LISTBOX,
|
||
|
IDC_CUSTOMRULER, IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_RULER,
|
||
|
IDC_CUSTOMSAMPLE,IDH_DISPLAY_SETTINGS_ADVANCED_GENERAL_CUSTOMFONT_SAMPLE,
|
||
|
|
||
|
0, 0
|
||
|
};
|
||
|
|
||
|
|
||
|
INT_PTR CALLBACK CustomFontDlgProc(HWND hDlg, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
HFONT hfont;
|
||
|
int i;
|
||
|
|
||
|
switch (uMessage)
|
||
|
{
|
||
|
case WM_CREATE:
|
||
|
break;
|
||
|
|
||
|
case WM_INITDIALOG:
|
||
|
CF_InitDialog(hDlg, (UINT)lParam);
|
||
|
break;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
hfont = (HFONT)SendDlgItemMessage(hDlg, IDC_CUSTOMSAMPLE, WM_GETFONT, 0, 0L);
|
||
|
if (hfont)
|
||
|
DeleteObject(hfont);
|
||
|
break;
|
||
|
|
||
|
case WM_DRAWITEM:
|
||
|
if (wParam == IDC_CUSTOMRULER)
|
||
|
DrawRuler(hDlg, (LPDRAWITEMSTRUCT)lParam);
|
||
|
break;
|
||
|
|
||
|
case WM_TIMER:
|
||
|
if (g_bTypeTimer)
|
||
|
{
|
||
|
KillTimer(hDlg, 13);
|
||
|
g_bTypeTimer = FALSE;
|
||
|
CF_ReadNewPercent(hDlg);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_HELP:
|
||
|
WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, TEXT("display.hlp"), HELP_WM_HELP,
|
||
|
(DWORD_PTR)(LPTSTR)aCustFontHelpIds);
|
||
|
break;
|
||
|
|
||
|
case WM_CONTEXTMENU:
|
||
|
WinHelp((HWND)wParam, TEXT("display.hlp"), HELP_CONTEXTMENU,
|
||
|
(DWORD_PTR)(LPTSTR)aCustFontHelpIds);
|
||
|
break;
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
switch (LOWORD(wParam))
|
||
|
{
|
||
|
case IDOK:
|
||
|
EndDialog(hDlg, GETDPI(g_iCurPercent));
|
||
|
break;
|
||
|
|
||
|
case IDCANCEL:
|
||
|
EndDialog(hDlg, 0);
|
||
|
break;
|
||
|
|
||
|
case IDC_CUSTOMRULER:
|
||
|
switch (HIWORD(wParam))
|
||
|
{
|
||
|
case DSN_NCCREATE:
|
||
|
SetWindowLong((HWND)lParam, GWL_EXSTYLE,
|
||
|
GetWindowLong((HWND)lParam, GWL_EXSTYLE) | WS_EX_WINDOWEDGE);
|
||
|
break;
|
||
|
|
||
|
case DSN_BEGINDRAG:
|
||
|
// Set the focus to the corresponding edit ctl
|
||
|
SendMessage(hDlg, WM_NEXTDLGCTL,
|
||
|
(WPARAM)GetDlgItem(hDlg, IDC_CUSTOMCOMBO), 1L);
|
||
|
|
||
|
SendMessage((HWND)lParam, DSM_DRAGPOS, 0, (LPARAM)&(g.wStartPos));
|
||
|
|
||
|
if ((int)g.wStartPos < g_rcRuler.left)
|
||
|
{
|
||
|
g.wStartPos = g_rcRuler.left;
|
||
|
}
|
||
|
g.wStartPix = g_iCurPercent;
|
||
|
break;
|
||
|
|
||
|
case DSN_DRAGGING:
|
||
|
{
|
||
|
UINT wNow, wPix;
|
||
|
POINT pt;
|
||
|
|
||
|
//wNow = LOWORD(SendMessage((HWND)lParam, DSM_DRAGPOS, 0, 0L));
|
||
|
SendMessage((HWND)lParam, DSM_DRAGPOS, 0, (LPARAM)&pt);
|
||
|
wNow = pt.x;
|
||
|
|
||
|
if ((int)wNow < g_rcRuler.left)
|
||
|
{
|
||
|
wNow = g_rcRuler.left;
|
||
|
}
|
||
|
|
||
|
wPix = LOWORD((DWORD)wNow*g.wStartPix/g.wStartPos);
|
||
|
if (wPix < MIN_PERCENT)
|
||
|
{
|
||
|
wPix = MIN_PERCENT;
|
||
|
}
|
||
|
if (wPix > MAX_PERCENT)
|
||
|
{
|
||
|
wPix = MAX_PERCENT;
|
||
|
}
|
||
|
|
||
|
if (wPix != g_iCurPercent)
|
||
|
{
|
||
|
CF_ShowNewPercent(hDlg, wPix);
|
||
|
CF_UpdateRuler(hDlg);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case DSN_ENDDRAG:
|
||
|
CF_UpdateData(hDlg, 0, UPDATE_COMBO | UPDATE_SAMPLE);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IDC_CUSTOMCOMBO:
|
||
|
switch(HIWORD(wParam))
|
||
|
{
|
||
|
case CBN_SELCHANGE:
|
||
|
i = (int)SendDlgItemMessage(hDlg, IDC_CUSTOMCOMBO, CB_GETCURSEL, 0, 0L);
|
||
|
if (i != CB_ERR)
|
||
|
{
|
||
|
i = LOWORD(SendDlgItemMessage(hDlg, IDC_CUSTOMCOMBO, CB_GETITEMDATA, (WPARAM)i, 0L));
|
||
|
CF_UpdateData(hDlg, (UINT)i, UPDATE_CURPER | UPDATE_SAMPLE | UPDATE_RULER);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case CBN_EDITCHANGE:
|
||
|
if (g_bTypeTimer)
|
||
|
{
|
||
|
KillTimer(hDlg, 13);
|
||
|
}
|
||
|
g_bTypeTimer = TRUE;
|
||
|
SetTimer(hDlg, 13, 500, NULL);
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return(FALSE);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return(FALSE);
|
||
|
}
|
||
|
return(TRUE);
|
||
|
}
|