//==================================================================
// TOPS.TXT - EXAMPLE FILE FOR TOPS - by ETS Inc.
// This is simply an example text file. It was clipped out
// of a piece of the actual .CPP (C++) Windows source files
// used to create TOPS. This material is not copyrighted.
//
// note: TABS are set to THREE in this source file, so the
// spacing won't look proper unless you set Misc Setup to
// TABS 3. (Tabs 3 is common in the new C++)
//
// ABOUT YOUR FILE   DIALOG
// BORDER STYLES     DIALOG
// FONT SELECTION    DIALOG
// FREE RESOURCES    DIALOG
// HEADER FOOTER     DIALOG
// LAYOUT SELECTION  DIALOG
// MISC SETUPS       DIALOG
// OPEN / VIEW FILE  DIALOG
// PAGE BREAKS ERR   DIALOG
// PAGE LAYOUT       DIALOG
// PRINT					DIALOG
// PRINT PREVIEW		DIALOG
// PRINTER SETUP		DIALOG
// SHEET MARGINS     DIALOG
// SIDES 0NE-BOTH    DIALOG
// TEXT MARGINS      DIALOG
// TITLE PAGES			DIALOG
// TURN PAPER OVER	DIALOG
//
//        AUTHOR: VAL PATTERSON, ETS, INC
//       CREATED: JUL 28 1994
// LAST MODIFIED: MAR 11 1995 windows version 1
//
//==================================================================
#include "main.h"
//==================================================================
// EXTERNAL PROTOTYPES
//==================================================================
extern	void		save_config( void );						// MISC.CPP
extern	void		restore_config( void );					// MISC.CPP
extern	void		check_config( void );					// MISC.CPP
extern	void		clear_memory_file( void );				// MAIN.CPP
extern	int		get_doublespaced_flag( int page );	// PRINT.CPP
extern	void		delete_preview_bitmaps( void );		// PREVIEW.CPP
extern	void		preview_destroy( void );				// PREVIEW.CPP
extern	void		print_destroy( void );					// PRINT.CPP
extern	void		destroy_viewfile( void );				// FVIEW.CPP
extern	void		setup_pm_from_config( void );			// PRINT.CPP
extern	char		*withpath( char *filename );			// MAIN.CPP
extern	void		ets_delay( int ms );						// MAIN.CPP
//==================================================================
// EXTERNAL VARIABLES
//==================================================================
extern	HINSTANCE hInstance;				// INSTANCE OF THIS PROGRAM
extern	HWND		MainWindow;				// THIS PROGRAMS MAIN WINDOW
extern	int		major_version;			// THIS PROGRAMS MAJOR VERSION NUMBER
extern	int		minor_version;			// THIS PROGRAMS MINOR VERSION NUMBER
extern	char		buffer[350];			// ANYBODY CAN USE
extern	char		line_buffer[350];		// ANYBODY CAN USE
extern	char		exepath[125];			// Path where .EXE was called from
extern	char		pathname[150];			// STRING STORAGE FOR withpath( )
extern	struct 	configuration config;
extern	struct	mainstruct ms;		 	 // MAIN GLOBAL DATA
extern	struct	analyzefilestruct az; // THE "az"   ANALYZE FILE STRUCTURE
extern	struct	readfilestruct rf;	 // READFILE PARAMATERS
extern	struct	printmanagement pm;	 // PRINT MANAGEMENT STRUCTURE
extern	struct	printfilestruct pf;	 // THE "pf"   PRINT FILE   STRUCTURE
extern	struct	printpreviewstruct pv;// PREVIEW FILE STRUCTURE
//==================================================================
// VARIABLES
//==================================================================
WNDPROC	OldEditFloat;	// SUBCLASSING EDIT CONTROLS FOR FLOATING POINT ONLY
FARPROC	NewEditFloat;
LRESULT	CALLBACK _export NewEditFloatProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam);
static	layout_selection;	// 0=QUIT 1=BOOK 2=SIMPLE 3=ADVANCED 4=WORDWRAP
//==================================================================
// PROTOTYPES
//==================================================================
			char	*add_commas( DWORD number );
			void	build_font_string( LOGFONT FAR *lf, char *buf, int charsize );
			void	master_clear( void);
static	BOOL	paint_current_layout( DRAWITEMSTRUCT *dis );
static	void	find_panel_size( RECT *ib, int rows, int cols, int *hinc, int *vinc, int *iheight, int *iwidth );
static	int	getthefont( HWND, LOGFONT FAR * );		// DEBUG
static	int	sheet_numbers_ok( HWND hwnd );
static	void	validate_margin_range( char *buf, float *who );
//==================================================================
// DIALOG PROTOTYPES
//==================================================================
			void	border_styles_dialog( HWND );
			void	font_select_dialog( HWND );
			void	free_resources_dialog( HWND );
			void	header_footer_dialog( HWND );
			void	page_breaks_dialog( void );
			void	page_layout_dialog( HWND );
			void	print_dialog( HWND );
			void	print_preview_dialog( HWND );
			int	printer_setup( HWND );
			void	misc_setups_dialog( HWND );
			void	text_margins_dialog( HWND );
			void	title_pages_dialog( HWND );
			void	sheet_margins_dialog( HWND );
			void	sides_one_both_dialog( HWND );
			BOOL	turn_paper_over_dialog( void );

static	FARPROC	lpfnAdvancedPageImageProc;			// SELECTING A FLAT STYLE
static	FARPROC	lpfnAboutFileProc;		// ABOUT YOUR FILE DIALOG
static	FARPROC	lpfnBordersProc;			// BORDERS DIALOG
static	FARPROC	lpfnFreeResourcesProc;	// BORDERS DIALOG
static	FARPROC	lpfnHeaderFooterProc;	// HEADER FOOTER DIALOG
static	FARPROC	lpfnLayoutTypeProc;		// PAGE LAYOUTS
static	FARPROC	lpfnPageBreaksProc;		// FILE DIDN'T HAVE PAGE BREAKS
static	FARPROC	lpfnPrintProc;				// PRINT
static	FARPROC	lpfnPreviewProc;			// PRINT PREVIEW
static	FARPROC	lpfnMiscSetupsProc; 		// SETUP DIALOG
static	FARPROC	lpfnTextMarginsProc;		// TEXT FILE MARGIN SETUPS DIALOG
static	FARPROC	lpfnTitlePagesProc;		// TITLE & CERT PAGES PROC
static	FARPROC	lpfnSheetMarginsProc;	// SHEET MARGIN SETUPS DIALOG
static	FARPROC	lpfnSidesProc;				// SIDES ONE-OR-BOTH DIALOG
static	FARPROC	lpfnTurnPaperOverProc;	// TURN PAPER OVER DIALOG

