mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
350 lines
10 KiB
350 lines
10 KiB
#include "precomp.h"
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* Windows Cardfile - Written by Mark Cliggett */
|
|
/* (c) Copyright Microsoft Corp. 1985, 1994 - All Rights Reserved */
|
|
/* */
|
|
/************************************************************************/
|
|
|
|
/* Page margins values are always stored in inches.
|
|
* chPageText[ID_LEFT .. ID_BOTTOM] contain the strings used to display the
|
|
* margin values in the dlg box.
|
|
* When the system of measurement is metric, margins are displayed in CMs,
|
|
* validated in CMs, but are converted to inches before being stored in
|
|
* chPageText[].
|
|
* For precision, arithmetic with margins values is done after multiplying
|
|
* by BASE and them dividing by 100.
|
|
*/
|
|
NOEXPORT int NEAR CheckMarginNums(
|
|
HWND hWnd);
|
|
|
|
NOEXPORT BOOL NEAR SetDlgItemNum(
|
|
HWND hDlg,
|
|
int nItemID,
|
|
LONG lNum,
|
|
BOOL bDecimal);
|
|
|
|
NOEXPORT BOOL NEAR StrToNum(
|
|
LPTSTR lpNumStr,
|
|
LONG FAR *lpNum);
|
|
|
|
NOEXPORT BOOL NEAR NumToStr(
|
|
LPTSTR lpNumStr,
|
|
LONG lNum,
|
|
BOOL bDecimal);
|
|
|
|
/* define a type for NUM and the base */
|
|
typedef long NUM;
|
|
#define BASE 100L
|
|
|
|
/* converting in/out of fixed point */
|
|
#define NumToShort(x,s) (LOWORD(((x) + (s)) / BASE))
|
|
#define NumRemToShort(x) (LOWORD((x) % BASE))
|
|
|
|
/* rounding options for NumToShort */
|
|
#define NUMFLOOR 0
|
|
#define NUMROUND (BASE/2)
|
|
#define NUMCEILING (BASE-1)
|
|
|
|
#define ROUND(x) NumToShort(x,NUMROUND)
|
|
#define FLOOR(x) NumToShort(x,NUMFLOOR)
|
|
|
|
/* Unit conversion */
|
|
#define InchesToCM(x) (((x) * 254L + 50) / 100)
|
|
#define CMToInches(x) (((x) * 100L + 127) / 254)
|
|
|
|
|
|
/*
|
|
* convert floating point strings (like 2.75 1.5 2) into number of pixels
|
|
* given the number of pixels per CM
|
|
*/
|
|
long CMToPixels(
|
|
TCHAR *ptr,
|
|
int pix_per_CM)
|
|
{
|
|
TCHAR *dot_ptr;
|
|
TCHAR sz[20];
|
|
int decimal;
|
|
|
|
lstrcpy(sz, ptr);
|
|
dot_ptr = _tcschr(sz, szDec[0]);
|
|
if (dot_ptr)
|
|
{
|
|
*dot_ptr++ = 0; /* terminate the inches */
|
|
if (*(dot_ptr + 1) == 0)
|
|
{
|
|
*(dot_ptr + 1) = TEXT('0'); /* convert decimal part to hundredths */
|
|
*(dot_ptr + 2) = 0;
|
|
}
|
|
decimal = ((int)MyAtol(dot_ptr) * pix_per_CM) / 100; /* first part */
|
|
}
|
|
else
|
|
decimal = 0; /* there is not fraction part */
|
|
|
|
return (MyAtol(sz) * pix_per_CM) + decimal; /* second part */
|
|
}
|
|
|
|
|
|
/*
|
|
* dialog procedure for page setup
|
|
*
|
|
* this guy sets the global variables that define how printing is too be done
|
|
* (ie margins, headers, footers)
|
|
*/
|
|
int PageSetupDlgProc(
|
|
HWND hwnd,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LONG lParam)
|
|
{
|
|
int id; /* ID of dialog edit controls */
|
|
long Num;
|
|
TCHAR szSpaceText[32];
|
|
/* store the value of system of measurement currently in use. Shouldn't
|
|
* change when the dlg is up */
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
|
|
for (id = ID_HEADER; id <= ID_FOOTER; id++)
|
|
{
|
|
SendDlgItemMessage(hwnd, id, EM_LIMITTEXT, PT_LEN-1, 0L);
|
|
SetDlgItemText(hwnd, id, chPageText[id - ID_HEADER]);
|
|
}
|
|
for (id = ID_LEFT; id <= ID_BOTTOM; id++)
|
|
{
|
|
SendDlgItemMessage(hwnd, id, EM_LIMITTEXT, 4, 0L);
|
|
if (!fEnglish)
|
|
{
|
|
StrToNum(chPageText[id-ID_HEADER], &Num);
|
|
Num = InchesToCM(Num);
|
|
SetDlgItemNum(hwnd, id, Num, TRUE);
|
|
}
|
|
else
|
|
SetDlgItemText(hwnd, id, chPageText[id-ID_HEADER]);
|
|
}
|
|
LoadString((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
|
|
(fEnglish ? IDS_SPACEISINCH : IDS_SPACEISCENTI),
|
|
szSpaceText, CharSizeOf(szSpaceText) );
|
|
SetDlgItemText(hwnd, ID_SPACE, szSpaceText);
|
|
SendDlgItemMessage(hwnd, ID_HEADER, EM_SETSEL, 0, MAKELONG(0, PT_LEN-1));
|
|
return(TRUE);
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
/* Check if margin values are valid. */
|
|
id = CheckMarginNums(hwnd);
|
|
if ( id <= 0) /* invalid */
|
|
{
|
|
MessageBox(hwnd, szMarginError, szCardfile, MB_OK | MB_ICONEXCLAMATION);
|
|
if (id == 0) /* can't guess which margin is invalid */
|
|
return TRUE; /* continue the dialog */
|
|
else if (id < 0) /* -id is the ID of the child with invalid value */
|
|
{
|
|
SetFocus(GetDlgItem(hwnd, -id));
|
|
return FALSE;
|
|
}
|
|
}
|
|
/* store the changes made only if valid. */
|
|
for (id = ID_HEADER; id <= ID_FOOTER; id++)
|
|
GetDlgItemText(hwnd, id, chPageText[id-ID_HEADER], PT_LEN);
|
|
for (id = ID_LEFT; id <= ID_BOTTOM; id++)
|
|
{
|
|
GetDlgItemText(hwnd, id, chPageText[id-ID_HEADER], PT_LEN);
|
|
if (!fEnglish) /* metric system, convert to inches before storing */
|
|
if (StrToNum(chPageText[id-ID_HEADER], &Num))
|
|
NumToStr(chPageText[id-ID_HEADER], CMToInches(Num), TRUE);
|
|
}
|
|
|
|
/* fall through... */
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hwnd, 0); // lhb tracks
|
|
break;
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
/* Check validity of margin values specified.
|
|
* return TRUE if margins are valid.
|
|
*
|
|
* returns -ID_LEFT if Left margin is invalid,
|
|
* -ID_RIGHT if Right margin is invalid
|
|
* -ID_TOP if Top margin is invalid
|
|
* -ID_BOTTOM if Bottom margin is invalid
|
|
* FALSE if it cannot guess the invalid margin
|
|
*/
|
|
NOEXPORT int NEAR CheckMarginNums(
|
|
HWND hWnd)
|
|
{
|
|
short n;
|
|
TCHAR *pStr;
|
|
TCHAR szStr[PT_LEN];
|
|
long Left, Right, Top, Bottom;
|
|
HANDLE hPrintDC;
|
|
int xPixelsPerInch, yPixelsPerInch, xPrintRes, yPrintRes;
|
|
int xPixelsPerCM; /* Horz Pixels per CM */
|
|
int yPixelsPerCM; /* Vert Pixels per CM */
|
|
int xSizeMM; /* Horz size in millimetres */
|
|
int ySizeMM; /* Vert size in millimeters */
|
|
|
|
for (n = ID_HEADER+2; n <= ID_BOTTOM; n++)
|
|
{
|
|
GetDlgItemText(hWnd, n, szStr, PT_LEN);
|
|
pStr = szStr;
|
|
|
|
while (*pStr)
|
|
{
|
|
if (_istdigit(*pStr) || *pStr == szDec[0])
|
|
pStr = CharNext(pStr);
|
|
else
|
|
return (-n);
|
|
}
|
|
}
|
|
|
|
if (!(hPrintDC = GetPrinterDC()))
|
|
return TRUE; /* can't do any range check, assume OK */
|
|
|
|
xPrintRes = GetDeviceCaps(hPrintDC, HORZRES);
|
|
yPrintRes = GetDeviceCaps(hPrintDC, VERTRES);
|
|
if (fEnglish == 0)
|
|
{
|
|
xSizeMM = GetDeviceCaps(hPrintDC, HORZSIZE);
|
|
ySizeMM = GetDeviceCaps(hPrintDC, VERTSIZE);
|
|
xPixelsPerCM = (xPrintRes/xSizeMM)/10;
|
|
yPixelsPerCM = (yPrintRes/ySizeMM)/10;
|
|
}
|
|
else
|
|
{
|
|
xPixelsPerInch = GetDeviceCaps(hPrintDC, LOGPIXELSX);
|
|
yPixelsPerInch = GetDeviceCaps(hPrintDC, LOGPIXELSY);
|
|
}
|
|
|
|
DeleteDC(hPrintDC);
|
|
|
|
/* margin values have int/float values. Do range check */
|
|
GetDlgItemText(hWnd, ID_LEFT, szStr, PT_LEN);
|
|
Left = (fEnglish == 0) ? CMToPixels(szStr, xPixelsPerCM):
|
|
atopix(szStr,xPixelsPerInch);
|
|
|
|
GetDlgItemText(hWnd, ID_RIGHT, szStr, PT_LEN);
|
|
Right = (fEnglish == 0) ? CMToPixels(szStr, xPixelsPerCM):
|
|
atopix(szStr, xPixelsPerInch);
|
|
|
|
GetDlgItemText(hWnd, ID_TOP, szStr, PT_LEN);
|
|
Top = (fEnglish == 0) ? CMToPixels(szStr, yPixelsPerCM):
|
|
atopix(szStr, yPixelsPerInch);
|
|
|
|
GetDlgItemText(hWnd, ID_BOTTOM, szStr, PT_LEN);
|
|
Bottom = (fEnglish == 0) ? CMToPixels(szStr, yPixelsPerCM):
|
|
atopix(szStr, yPixelsPerInch);
|
|
|
|
/* try to guess the invalid margin */
|
|
if (Left >= xPrintRes)
|
|
return -ID_LEFT; /* Left margin is invalid */
|
|
else if (Right >= xPrintRes)
|
|
return -ID_RIGHT; /* Right margin is invalid */
|
|
else if (Top >= yPrintRes)
|
|
return -ID_TOP; /* Top margin is invalid */
|
|
else if (Bottom >= yPrintRes)
|
|
return -ID_BOTTOM; /* Bottom margin is invalid */
|
|
else if (Left >= (xPrintRes-Right))
|
|
return FALSE; /* can't guess, return FALSE */
|
|
else if (Top >= (yPrintRes-Bottom))
|
|
return FALSE; /* can't guess, return FALSE */
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
NOEXPORT BOOL NEAR StrToNum(LPTSTR lpNumStr, LONG FAR *lpNum)
|
|
{
|
|
LPTSTR s;
|
|
TCHAR szNum[10];
|
|
LONG lNum = 0;
|
|
BOOL fSign;
|
|
|
|
lstrcpy(szNum, lpNumStr);
|
|
/* assume we have an invalid number */
|
|
*lpNum = -1;
|
|
|
|
/* find the decimal point or EOS */
|
|
for (s = szNum; *s && *s != szDec[0]; ++s)
|
|
;
|
|
|
|
/* add two zeros on end of string */
|
|
lstrcat(szNum, TEXT("00"));
|
|
|
|
/* move decimal point right two places */
|
|
s[3] = TEXT('\0');
|
|
if (*s == szDec[0])
|
|
lstrcpy(s, s + 1);
|
|
|
|
/* find beginning of number */
|
|
for (s = szNum; *s == TEXT(' ') || *s == TEXT('\t'); ++s)
|
|
;
|
|
|
|
/* save sign */
|
|
if (*s == TEXT('-')) {
|
|
fSign = TRUE;
|
|
++s;
|
|
} else
|
|
fSign = FALSE;
|
|
|
|
/* convert the number to a long */
|
|
while (*s) {
|
|
if (*s < TEXT('0') || *s > TEXT('9'))
|
|
return FALSE;
|
|
|
|
lNum = lNum * 10 + *s++ - TEXT('0');
|
|
}
|
|
|
|
/* negate result if we saw negative sign */
|
|
if (fSign)
|
|
lNum = -lNum;
|
|
|
|
*lpNum = lNum;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL GetDlgItemNum(HWND hDlg, int nItemID, LONG FAR * lpNum)
|
|
{
|
|
TCHAR num[20];
|
|
|
|
/* get the edit text */
|
|
if (!GetDlgItemText(hDlg, nItemID, num, 20))
|
|
return FALSE;
|
|
|
|
return StrToNum(num, lpNum);
|
|
}
|
|
|
|
NOEXPORT BOOL NEAR NumToStr(LPTSTR lpNumStr, LONG lNum, BOOL bDecimal)
|
|
{
|
|
if (bDecimal)
|
|
wsprintf(lpNumStr, TEXT("%d%c%02d"), FLOOR(lNum), szDec[0], NumRemToShort(lNum));
|
|
else
|
|
wsprintf(lpNumStr, TEXT("%d"), ROUND(lNum));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
NOEXPORT BOOL NEAR SetDlgItemNum(
|
|
HWND hDlg,
|
|
int nItemID,
|
|
LONG lNum,
|
|
BOOL bDecimal)
|
|
{
|
|
TCHAR num[20];
|
|
|
|
NumToStr(num, lNum, bDecimal);
|
|
SetDlgItemText(hDlg, nItemID, num);
|
|
|
|
return TRUE;
|
|
}
|