static	BOOL 	  CALLBACK _export AdvancedPageImageProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export AboutFileProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export BordersProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export FreeResourcesProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export HeaderFooterProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export LayoutTypeProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export PrintProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export PageBreaksProc( HWND, WORD, WORD, LONG );
static	LRESULT CALLBACK _export PreviewProc( HWND, WORD, WORD, LONG );
static	BOOL	  CALLBACK _export MiscSetupsProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export TextMarginsProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export TitlePagesProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export TurnPaperOverProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export SheetMarginsProc( HWND, WORD, WORD, LONG );
static	BOOL 	  CALLBACK _export SidesProc( HWND, WORD, WORD, LONG );

//=====================================================================
// DESTROY THE FILE IN MEMORY & ERASE ANY ASSOCIATED WINDOWS
// (JUST LIKE NO FILE WAS EVER OPENED)
//=====================================================================
void	master_clear( void )
{
	clear_memory_file();
	delete_preview_bitmaps();
	preview_destroy();		// JUST IN CASE THE PREVIEW WINDOW WAS UP
	print_destroy();			// JUST IN CASE A PRINT DC WAS ACTIVE
	destroy_viewfile();		// JUST IN CASE VIEWFILE WINDOW WAS UP
}

//=======================================================================
// RUN THE "ABOUT FILE" DIALOG
//=======================================================================
void	about_file_dialog( HWND hwnd )
{
	//--------------------------------------------------------------------
	// IF THERE WERE LESS THAN 8 PAGES IN THE FILE, WE CAN'T SHOW THE DATA
	//--------------------------------------------------------------------
	if(az.totalpages<8)
	{
	 MessageBox(hwnd, "Sorry, but this file is too small.\r\n"
							"It must have at least 8 pages for\r\n"
							"this option to work properly.","SORRY",MB_OK);
	 return;
	}
	// CREATE AN INSTANCE FOR THE -TITLE PAGES- DIALOG BOX
	lpfnAboutFileProc = MakeProcInstance((FARPROC)AboutFileProc,hInstance);
	DialogBox(hInstance,"AboutFileProc",hwnd,(DLGPROC)lpfnAboutFileProc);
	FreeProcInstance(lpfnAboutFileProc);
	InvalidateRect(hwnd,NULL,FALSE);
}

//=======================================================================
// ABOUT FILE DIALOG - SHOW THE USER DETAILS ABOUT HIS FILE
// PAGES, SHEETS, PAGE BREAKS, LINES PER PAGE, DOUBLESPACED
//=======================================================================
static BOOL CALLBACK _export AboutFileProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam)
{
	int 	j,k,pg;
	char	*ww;

	switch( Msg )
	{
	 case WM_INITDIALOG:
	  // SET THE "PAGES IN FILE", "PAGE BREAKS FOUND", AND "SHEETS REQUIRED"
	  // 0th IS HARD-CODED TO ID#101 TO SAVE TIME
	  sprintf(buffer,"Pages in file: %d",az.totalpages);
	  SetDlgItemText(hwnd,101,buffer);
	  sprintf(buffer,"Page breaks found: %d",rf.PAGEBREAKCT);
	  SetDlgItemText(hwnd,102,buffer);
	  sprintf(buffer,"Sheets required to print: %d",pm.max_sheet);
	  SetDlgItemText(hwnd,103,buffer);
	  // SET ALL OF THE "ANALYSE FILE" DATA TEXTBOXES, THERE ARE 8 OF 'EM
	  // 0th IS HARD-CODED TO ID#104-->#111 TO SAVE TIME
	  for(j=104,k=1;j<112;j++,k++)
	  {
		pg=k;
		if(k==7)
		 pg=az.totalpages-1;		// ITEM 7 IS 2nd TO LAST PAGE
		if(k==8)
		 pg=az.totalpages;		// ITEM 8 IS LAST PAGE
		if(get_doublespaced_flag(pg))	// SEE IF PAGE WAS DOUBLE OR SINGLE SPACED
		 ww="double";
		else
		 ww="single";
		sprintf(buffer,"Page %d: %d lines - %sspaced",pg,az.page_about[k-1],ww);
		SetDlgItemText(hwnd,j,buffer);
	  }
	  return TRUE;		// TRUE = SET KEYBOARD FOCUS TO THIS WINDOW

	 //-------------------------------------------------------
	 // IF USING ETS-OWNERDRAW BUTTONS:
	 // YOU MUST INTERCEPT WM_DRAWITEM MESSAGES, & RETURN TRUE
	 //-------------------------------------------------------
	 case WM_DRAWITEM:
	  //------------------------------------
	  // IF THE ITEM IS ONE OF OUR BUTTONS..
	  //------------------------------------
	  DrawDialogEtsButton( (DRAWITEMSTRUCT *)lParam );
	  return TRUE;		// TRUE = I PROCESSED THIS MESSAGE

	 case WM_CLOSE:				// HE SELECTED CLOSE (ALT+F4) BUTTON
	  EndDialog(hwnd,FALSE);
	  return FALSE;

	 case WM_COMMAND:
	  switch( wParam )
	  {
		case ETSOK:
		 EndDialog(hwnd,TRUE);	// RETURN ZERO
		 return FALSE;

		case ETSHELP:
		 WinHelp(hwnd,MAINHELP,HELP_CONTEXT,About_your_File);
		 return TRUE;
	  }
	  break;
	}
	return FALSE;		// DEFAULT WINDOWS DIALOG HANDLER
}

//=======================================================================
// ADD COMMAS TO BIG NUMBERS     EG: 25550550 becomes 25,550,550
// PASS: (DWORD) NUMBER (unsigned long, 32 bits)
// RETURNS: POINTER TO STATIC DATA STRING
// SUBSEQUENT CALLS CHANGE THE STATIC STRING
//=======================================================================
char	*add_commas( DWORD number )
{
	static	char	finishedbuf[20];	// MAX: ULONG = 4,294,967,295
	char	workbuf[20];
	int	j;
	char	*ss;
	char	*dd;
	memset(&finishedbuf[0],0,sizeof(finishedbuf));
	sprintf(workbuf,"%ld",number);	// PRINT WITHOUT COMMAS FIRST
	ss=&workbuf[0];						// POINTER TO SOURCE BUF
	dd=&finishedbuf[0];					// POINTER TO DEST BUF
	j=strlen(workbuf);
	while( *ss )							// GO UNTIL THE TERMINATING NULL
	{
	 *dd++ = *ss++;						// COPY THE NUMBER OVER
	 j--;
	 if( j>=3 )								// DON'T USE THE LAST 3 DIGITS
	  if( ((j%3)==0) )
		*dd++ = ','; 						// ADD A COMMA
	}
	return &finishedbuf[0];				// RETURN A POINTER TO THE NEW NUMBER
}

//=======================================================================
// RUN THE BORDER STYLES DIALOG
//=======================================================================
void	border_styles_dialog( HWND hwnd )
{
	lpfnBordersProc = MakeProcInstance((FARPROC)BordersProc,hInstance);
	DialogBox(hInstance,"BordersProc",hwnd,(DLGPROC)lpfnBordersProc);
	FreeProcInstance(lpfnBordersProc);
}

//=====================================================
// LET THE USER SELECT HIS BORDER STYLE
//=====================================================
static BOOL CALLBACK _export BordersProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam)
{
				PAINTSTRUCT	paint;
	static	HBITMAP		oldbitmap,picsbitmap,textbitmap=NULL;
				HDC			memdc,screendc;
				int			j,left,top;
	static	int			newselection;
	static	char			borders[]={0,1,2,3,4,5,6,1,2,3,4,6};
	static	char			shades[]= {0,0,0,0,0,0,0,1,1,1,1,1};
	static	char			xlate[]=  {0,1,2,3,4,5,6,0,7,8,9,10,0,11};

	switch( Msg )
	{
	 case WM_INITDIALOG:
	  //----------------------------------------------
	  // THERE ARE 14 IMAGES EACH 66 TALL AND 50 WIDE
	  // WE'RE GOING TO DO 7 ON TOP AND 7 ON BOTTOM
	  //----------------------------------------------
	  picsbitmap = LoadBitmap( hInstance, MAKEINTRESOURCE(BORDERSBITMAP) );
	  textbitmap = LoadBitmap( hInstance, MAKEINTRESOURCE(BORDERSTEXTBITMAP) );
	  newselection = config.border;
	  if(newselection!=0 && newselection!=5)
		if(config.shade) newselection+=7;
	  j=xlate[newselection];
	  CheckDlgButton(hwnd,BORDERSA+j,1);
	  save_config();
	  return TRUE;		// DEFAULT DIALOG CONTROL GETS KEYBOARD FOCUS
	 //-------------------------------------------------------
	 // IF USING ETS-OWNERDRAW BUTTONS:
	 // YOU MUST INTERCEPT WM_DRAWITEM MESSAGES, & RETURN TRUE
	 //------------------------------------------------------
	 case WM_DRAWITEM:
	  //------------------------------------
	  // IF THE ITEM IS ONE OF OUR BUTTONS..
	  //------------------------------------
	  DrawDialogEtsButton( (DRAWITEMSTRUCT *)lParam );
	  return TRUE;		// TRUE = I PROCESSED THIS MESSAGE
	 case WM_CLOSE:				// HE SELECTED CLOSE (ALT+F4) BUTTON
	  EndDialog(hwnd,TRUE);
	  return FALSE;
	 case WM_COMMAND:
	  //-----------------------------------------------
	  // SEE IF HE MOUSED ON ONE OF THE CHOICES BUTTONS
	  //-----------------------------------------------
	  if(wParam>=BORDERSA && wParam<=BORDERSL)
	  {
		newselection=wParam-BORDERSA;
		j=newselection;
		if(newselection==11)
		 newselection+=2;
		else
		 if(newselection>6)
		  newselection++;
		// DRAW THE TEXT DESCRIPTION...
		screendc=GetDC(hwnd);
		memdc=CreateCompatibleDC(screendc);
		oldbitmap=SelectBitmap(memdc,textbitmap);
		BitBlt(screendc,15,235,145,16,memdc,0,newselection*16,SRCCOPY);
		newselection=j;

		SelectObject(memdc,oldbitmap);
		DeleteDC(memdc);
		ReleaseDC(hwnd,screendc);
		return FALSE;
	  }
	  switch( wParam )
	  {
		case ETSOK:
		 config.shade=shades[newselection];
		 config.border=borders[newselection];
		 check_config();			// SET "ms.setup_changed" IF ANYTHING CHANGED
		 EndDialog(hwnd,FALSE);
		 return FALSE;
		case ETSCANCEL:
		 restore_config();
		 EndDialog(hwnd,FALSE);	// RETURN ZERO
		 return FALSE;
		case ETSHELP:
		 WinHelp(hwnd,MAINHELP,HELP_CONTEXT,Border_Styles);
		 return TRUE;
	  }
	  break;
	 case WM_PAINT:
	  BeginPaint(hwnd,&paint);
	  if( picsbitmap==NULL ) return FALSE;
	  if( textbitmap==NULL ) return FALSE;
	  memdc = CreateCompatibleDC(paint.hdc);
	  // DRAW ALL OF THE PICTURES...
	  oldbitmap = SelectBitmap(memdc,picsbitmap);
	  top=25;left=15;
	  for(j=0;j<14;j++)
	  {
		if(j==7){top=135;left=15;}
		//--------------------------------------------------
		// STYLES 7 AND 12 ARE NOT USED
		// 7=NO BORDER,CAN'T SHADOW  12=TIC-TAC CAN'T SHADOW
		//--------------------------------------------------
		if(j==7 || j==12){ left+=65; continue; }
		BitBlt(paint.hdc,left,top,50,66,memdc,j*50,0,SRCCOPY);
		left+=65;
	  }
	  // DRAW THE TEXT DESCRIPTION...
	  SelectBitmap(memdc,textbitmap);
	  BitBlt(paint.hdc,15,235,145,16,memdc,0,newselection*16,SRCCOPY);
	  SelectObject(memdc,oldbitmap);
	  DeleteObject(memdc);
	  EndPaint(hwnd,&paint);
	  break;
	 case WM_DESTROY:
	  DeleteObject(picsbitmap);
	  DeleteObject(textbitmap);
	  break;
	}
	return FALSE;		// DEFAULT WINDOWS DIALOG HANDLER
}

//=======================================================================
// RUN THE FONT SELECT DIALOG
// NOTE: THIS DIALOG ONLY CHOOSES THE BODY TEXT FONT,
//=======================================================================
void	font_select_dialog( HWND hwnd )
{
	CHOOSEFONT	cf;
	LOGFONT		lf;
	int			result;
	HFONT       hFont;

	save_config();		// IN CASE ANYTHING CHANGES
	memset(&cf,0,sizeof(cf));

	// MAKE A LOGFONT STRUCTURE OF THE BODY TEXT FONT
	GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf );
	hFont = CreateFontIndirect(&lf);
	strcpy(lf.lfFaceName,config.body_font_name);
	lf.lfWeight = config.body_font_weight;
	lf.lfItalic = config.body_font_italic;

	strcpy(buffer,config.body_font_name);	// INIT OUR CURRENT FONT

	cf.lStructSize = sizeof(cf);
	cf.hwndOwner	= hwnd;
	cf.lpLogFont 	= &lf;
	cf.hDC 			= CreateDC( config.printer_driver,config.printer_device,
										config.printer_output,NULL );
	cf.Flags =
		CF_INITTOLOGFONTSTRUCT |   // USE THE LOG FONT SURUCTURE
		CF_BOTH |						// PRINTER AND DISPLAY FONTS
		CF_TTONLY |						// TRUETYPE ONLY
		CF_EFFECTS |					// ENABLE STRIKEOUT, UNDERLINE & COLORS
		CF_FORCEFONTEXIST | 			// FONT MUST EXIST, OR USER WILL GET AN ERROR
		CF_NOVECTORFONTS |			// NO PLOTTER FONTS
		CF_SCALABLEONLY |				// ONLY SCALABLE FONTS
		CF_WYSIWYG;						// ONLY PRINTER AND DISPLAY FONTS WILL BE SHOWN
	cf.lpszStyle = buffer;			// THE FONT WHICH IS CURRENTLY SELECTED

	result = ChooseFont(&cf);		// CALL THE WINDOWS COMMON DIALOG
	DeleteDC(cf.hDC);		// REMOVE THE DC WE JUST CREATED
	DeleteFont(hFont);	// REMOVE THE FONT WE CREATED
	if( result == FALSE )
	 return;
	//----------------------------------
	// SAVE THE NEW FONT NAME AND WEIGHT
	//----------------------------------
	if( lf.lfFaceName != NULL )
	 strcpy(config.body_font_name,lf.lfFaceName);
	config.body_font_weight = lf.lfWeight;
	check_config();			// SEE IF THE FONT CHANGED
}

//=======================================================================
// RUN THE FREE SYSTEM RESOURCES DIALOG
//=======================================================================
void	free_resources_dialog( HWND hwnd )
{
//	etswin_set_font(0);			// SET THE FIXED PITCH FONT
	// CREATE AN INSTANCE FOR THE -TITLE PAGES- DIALOG BOX
	lpfnFreeResourcesProc = MakeProcInstance((FARPROC)FreeResourcesProc,hInstance);
	DialogBox(hInstance,"FreeResourcesProc",hwnd,(DLGPROC)lpfnFreeResourcesProc);
	FreeProcInstance(lpfnFreeResourcesProc);
	InvalidateRect(hwnd,NULL,FALSE);
//	etswin_set_font(1);			// RESTORE OUR CUSTOM FONT
}

//=======================================================================
// TITLE PAGES PROC - CHOOSE HOW MANY TITLE & CERTIFICATE PAGES IN FILE
// PRINTS THESE PAGES IN A FIXED PITCH FONT, LIKE COURIER
//=======================================================================
static BOOL CALLBACK _export FreeResourcesProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam)
{
	static	struct	diskfree_t df;
	static	long		diskfree;		// FREE DISK SPACE
	static	DWORD		contigfree;		// FREE CONTIGUOUS MEMORY
	static	DWORD		memfree;			// FREE MEMORY IN GENERAL
	static	int		sysfree;			// % FREE SYSTEM
	static	int		gdifree;			// % FREE GDI
	static	int		usrfree;			// % FREE USER

	switch( Msg )
	{
	 case WM_INITDIALOG:
	  // CALCULATE ALL OF THE FREE RESOURCES
	  _dos_getdiskfree(0,&df);
	  diskfree 	=(long)df.avail_clusters
					*(long)df.bytes_per_sector
					*(long)df.sectors_per_cluster;  // USE "%ld" TO PRINT "avail"
	  contigfree = GlobalCompact(0);
	  memfree = GetFreeSpace(0);
	  sysfree = GetFreeSystemResources(GFSR_SYSTEMRESOURCES);
	  gdifree = GetFreeSystemResources(GFSR_GDIRESOURCES);
	  usrfree = GetFreeSystemResources(GFSR_USERRESOURCES);
	  // THE DIALOG CONTAINS HARD-CODED TEXT FIELDS, IT'S TOO EASY
	  SetDlgItemText(hwnd,101,add_commas(diskfree));	// 101 = DISK FREE SPACE
	  SetDlgItemText(hwnd,102,add_commas(memfree));		// 102 = TOTAL FREE MEMORY
	  SetDlgItemText(hwnd,103,add_commas(contigfree));	// 103 = TOTAL CONTIGUOUS FREE MEMORY
	  sprintf( buffer,"%d%%",sysfree);
	  SetDlgItemText(hwnd,104,buffer);						// 104 = FREE SYSTEM RESOURCES
	  sprintf( buffer,"%d%%",gdifree);
	  SetDlgItemText(hwnd,105,buffer);						// 105 = FREE GDI RESOURCES
	  sprintf( buffer,"%d%%",usrfree);
	  SetDlgItemText(hwnd,106,buffer);						// 106 = FREE USER RESOURCES
	  return TRUE;		// TRUE = SET KEYBOARD FOCUS TO THIS WINDOW

	 //-------------------------------------------------------
	 // IF USING ETS-OWNERDRAW BUTTONS:
	 // YOU MUST INTERCEPT WM_DRAWITEM MESSAGES, & RETURN TRUE
	 //------------------------------------------------------
	 case WM_DRAWITEM:
	  //------------------------------------
	  // IF THE ITEM IS ONE OF OUR BUTTONS..
	  //------------------------------------
	  DrawDialogEtsButton( (DRAWITEMSTRUCT *)lParam );
	  return TRUE;		// TRUE = I PROCESSED THIS MESSAGE
	 case WM_CLOSE:				// HE SELECTED CLOSE (ALT+F4) BUTTON
	  EndDialog(hwnd,TRUE);
	  return FALSE;
	 case WM_COMMAND:
	  switch( wParam )
	  {
		case ETSOK:
		 EndDialog(hwnd,FALSE);	// RETURN ZERO
		 return FALSE;          // SHOULD NEVER GET HERE
	  }
	  break;
	}
	return FALSE;		// DEFAULT WINDOWS DIALOG HANDLER
}

//=======================================================================
// RUN THE HEADER-FOOTER DIALOG
//=======================================================================
void	header_footer_dialog( HWND hwnd )
{
	// CREATE AN INSTANCE FOR THE -HEADER FOOTER- DIALOG BOX
	lpfnHeaderFooterProc = MakeProcInstance((FARPROC)HeaderFooterProc,hInstance);
	DialogBox(hInstance,"HeaderFooterProc",hwnd,(DLGPROC)lpfnHeaderFooterProc);
	FreeProcInstance(lpfnHeaderFooterProc);
}

//=======================================================================
// HEADER FOOTER PROC - PICK THE HEADER, FOOTER LINE & FONTS
// TOPS HAS ONLY 1 HEADER, 1 FOOTER
//=======================================================================
static BOOL CALLBACK _export HeaderFooterProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam)
{
	int	k;
	switch( Msg )
	{
	 case WM_INITDIALOG:
	  save_config();
	  // EXPLANATION OF THE HARD-CODED IDENTIFIERS IN THIS DIALOG:
	  // DESCRIPTION                   INDEX
	  // Text of Header or Footer         0
	  // Auto Radiobutton "NONE"          1
	  // Auto Radiobutton "LEFT"          2
	  // Auto Radiobutton "CENTER"        3
	  // Auto Radiobutton "RIGHT"         4
	  // Description of Font              5
	  // Pushbutton "CHANGE FONT"         6
	  // TOPS HAS ONLY 1 HEADER, 1 FOOTER
	  SetDlgItemText(hwnd,HDR1,config.header_text[0]);
	  SetDlgItemText(hwnd,FTR1,config.footer_text[0]);
	  CheckDlgButton(hwnd,HDR1+1+config.header_enabled[0],1);
	  CheckDlgButton(hwnd,FTR1+1+config.footer_enabled[0],1);
	  // FILL IN THE HEADER DESCRIPTION
	  build_font_string( &config.hdrftr_logfont[0], buffer, config.hdrftr_pointsize[0] );
	  SetDlgItemText(hwnd,HDR1+5,buffer);
	  // FILL IN THE FOOTER DESCRIPTION
	  build_font_string( &config.hdrftr_logfont[3], buffer, config.hdrftr_pointsize[3] );
	  SetDlgItemText(hwnd,FTR1+5,buffer);
	  return TRUE;		// TRUE = SET KEYBOARD FOCUS TO THIS WINDOW

	 //-------------------------------------------------------
	 // IF USING ETS-OWNERDRAW BUTTONS:
	 // YOU MUST INTERCEPT WM_DRAWITEM MESSAGES, & RETURN TRUE
	 //------------------------------------------------------
	 case WM_DRAWITEM:
	  //------------------------------------
	  // IF THE ITEM IS ONE OF OUR BUTTONS..
	  //------------------------------------
	  DrawDialogEtsButton( (DRAWITEMSTRUCT *)lParam );
	  return TRUE;		// TRUE = I PROCESSED THIS MESSAGE

	 case WM_CLOSE:				// HE SELECTED CLOSE (ALT+F4) BUTTON
	  restore_config();
	  EndDialog(hwnd,TRUE);
	  return FALSE;

	 case WM_COMMAND:
	  switch( wParam )
	  {
		// HEADER LINE STARTS AT INDEX 0 INTO THE ARRAY
		case HDR1+6:	// HE PRESSED A "CHANGE FONT" (INDEX 6) BUTTON
		 k = getthefont(hwnd,&config.hdrftr_logfont[0]);
		 if( k!=0 )		// RETURNS POINT SIZE OR ZERO IF CANCELLED
		 {
		  config.hdrftr_pointsize[0] = k;	// SET THE TRUE POINT SIZE
		  build_font_string( &config.hdrftr_logfont[0], buffer, k );
		  SetDlgItemText(hwnd,HDR1+5,buffer);
		 }
		 return TRUE;
		// FOOTER LINE STARTS AT INDEX 3 INTO THE ARRAY
		case FTR1+6:   // HE PRESSED A "CHANGE FONT" (INDEX 6) BUTTON
		 k = getthefont(hwnd,&config.hdrftr_logfont[3]);
		 if( k!=0 )		// RETURNS POINT SIZE OR ZERO IF CANCELLED
		 {
		  config.hdrftr_pointsize[3] = k;	// SET THE TRUE POINT SIZE
		  build_font_string( &config.hdrftr_logfont[3], buffer, k );
		  SetDlgItemText(hwnd,FTR1+5,buffer);
		 }
		 return TRUE;

		case ETSOK:
		 // EXTRACT ALL HEADER INFORMATION
		 GetDlgItemText(hwnd,HDR1,config.header_text[0],sizeof(config.header_text[0])-1);
		 for(k=0;k<4;k++)
		  if(IsDlgButtonChecked(hwnd,HDR1+1+k))
			config.header_enabled[0]=k;	// 0=NO 1=LEFT 2=CENTER 3=RIGHT
		 // EXTRACT ALL FOOTER INFORMATION
		 GetDlgItemText(hwnd,FTR1,config.footer_text[0],sizeof(config.footer_text[0])-1);
		 for(k=0;k<4;k++)
		  if(IsDlgButtonChecked(hwnd,FTR1+1+k))
			config.footer_enabled[0]=k;	// 0=NO 1=LEFT 2=CENTER 3=RIGHT
		 check_config();
		 EndDialog(hwnd,FALSE);	// RETURN ZERO
		 return FALSE;

		case ETSCANCEL:
		 restore_config();
		 EndDialog(hwnd,TRUE);	// RETURN ZERO
		 return FALSE;

		case ETSHELP:
		 WinHelp(hwnd,MAINHELP,HELP_CONTEXT,Headers_and_Footers);
		 return TRUE;
	  }
	  break;
	}
	return FALSE;		// DEFAULT WINDOWS DIALOG HANDLER
}
//=====================================================
// CALLED FROM HEADER FOOTER PROC (ABOVE)
// RETURNS THE TRUE POINT SIZE OF THE SELECTED FONT
// -or- FALSE IF USER CANCELLED
//=====================================================
static	int	getthefont( HWND hwnd, LOGFONT FAR *lf )
{
	int	result;
	CHOOSEFONT	cf;
	int	realpointsize;

	memset(&cf,0,sizeof(CHOOSEFONT));
	cf.lStructSize = sizeof(CHOOSEFONT);
	cf.hwndOwner = hwnd;
	cf.lpLogFont = lf;
	cf.Flags =
		CF_INITTOLOGFONTSTRUCT |   // USE THE LOG FONT SURUCTURE
		CF_SCREENFONTS |				// FONTS PRINTABLE TO THE SCREEN ONLY
		CF_TTONLY |						// TRUETYPE ONLY
		CF_EFFECTS |					// ENABLE STRIKEOUT, UNDERLINE & COLORS
		CF_FORCEFONTEXIST; 			// FONT MUST EXIST, OR USER WILL GET AN ERROR
	result = ChooseFont(&cf);
	if( result == FALSE )
	 return FALSE;
	// FEB 17 1995: ChooseFont RETURNS WITH THE USER'S FONT "POINTS" CHOICE
	// IN cf.iPointSize (times ten: eg: if he chose 72 points: iPointSize = 720)
	// WE USE THIS NUMBER TO SET lf->lfHeight TO THE NEGATIVE OF THIS NUMBER/10.
	//
	// WINDOWS (THIS TOOK ME A LOT OF TROUBLE) RETURNS THE WRONG VALUE IN lfHeight
	// (HE USES THE CURRENTLY ACTIVE VERTICAL DPI OF THE SCREEN)
	// EG: IF YOU HAVE A 96 DPI SCREEN, HE WILL SET 72 POINT lfHeight = -96 (SHD BE -72)
	// IF YOU ARE USING A 1280x1024 LARGE FONT, HE WILL SET A 72 POINT TO -140
	// I SIMPLY WISH TO AVOID ALL THAT BULLSHIT, AND SET THE USERS POINT SIZE
	// TO THE VALUE THE USER CHOSE, NOT SOME "ARBITRARY" VALUE WINDOWS USED!
	realpointsize = (cf.iPointSize/10);
	return realpointsize;
}

//==================================================================
// SUBROUTINE: BUILD FONT STRING:
// BUILDS AN ENGLISH FONT DESCRIPTION FROM A LOGFONT STRUCTURE
// EG: Courier New 12 pt Extra Bold Italic
// PASS:
// Pointer to LOGFONT structure &
// Pointer to the dest string( usually "buffer[]") to hold string
// Point Size of font (usually from config.hdrftr_pointsize[])
//
// I will build the string into your dest (usally "buffer[]")
//==================================================================
void	build_font_string( LOGFONT FAR *lf, char *buf, int pointsize )
{
	char 	minibuf[15];

	sprintf( buf," %s ", lf->lfFaceName );	// 1 BLANK BEFORE STARTING STRING
	sprintf( minibuf,"%d",pointsize);		// FONT HEIGHT IN POINTS
	strcat( buf,minibuf );
	strcat( buf," Pt " );
	//-------------------------------
	// FIGURE OUT NORMAL, BOLD.. ETC.
	//-------------------------------
	switch( lf->lfWeight )
	{
	 case 100:	strcat(buf,"Thin");		  break;
	 case 200:  strcat(buf,"Extra Light");break;
	 case 300:  strcat(buf,"Light");		  break;
	 case 400:  strcat(buf,"Normal");     break;
	 case 500:  strcat(buf,"Medium");     break;
	 case 600:  strcat(buf,"SemiBold");   break;
	 case 700:  strcat(buf,"Bold");       break;
	 case 800:  strcat(buf,"Extra Bold"); break;
	 case 900:  strcat(buf,"Heavy");
	}
	//------------------
	// IS IT IN ITALICS?
	//------------------
	if( lf->lfItalic )
	 strcat( buf," Italic" );
	//------------------
	// IS IT UNDERLINED?
	//------------------
	if( lf->lfUnderline )
	 strcat( buf," Underlined");
}

//==================================================================
// RUN THE "PAGE BREAKS" DIALOG:
// CALLED at the END of "open file" if NO PAGE BREAKS WERE FOUND,
// AND WE WERE SET TO "USE EMBEDDED"
// COMPUTER SETS "config.page_breaks" TO A BEST GUESS BEFORE CALLING
//==================================================================
void	page_breaks_dialog( void )
{
	  lpfnPageBreaksProc = MakeProcInstance((FARPROC)PageBreaksProc,hInstance);
	  DialogBox(hInstance,"PageBreaksProc",NULL,(DLGPROC)lpfnPageBreaksProc);
	  FreeProcInstance(lpfnPageBreaksProc);
}
//=====================================================
// PAGE BREAKS DIALOG PROCEDURE:
// THE SINGLE EDIT CONTROL IS HARD CODED TO: 101
//=====================================================
BOOL CALLBACK _export PageBreaksProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam)
{
	int	j;
	BOOL	translated;
	switch( Msg )
	{
	 case WM_INITDIALOG:
	  sprintf(buffer,"%d",config.page_breaks);
	  SetDlgItemText(hwnd,101,buffer);
	  return TRUE;		// TRUE = SET KEYBOARD FOCUS TO THIS WINDOW

	 case WM_DRAWITEM:
	  //------------------------------------
	  // IF THE ITEM IS ONE OF OUR BUTTONS..
	  //------------------------------------
	  DrawDialogEtsButton((DRAWITEMSTRUCT *)lParam );
	  return TRUE;		// TRUE = I PROCESSED THIS MESSAGE

	 case WM_CLOSE:				// HE SELECTED CLOSE (ALT+F4) BUTTON
	  EndDialog(hwnd,TRUE);
	  return FALSE;

	 case WM_COMMAND:
	  switch( wParam )
	  {
		case ETSCANCEL:
		 EndDialog(hwnd,TRUE);			// RETURN OK
		 break;
		case ETSOK:
		 // ASK WINDOWS TO TRANSLATE THE NUMBER FOR ME..
		 j = GetDlgItemInt(hwnd,101,&translated,FALSE);
		 if( translated==TRUE )			// WINDOWS LIKED HIS INTEGER
		  if( j>MINIMUMLINESPERPAGE && j<=MAXIMUMLINESPERPAGE )
			config.page_breaks=j;
		 EndDialog(hwnd,TRUE);	// RETURN OK
		 break;

		case ETSHELP:
		 WinHelp(hwnd,MAINHELP,HELP_CONTEXT,Page_Breaks_Error);
		 return TRUE;
	  }
	  break;
	}
	return FALSE;		// DEFAULT WINDOWS DIALOG HANDLER
}

//=======================================================================
// RUN THE PRINT DIALOG
//=======================================================================
void	print_dialog( HWND hwnd )
{
	  ms.dialog_cancelled=0;
	  lpfnPrintProc = MakeProcInstance((FARPROC)PrintProc,hInstance);
	  DialogBox(hInstance,"PrintProc",hwnd,(DLGPROC)lpfnPrintProc);
	  FreeProcInstance(lpfnPrintProc);
}

//=========================================================================
// PRINT PROC DIALOG:
// - GET THE NUMBER OF COPIES
// - GET HIS SHEET RANGE
// - HANDLE CANCEL & HELP
// - GET: ONE SIDE PRINTING
//        BOTH SIDES PRINTING
//         FRONT SIDES, THEN STOP
//         BACK SIDES, THEN STOP
//=========================================================================
BOOL CALLBACK _export PrintProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam)
{
	switch( Msg )
	{
	 case WM_INITDIALOG:
	  ms.dialog_cancelled=0;
	  sprintf(buffer,"PRINTER: %s on %s",config.printer_device,config.printer_output);
	  SetDlgItemText(hwnd,PRINTERANDPORT,buffer);
	  sprintf(buffer,"Printing on ");
	  if( config.both_sides ) strcat(buffer,"Both Sides.");
	  else strcat(buffer,"One Side.");
	  SetDlgItemText(hwnd,PRINTONEORBOTHSIDES,buffer);

	  if( config.both_sides )
	  {
		switch( config.both_sides_method )
		{
		 case 0:	strcpy(buffer,"Print Fronts, Pause, then Print Backs."); break;
		 case 1: strcpy(buffer,"Print all Front Sides, then Stop.");		break;
		 case 2: strcpy(buffer,"Print all Back Sides, then Stop.");			break;
		 case 3:	strcpy(buffer,"Printing on a Duplexing Printer.");			break;
		}
	  }
	  else strcpy(buffer,"Front sides of paper only.");
	  SetDlgItemText(hwnd,PRINTMETHOD,buffer);

	  PostMessage(hwnd,WM_RECALCULATE,0,0);
	  return TRUE;		// TRUE = SET KEYBOARD FOCUS TO THIS WINDOW

	 case WM_RECALCULATE:
	  pm.copies = 1;
	  pm.start_sheet = pm.min_sheet;
	  if(pm.both_sides)
		pm.max_sheet = (pm.total_sides+1)/2;
	  else
		pm.max_sheet = pm.total_sides;
	  pm.end_sheet = pm.max_sheet;
	  SetDlgItemText(hwnd,NUMBEROFCOPIES,"1");
	  sprintf(buffer," Print Range Min: %d  Max: %d",pm.min_sheet,pm.max_sheet);
	  SetDlgItemText(hwnd,MINMAX,buffer);
	  SetDlgItemText(hwnd,STARTSHEET,"1");
	  sprintf(buffer,"%d",pm.max_sheet);
	  SetDlgItemText(hwnd,ENDSHEET,buffer);
	  //InvalidateRect(GetDlgItem(hwnd,MINMAX),NULL,TRUE);
	  return TRUE;	// REPAINT ANY UPDATED WINDOWS
	 //-------------------------------------------------------
	 // IF USING ETS-OWNERDRAW BUTTONS:
	 // YOU MUST INTERCEPT WM_DRAWITEM MESSAGES, & RETURN TRUE
	 //------------------------------------------------------
	 case WM_DRAWITEM:
	  //------------------------------------
	  // IF THE ITEM IS ONE OF OUR BUTTONS..
	  //------------------------------------
	  DrawDialogEtsButton((DRAWITEMSTRUCT *)lParam );
	  return TRUE;		// TRUE = I PROCESSED THIS MESSAGE
	 case WM_CLOSE:				// HE SELECTED CLOSE (ALT+F4) BUTTON
	  ms.dialog_cancelled = 1;
	  EndDialog(hwnd,TRUE);
	  return FALSE;
	 case WM_COMMAND:
	  switch( wParam )
	  {
		case PRINTTOFILE:
		 pm.print_to_file = IsDlgButtonChecked(hwnd,PRINTTOFILE);
		 break;
		case COLLATEDCOPIES:
		 pm.collated_copies = IsDlgButtonChecked(hwnd,COLLATEDCOPIES);
		 break;
		case STARTSHEET:
		case ENDSHEET:
		case NUMBEROFCOPIES:
		 break;
		case ETSCANCEL:
		 ms.dialog_cancelled = 1;		// SHOW HE WANTS TO ABORT
		 EndDialog(hwnd,TRUE);			// RETURN OK
		 break;
		case ETSOK:
		 // VALIDATE START SHEET AND END SHEET
		 GetDlgItemText(hwnd,STARTSHEET,buffer,4);
		 pm.start_sheet=atoi(buffer);
		 GetDlgItemText(hwnd,ENDSHEET,buffer,4);
		 pm.end_sheet=atoi(buffer);
		 if(!sheet_numbers_ok(hwnd))
		 {
		  PostMessage(hwnd,WM_RECALCULATE,0,0);
		  break;
		 }
		 // VALIDATE NUMBER OF COPIES
		 GetDlgItemText(hwnd,NUMBEROFCOPIES,buffer,3);
		 pm.copies = atoi(buffer);
		 if(pm.copies<1 || pm.copies>99)
		  pm.copies = 1;
		 EndDialog(hwnd,TRUE);	// RETURN OK
		 break;
		case ETSHELP:
		 WinHelp(hwnd,MAINHELP,HELP_CONTEXT,Printing_your_File);
		 return TRUE;
	  }
	  break;
	}
	return FALSE;		// DEFAULT WINDOWS DIALOG HANDLER
}

//===========================================================
// CHECK TO SEE THAT THE SHEET NUMBERS TO PRINT ARE IN RANGE:
// PLACES MESSAGE AND RETURNS FALSE IF ANY ERROR
// CALLED BY: print_dialog()
//===========================================================
static	int	sheet_numbers_ok( HWND hwnd )
{
	int	j=0;
	//----------------------------------------------------------
	// CHECK TO SEE THAT HIS START AND/OR END SHEET ARE IN RANGE
	//----------------------------------------------------------
	if(pm.start_sheet<pm.min_sheet || pm.start_sheet>pm.max_sheet)
	 j++;
	if(pm.end_sheet<pm.min_sheet   || pm.end_sheet>pm.max_sheet  )
	 j++;
	if(pm.start_sheet>pm.end_sheet || pm.end_sheet<pm.start_sheet)
	 j++;
	if(j)
	{
	 MessageBox(hwnd,
	  "INCORRECT SHEET NUMBER(s) ENTERED.\r\n"
	  "PLEASE TRY AGAIN.","Error Entering Numbers",MB_ICONASTERISK);
	 return FALSE;
	}
	return TRUE;
}

//=======================================================================
// RUN THE ONE OR BOTH SIDES PRINT DIALOG
//=======================================================================
void	sides_one_both_dialog( HWND hwnd )
{
	lpfnSidesProc = MakeProcInstance((FARPROC)SidesProc,hInstance);
	DialogBox(hInstance,"SidesProc",hwnd,(DLGPROC)lpfnSidesProc);
	FreeProcInstance(lpfnSidesProc);
}

//=========================================================================
// PRINT ONE OR BOTH SIDES DIALOG:
// - GET: ONE SIDE PRINTING
//        BOTH SIDES PRINTING
//        FRONT SIDES, THEN STOP
//        BACK SIDES, THEN STOP
//			 DUPLEXING PRINTER
//=========================================================================
BOOL CALLBACK _export SidesProc(HWND hwnd,WORD Msg,WORD wParam,LONG lParam)
{
	switch( Msg )
	{
	 case WM_INITDIALOG:
	  ms.dialog_cancelled=0;
	  save_config();
	  sprintf(buffer,"PRINTER: %s on %s",config.printer_device,config.printer_output);
	  SetDlgItemText(hwnd,PRINTERANDPORT,buffer);
	  if( config.both_sides==TRUE )
		CheckDlgButton(hwnd,BOTHSIDES,1);
	  else
		CheckDlgButton(hwnd,ONESIDE,1);
	  if( config.duplexing_printer==TRUE )
		CheckDlgButton(hwnd,DUPLEXPRINTER,1);
	  switch( config.both_sides_method )
	  {
		case 1:			// PRINT FRONTS ONLY, THEN STOP
		 CheckDlgButton(hwnd,FRONTSONLY,1);
		 break;
		case 2:			// PRINT BACKS ONLY, THEN STOP
		 CheckDlgButton(hwnd,BACKSONLY,1);
		 break;
		case 3:			// DUPLEXING PRINTER, BOTH SIDES AT ONCE
		 CheckDlgButton(hwnd,DUPLEXPRINTER,1);
	  }
	  return TRUE;		// TRUE = SET KEYBOARD FOCUS TO THIS WINDOW
	 //-------------------------------------------------------
	 // IF USING ETS-OWNERDRAW BUTTONS:
	 // YOU MUST INTERCEPT WM_DRAWITEM MESSAGES, & RETURN TRUE
	 //------------------------------------------------------
	 case WM_DRAWITEM:
	  //------------------------------------
	  // IF THE ITEM IS ONE OF OUR BUTTONS..
	  //------------------------------------
	  DrawDialogEtsButton((DRAWITEMSTRUCT *)lParam );
	  return TRUE;		// TRUE = I PROCESSED THIS MESSAGE
	 case WM_CLOSE:				// HE SELECTED CLOSE (ALT+F4) BUTTON
	  ms.dialog_cancelled = 1;
	  restore_config();
	  EndDialog(hwnd,TRUE);
	  return FALSE;
	 case WM_COMMAND:
	  switch( wParam )
	  {
		// config.duplexing_printer	TRUE = YES
		// config.both_sides				TRUE = YES
		// config.both_sides_method	0=NORMAL, FRONTS, PAUSE, BACKS
		//										1=FRONTS, STOP
		//										2=BACKS,  STOP
		//										3=DUPLEXING, BOTH SIDES AT ONCE
		case ONESIDE:
		 config.both_sides=FALSE;
		 break;
		case BOTHSIDES:
		 config.both_sides=TRUE;
		 break;
		case FRONTSONLY:
		 config.both_sides_method=1;
		 break;
		case BACKSONLY:
		 config.both_sides_method=2;
		 break;
		case DUPLEXPRINTER:
		 config.both_sides_method=3;
		 config.duplexing_printer=TRUE;
		 break;
		case ETSCANCEL:
		 ms.dialog_cancelled = 1;		// SHOW HE WANTS TO ABORT
		 restore_config();
		 EndDialog(hwnd,TRUE);			// RETURN OK
		 break;
		case ETSOK:
		 // VALIDATES ONE SIDE, BOTH SIDES AND METHOD
		 check_config();
		 setup_pm_from_config();		// INSTALL THE NEW DATA INTO THE pm. STRUCTURE
		 EndDialog(hwnd,TRUE);			// RETURN OK
		 break;
		case ETSHELP:
		 WinHelp(hwnd,MAINHELP,HELP_CONTEXT,Printing_Both_Sides);
		 return TRUE;
	  }
	  break;
	}
	return FALSE;		// DEFAULT WINDOWS DIALOG HANDLER
}
