/*					dviout for Windows

					Property Sheets
					1996, written by SHIMA

					*** Registry ***
	Settings\mode			 mode <- <x>  0, 1, ..., 9
	para<x>\pmode			 mode <- <y>  0, 1, ..., 9
	para<x>\restore			 list or parametes

				***	 Initialization ***
	SetParaSection( RestoreInt("Settings", "mode", 0) );
	RestoreRegistry();

					***	 Print	***
	org_mode = SetParaSection(-1);
	SetParaSection( RestoreIntPara("pmode", org_mode) );
	if(org_mode != SetParaSection(-1))
	RestoreRegistry();
	...
	if(org_mode != SetParaSection(-1))
	SetParaSection(org_mode);
	RestoreRegistry();
*/

// #define	_WIN32_IE 0x0300
#include "dviout.h"
#include <commctrl.h>
#include <ddeml.h>
#include <htmlhelp.h>
#ifdef MSVC
#include "msvcdir.h"
#else
#include <dir.h>
#endif
#include <io.h>
#include "para.h"
#include "option.h"
#include "err.h"
#include "vfont.h"

#ifndef DWL_MSGRESULT
#define DWL_MSGRESULT 0
#endif

	   LRESULT CALLBACK KeyTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK DisplayTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK PrintTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK GraphicTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK PaperTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK SystemTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK FontTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK Font2TabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK JFontTabProc( HWND, UINT, WPARAM, LPARAM ); 
static LRESULT CALLBACK SearchTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK HyperTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK ResolutionTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK RegistryTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK TopTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK LoupeTabProc( HWND, UINT, WPARAM, LPARAM );
static LRESULT CALLBACK WinJFontTabProc( HWND, UINT, WPARAM, LPARAM );
// static LRESULT CALLBACK NonJapaneseTabProc( HWND, UINT, WPARAM, LPARAM );
static int CALLBACK PropSheetProc( HWND, UINT, LPARAM );


/* fontdef.c */
extern char *checkjfm(char *);
extern int resolve_font_root_path(void);
extern char *font_root_path;
extern char *font_search_path;

/* wndproc.c */
extern void LoadKeyTable(void);

/* prtinit.c */
extern void end_config(void );
int GetAddMemory(char *, char *, int);
extern int f_init;

/* wmain.c */
extern HINSTANCE g_hCCdll;
/* vfont.c */
V_JFM *check_wintt(char *);
char *check_ftt(char *);
void release_sfd_record(void);
void DefineFTT(char *);
void chg_ftt(char *, char *);

void *marea(unsigned int);

extern DDESTRUCT	g_ddeData;
extern char			*vfn_org;
extern char *exec_src_sp;
extern char *exec_gsrc_sp;
extern BOOL f_kakuto;

HINSTANCE g_hDVIOUTSR = NULL;

//
// ***********************					 ****************************
//

struct KEY_TAB{
	char *key;
	int	id;
};

static char ParaSection[] = "para0";
int	g_bPropertySheetChange;

int SetParaSection(int val)
{
	int tmp;

	tmp = ParaSection[4] - '0';
	if(val >= 0 && val <= 9)
		ParaSection[4] = '0' + val;
	return tmp;
}

int DeletePara(char *para)
{
	return DeleteRegistry(ParaSection, para);	
}

void set_mode(char *mode)
{
	int	val;
	char *tmp;

	if(mode != NULL){
		val = *mode - '0';
		if(val >= 0 && val <= 9){
			SetParaSection(val);
			RestoreRegistry();
			tmp = GetParaString("mode");
			if(tmp != NULL)
				*tmp |= 0x80;
		}
	}
}

void ReserveIntPara(char *key, int val)
{
	ReserveInt(ParaSection, key, val);
}

static void ReserveTabInt(HWND hwnd, char *key, int id)
{
	int val;
	int flag;

	val = GetDlgItemInt(hwnd, id, &flag, TRUE);
	if(flag)
		ReserveIntPara(key, val);
}

static void ReserveTabIntK(HWND hwnd, char *key, int id)
{
	int val;
	int flag;

	val = GetDlgItemInt(hwnd, id, &flag, TRUE);
	if(flag)
		ReserveIntPara(key, val << 10);
}


void ReserveStringPara(char *key, char *s)
{
	ReserveString(ParaSection, key, s);
}

void ReserveTabString(HWND hwnd, char *key, int id)
{
	GetDlgItemText(hwnd, id, common_work, 0x2000);
	ReserveStringPara(key, common_work);
}

int RestoreIntPara(char *key, int val)
{
	return RestoreInt(ParaSection, key, val);
}

static void RestoreTabInt(HWND hwnd, char *key)
{
	int tmp;

	tmp = RestoreIntPara(key, WRONG_INT);
	if(tmp != WRONG_INT)
		SendMessage( hwnd, UDM_SETPOS, 0, MAKELONG(tmp, 0));
}

static void RestoreTabIntK(HWND hwnd, char *key)
{
	int tmp;

	tmp = RestoreIntPara(key, WRONG_INT);
	if(tmp != WRONG_INT)
		SendMessage( hwnd, UDM_SETPOS, 0, MAKELONG(tmp>>10, 0));
}

int RestoreStringPara(char *str, int size, char *key)
{
	return RestoreString(str, size, ParaSection, key, "");
}

void RestoreTabString(HWND hwnd, char *key, int id)
{
	RestoreStringPara(common_work, 0x2000, key);
	SetDlgItemText(hwnd, id, common_work);
}

void SetTabString(HWND hwnd, char *key, int id)
{
	GetDlgItemText(hwnd, id, common_work, 0x2000);
	SetParaStringDirect(key, common_work);
}

static void SetTabInt(HWND hwnd, char *key, int id)
{
	int val;
	BOOL flag;

	val = GetDlgItemInt(hwnd, id, &flag, TRUE);
	if(flag == TRUE)
		SetParaInt(key, val);
}

static void SetTabIntK(HWND hwnd, char *key, int id)
{
	int val;
	BOOL flag;

	val = GetDlgItemInt(hwnd, id, &flag, TRUE);
	if(flag == TRUE)
		SetParaInt(key, val<<10);
}

static void ReserveAllInt(HWND hwnd, struct KEY_TAB *key_tab)
{
	for( ; key_tab->key != NULL; key_tab++)
		ReserveTabInt(hwnd, key_tab->key, key_tab->id);
}


void InitTabString(HWND hwnd, char *key, int id)
{
	char *tmp;
	tmp = GetParaString(key);
	if(tmp != NULL)
		SetDlgItemText(hwnd, id, tmp);
}


static void InitTabInt(HWND hwnd, char *key, int id, HWND *udWnd)
{
	ARG_TABLE *opt;

	opt = (ARG_TABLE *)SetPara(key, CHECK_OPTION);
	if(opt != NULL){
		*udWnd = CreateUpDownControl(				// Scroll speed
			WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
			| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
			50, 22, 20, 20, 
			hwnd,
			ID_UPDOWN,
			g_winData.hInstance,
			(HWND)GetDlgItem( hwnd, id ),
			opt->end, opt->top, *(int *)(opt->var) );
	}
}

static void InitTabIntK(HWND hwnd, char *key, int id, HWND *udWnd)
{
	ARG_TABLE *opt;

	opt = (ARG_TABLE *)SetPara(key, CHECK_OPTION);
	if(opt != NULL){
		*udWnd = CreateUpDownControl(				// Scroll speed
			WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
			| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
			50, 22, 20, 20, 
			hwnd,
			ID_UPDOWN,
			g_winData.hInstance,
			(HWND)GetDlgItem( hwnd, id ),
			(opt->end)>>10, (opt->top)>>10, *(int *)(opt->var)>>10 );
	}
}


//
// ************************					****************************
//
enum{
	TAB_BOOL,	// 0
	TAB_BOOL2,	// 1
	TAB_INT,	// 2
	TAB_INTK,	// 3
	TAB_STRING,	// 4
	TAB_LENGTH,	// 5
	TAB_PROC,	// 6
	TAB_KEY,	// 7
			// up to 9
	TAB_HELP
};

typedef struct STRUCT_PARA_TAB {
	char *key;
	int	id;
	int hid;
	short int type;
	short int flag;
} PARA_TAB;

static int SPto10mm(int val)
{
	return (int)(((double)(val))/(65536*72.27)*254 + ((val>0)?0.5:-0.5));
}

static void InitAllPara(HWND hwnd, PARA_TAB *para, HWND *udWnd)
{
	ARG_TABLE *opt;
	BOOL tmp;
	int val, val0, val1;

	for( ; para->key != NULL; para++ ){
		if(!para->flag)
			continue;
		switch(para->type){
			case TAB_BOOL:
			case TAB_BOOL2:
				opt = (ARG_TABLE*)SetPara(para->key, CHECK_OPTION);
				if(opt != NULL){
					tmp = *(BOOL*)(opt->var);
					if(para->type == TAB_BOOL2)
						tmp = (tmp==FALSE)?TRUE:FALSE;
					CheckDlgButton(hwnd, para->id, tmp);
				}
				break;

			case TAB_INT:
				if(udWnd != NULL)
					InitTabInt(hwnd, para->key, para->id, udWnd++);
				break;

			case TAB_INTK:
				if(udWnd != NULL)
					InitTabIntK(hwnd, para->key, para->id, udWnd++);
				break;

			case TAB_STRING:
			case TAB_PROC:
				InitTabString(hwnd, para->key, para->id);
				break;

			case TAB_LENGTH:
				opt = (ARG_TABLE*)SetPara(para->key, CHECK_OPTION);
				if(opt != NULL){
					val =	SPto10mm(*(int*)opt->var);
					val0 =	SPto10mm(opt->end);
					val1 =	SPto10mm(opt->top);
					if(udWnd != NULL)
					  *udWnd++ = CreateUpDownControl(		// Scroll speed
						WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
						| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
						50, 22, 20, 20, 
						hwnd,
						ID_UPDOWN,
						g_winData.hInstance,
						(HWND)GetDlgItem( hwnd, para->id ),
						val0, val1, val );
				}
				break;

			default:
				break;
		}
	}
}

static void ReserveAllPara(HWND hwnd, PARA_TAB *para)
{
	BOOL tmp;

	for( ; para->key != NULL; para++ ){
		switch(para->type){
			case TAB_BOOL:
			case TAB_BOOL2:
				tmp = IsDlgButtonChecked(hwnd, para->id);
				if(para->type == TAB_BOOL2)
					tmp = (tmp==FALSE)?TRUE:FALSE;
				ReserveIntPara(para->key, tmp);
				break;

			case TAB_INT:
			case TAB_LENGTH:
				ReserveTabInt(hwnd, para->key, para->id);
				break;

			case TAB_INTK:
				ReserveTabIntK(hwnd, para->key, para->id);
				break;

			case TAB_STRING:
			case TAB_PROC:
				ReserveTabString(hwnd, para->key, para->id);
				break;

			default:
				break;
		}
	}
	MessageSaved(hwnd);
}


static void RestoreAllPara(HWND hwnd, PARA_TAB *para, HWND *udWnd)
{
//	ARG_TABLE *opt;
	BOOL tmp;

	for( ; para->key != NULL && *para->key; para++ ){
		if(!para->flag){
			switch(para->type){
				case TAB_INT:
				case TAB_LENGTH:
				case TAB_INTK:
					udWnd++;
			}
			continue;
		}
		switch(para->type){
			case TAB_BOOL:
			case TAB_BOOL2:
				tmp = RestoreIntPara(para->key, WRONG_INT);
				if(tmp != WRONG_INT){
					if(para->type == TAB_BOOL2)
						tmp = (tmp==FALSE)?TRUE:FALSE;
					CheckDlgButton(hwnd, para->id, tmp);
				}
				break;

			case TAB_INT:
			case TAB_LENGTH:
				RestoreTabInt(*udWnd++, para->key);
				break;

			case TAB_INTK:
				RestoreTabIntK(*udWnd++, para->key);
				break;

			case TAB_STRING:
			case TAB_PROC:
				RestoreTabString(hwnd, para->key, para->id);
				break;

			default:
				break;
		}
	}
}

static void DefaultAllPara(HWND hwnd, PARA_TAB *para, HWND *udWnd)
{
//	ARG_TABLE *opt;
	int tmp;

	for( ; para->key != NULL; para++ ){
		if(!para->flag){
			switch(para->type){
				case TAB_INT:
				case TAB_LENGTH:
				case TAB_INTK:
					udWnd++;
			}
			continue;
		}
		switch(para->type){
			case TAB_BOOL:
			case TAB_BOOL2:
				tmp = GetParaFlagDefault(para->key);
				if(tmp != WRONG_INT){
					if(para->type == TAB_BOOL2)
						tmp = (tmp==FALSE)?TRUE:FALSE;
					CheckDlgButton(hwnd, para->id, tmp);
				}
				break;

			case TAB_LENGTH:
			case TAB_INT:
			case TAB_INTK:
				tmp = GetParaIntDefault(para->key);
				switch(para->type){
					case TAB_LENGTH:
						tmp = SPto10mm(tmp);
						break;
					case TAB_INTK:
						tmp >>= 10;
				}
				SendMessage( *udWnd++, UDM_SETPOS, 0, 
					MAKELONG(tmp, 0));
				break;

			case TAB_STRING:
			case TAB_PROC:
				SetDlgItemText( hwnd, para->id,
					GetParaStringDefault(para->key));
				break;

			default:
				break;
		}
	}
}

char *print10mm(int val)
{
	static char tmp[16];
	int plus;

	tmp[0] = '-';

	if(val < 0){
		plus = 0;
		val = -val;
	}else
		plus = 1;
	sprintf(tmp + 1, "%d.%dmm", val/10, val % 10);
	return tmp + plus;
}

static void SetAllPara(HWND hwnd, PARA_TAB *para)
{
	BOOL tmp;
	int val;
	for( ; para->key != NULL; para++ ){
		if(!para->flag)
			continue;
		para->flag = FALSE;
		switch(para->type){
			case TAB_BOOL:
			case TAB_BOOL2:
				tmp = IsDlgButtonChecked(hwnd, para->id);
				if(para->type == TAB_BOOL2)
					tmp = (tmp==FALSE)?TRUE:FALSE;
				SetParaFlag(para->key, tmp);
				break;

			case TAB_INT:
				SetTabInt(hwnd, para->key, para->id);
				break;

			case TAB_INTK:
				SetTabIntK(hwnd, para->key, para->id);
				break;

			case TAB_STRING:
			case TAB_PROC:
				SetTabString(hwnd, para->key, para->id);
				break;

			case TAB_LENGTH:
				val = GetDlgItemInt(hwnd, para->id, &tmp, TRUE);
				SetParaString(para->key, print10mm(val));

			default:
				break;
		}
	}
}

static void InitParaTab(PARA_TAB *para, int val)
{
	while(para->key != NULL)
		(para++)->flag = val;
}

static BOOL CheckParaTab(PARA_TAB *para, int id)
{
	for( ; para->id != 0; para++){
		if(para->id == id){
			para->flag = TRUE;
			return TRUE;
		}
	}
	return FALSE;
}

// ***********************	 Help	****************************
#include "id2str_idh.h"
void ShowCHelp(DWORD val, DWORD *para)
{
	char buf[4096];
	DWORD id;

	id = (DWORD)GetWindowLong( 
		((LPHELPINFO)val)->hItemHandle, GWL_ID );
	for( ; *para; para += 2){
		if(*para == id){
/*
			WinHelp( ((LPHELPINFO)val)->hItemHandle,
				GetHelpPath(), 
#if 0
				HELP_WM_HELP, 
				(DWORD)para);
#else
				HELP_CONTEXT,
				para[1]);
#endif
*/
			lstrcpy(buf,GetHelpPath());
			lstrcat(buf,"::");
			lstrcat(buf,Id2Str_IDH(para[1]));
			HtmlHelp( ((LPHELPINFO)val)->hItemHandle,
				GetHelpPath(),HH_DISPLAY_TOC, (DWORD)NULL); 
			break;
		}
	}
};


void MessageSaved(HWND hwnd)
{
	DisplayWinMessage(hwnd, "Saved");
	Sleep(1000);
	DisplayMessage(NULL);
}

BOOL ShowWMHelp(DWORD val, PARA_TAB *para)
{
	static DWORD nIDs[] = {0, 0, 0, 0};
	nIDs[0] = (DWORD)GetWindowLong( 
		((LPHELPINFO)val)->hItemHandle, GWL_ID );

	while(para->key != NULL){
		if(para->id == nIDs[0]) {
			if((nIDs[1] = para->hid) != 0)
				goto show;
			 return FALSE;
		}
		para++;
	}
	switch(nIDs[0]){
		case ID_RESTORE:
			nIDs[1] = IDH_RESTORE;
			break;

		case ID_SAVE:
			nIDs[1] = IDH_PSAVE;
			break;

		default:
			return FALSE;
	}
show:
#if 0
	WinHelp( ((LPHELPINFO)val)->hItemHandle,
		GetHelpPath(), HELP_WM_HELP, (DWORD)(LPVOID)nIDs);
#else
//	WinHelp(g_winData.hMainWnd, GetHelpPath(), HELP_CONTEXT, nIDs[1]);
	ShowWinHelp(nIDs[1]);
#endif
	return TRUE;
}

/**************************************************************************/
void SearchFile(char *fname)
{
	int i, tmp, drive;
	char tmpname[0x200];
	char find_name[0x200];
	char *name;

	drive = GetLogicalDrives();
	sprintf(tmpname, "Searching %s", fname);
	DisplayMessage(tmpname);

	if(SearchPath(NULL, fname, NULL, 0x200, tmpname, &name)){
		*name = 0;
		GSPN(tmpname, fname);
		DisplayMessage(NULL);
		return;
	}
	for(i=0, tmp = 1; i < 32; i++, tmp<<=1){
		if(drive & tmp){
			sprintf(tmpname, "%c:\\", i + 'A');
			if(GetDriveType(tmpname) == DRIVE_FIXED){
				sprintf(tmpname, "%c:" "\\\\" "%s", i + 'A', fname);
				if(kpse_search(tmpname, "\\\\") == FALSE)
					continue;
				ChangeWaitCursor(1);
				do{
#if 0
					MSG msg;
#endif
					sprintf( find_name, "Searching %s", tmpname );
#if 0
					while( PeekMessage( (LPMSG)&msg, (HWND)NULL, 0, 0, PM_REMOVE ) ){
						TranslateMessage( (LPMSG)&msg );
						DispatchMessage( (LPMSG)&msg );
					}
#endif
					DisplayMessage( find_name );
					if(!access(tmpname, 0)){
						ChangeWaitCursor(0);
						sprintf( find_name, "Do you use the following:\n%s ?", tmpname );
						if( !AskYes(find_name, "Found") ){
							ChangeWaitCursor(1);
							continue;
						}
						GSPN(tmpname, fname);
						i = strlen(fname);
						while(i > 0 && fname[i-1] != '\\')
							i--;
						if(i)
							fname[i] = 0;
						DisplayMessage(NULL);
						return;
					}
				}while (kpse_search(tmpname, NULL));
			}
		}
	}
	fname[0] = 0;
	DisplayMessage(NULL);
	ChangeWaitCursor(0);
	return;
}


//
// ***********************	Poperty Sheets	******************************
//

#ifdef	MSVC
typedef struct _PROPSHEETPAGEAOLD {
		DWORD           dwSize;
		DWORD           dwFlags;
		HINSTANCE       hInstance;
		union {
			LPCSTR          pszTemplate;
			LPCDLGTEMPLATE  pResource;
		} u;
		union {
			HICON       hIcon;
			LPCSTR      pszIcon;
		} u2;
		LPCSTR          pszTitle;
		DLGPROC         pfnDlgProc;
		LPARAM          lParam;
		LPFNPSPCALLBACKA pfnCallback;
		UINT FAR * pcRefParent;
} PROPSHEETPAGEOLD;

typedef struct _PROPSHEETHEADERAO {
		DWORD           dwSize;
		DWORD           dwFlags;
		HWND            hwndParent;
		HINSTANCE       hInstance;
		union {
			HICON       hIcon;
			LPCSTR      pszIcon;
		} u;
		LPCSTR          pszCaption;
		UINT            nPages;
		union {
			UINT        nStartPage;
			LPCSTR      pStartPage;
		} u2;
		union {
			LPCPROPSHEETPAGEA ppsp;
			HPROPSHEETPAGE FAR *phpage;
		} u3;
		PFNPROPSHEETCALLBACK pfnCallback;
} PROPSHEETHEADEROLD;
#else
# define	PROPSHEETPAGEOLD		PROPSHEETPAGE
# define	PROPSHEETHEADEROLD		PROPSHEETHEADER
#endif

enum {			// Sheets (The order is as follows
	P_TOP,
	P_DISP,
	P_RESOLUTION,
	P_FONT,
	P_FONT2,

	P_WJFONT,
	P_JFONT,
	P_KEY,
	P_SEARCH,
	P_HYPER,

	P_LOUPE,
	P_GRAPHIC,
	P_PRINTER,
	P_PAPER,
	P_SYSTEM,

	P_REGISTRY,
};

int CreateTabCtrl( HWND hwndOwner )
{
	PROPSHEETPAGEOLD psp[16];
	PROPSHEETHEADEROLD psh;
	int i, r;
	FARPROC f; // for PropertySheet() API.

#if	0
#define	PSZICON		pszIcon
#define	PSZTICON	pszIcon
#define	PSZTEMPLATE	pszTemplate
#define	PPSP		ppsp
#else
#define	PSZICON		u2.pszIcon
#define	PSZTICON	u.pszIcon
#define	PSZTEMPLATE	u.pszTemplate
#define	PPSP		u3.ppsp
#endif

	for(i = 0; i < sizeof(psp)/sizeof(PROPSHEETPAGEOLD); i++){
		psp[i].dwSize = sizeof(PROPSHEETPAGEOLD);
		psp[i].dwFlags = PSP_USETITLE|PSP_HASHELP;
		psp[i].hInstance = g_winData.hInstance;
		psp[i].PSZICON = NULL;
		psp[i].lParam = 0;
	}

	psp[P_DISP].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_DISPLAY);
	psp[P_DISP].pfnDlgProc = (DLGPROC)DisplayTabProc;
	psp[P_DISP].pszTitle = "Display";

	psp[P_TOP].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_TOP);
	psp[P_TOP].pfnDlgProc = (DLGPROC)TopTabProc;
	psp[P_TOP].pszTitle = "CONTENTS";

	psp[P_PRINTER].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_PRINTER);
	psp[P_PRINTER].pfnDlgProc = (DLGPROC)PrintTabProc;
	psp[P_PRINTER].pszTitle = "Printer";

	psp[P_SYSTEM].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_SYSTEM);
	psp[P_SYSTEM].pfnDlgProc = (DLGPROC)SystemTabProc;
	psp[P_SYSTEM].pszTitle = "System";

	psp[P_FONT].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_FONT);
	psp[P_FONT].pfnDlgProc = (DLGPROC)FontTabProc;
	psp[P_FONT].pszTitle = "Font";

	psp[P_HYPER].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_HYPER);
	psp[P_HYPER].pfnDlgProc = (DLGPROC)HyperTabProc;
	psp[P_HYPER].pszTitle = "HyperTeX";

	psp[P_SEARCH].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_SEARCH);
	psp[P_SEARCH].pfnDlgProc = (DLGPROC)SearchTabProc;
	psp[P_SEARCH].pszTitle = "Search";

	psp[P_LOUPE].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_LOUPE);
	psp[P_LOUPE].pfnDlgProc = (DLGPROC)LoupeTabProc;
	psp[P_LOUPE].pszTitle = "Common";

	psp[P_PAPER].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_PAPER);
	psp[P_PAPER].pfnDlgProc = (DLGPROC)PaperTabProc;
	psp[P_PAPER].pszTitle = "Paper";

	psp[P_RESOLUTION].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_RESOLUTION);
	psp[P_RESOLUTION].pfnDlgProc = (DLGPROC)ResolutionTabProc;
	psp[P_RESOLUTION].pszTitle = "Resolution";

	psp[P_KEY].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_KEY);
	psp[P_KEY].pfnDlgProc = (DLGPROC)KeyTabProc; // -> 
	psp[P_KEY].pszTitle = "Key";

	psp[P_REGISTRY].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_REGISTRY);
	psp[P_REGISTRY].pfnDlgProc = (DLGPROC)RegistryTabProc;
	psp[P_REGISTRY].pszTitle = "REGISTRY";

	psp[P_FONT2].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_FONT2);
	psp[P_FONT2].pfnDlgProc = (DLGPROC)Font2TabProc;
	psp[P_FONT2].pszTitle = "Font2";

	psp[P_GRAPHIC].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_GRAPHIC);
	psp[P_GRAPHIC].pfnDlgProc = (DLGPROC)GraphicTabProc;
	psp[P_GRAPHIC].pszTitle = "Graphic";

	psp[P_JFONT].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_JFONT);
	psp[P_JFONT].pfnDlgProc = (DLGPROC)JFontTabProc;
	psp[P_JFONT].pszTitle = "JFont2";

	psp[P_WJFONT].PSZTEMPLATE = MAKEINTRESOURCE(IDD_TAB_WINJFONT);
	psp[P_WJFONT].pfnDlgProc = (DLGPROC)WinJFontTabProc;
	psp[P_WJFONT].pszTitle = "WinJFont";

	memset(&psh, 0, sizeof(PROPSHEETHEADEROLD));
	psh.dwSize = sizeof(PROPSHEETHEADEROLD);
	psh.dwFlags = PSH_PROPSHEETPAGE|PSH_PROPTITLE|PSH_HASHELP;
	// psh.dwFlags |= PSH_USECALLBACK;
	psh.hwndParent = hwndOwner;
	psh.hInstance = g_winData.hInstance;
	psh.pszCaption = (LPSTR)"DVIOUT";
	psh.PSZTICON = NULL;
	psh.PPSP = (LPCPROPSHEETPAGE)&psp;
	psh.pfnCallback = (PFNPROPSHEETCALLBACK)PropSheetProc;
	psh.nPages = sizeof(psp)/sizeof(PROPSHEETPAGEOLD);

//	#ifdef MSVC
		f = GetProcAddress( g_hCCdll, "PropertySheet" );
/*
	#else
		if( g_hDVIOUTSR == NULL ) g_hDVIOUTSR = LoadLibrary( "dvioutsr.dll" );
		f = GetProcAddress( g_hDVIOUTSR, "PropertySheetSF" );
	#endif
*/

	r = f==NULL?-1:f(&psh);

/*
	if( r < 0 && GetVersionLevel() <= 0 )
	{
		if( g_hDVIOUTSR != NULL )
			f = GetProcAddress( g_hDVIOUTSR, "PropertySheetSF" );
		if( f == NULL )
		{
			error( WARNING, "You need dvioutsr.dll." );
			return -1;
		}
		else
			r = f(&psh);
	}
*/
	if( r < 0 )
	{
		error( WARNING, "Creating Property Sheet fails with error code %d.\n"
			"I called the address %x.\n",
			GetLastError(), f );
	}
	return r;
}

#define	INIT_APPLY	0x1000
#define	NO_APPLY	0x2000
//
// **********************				 ******************************
//

int CALLBACK PropSheetProc( HWND hwnd, UINT message, LPARAM lParam )
{
	switch( message )
	{
		case PSCB_INITIALIZED:

			break;
		case PSCB_PRECREATE:
//			((DLGTEMPLATE*)(lParam))->cx = 1024;
//			((DLGTEMPLATE*)(lParam))->cy = 768;
			
//			SetWindowPos( hwnd, NULL, 100,100, 1024, 768, SWP_SHOWWINDOW );
			break;
	}
	return 0;
	
}


void ApplyOn(HWND hwnd, UINT *flag)
{
	if(*flag & INIT_APPLY)
		return;
	if(*flag & NO_APPLY){		
		*flag &= ~NO_APPLY;
		if(!*flag)
			return;
	}else if(*flag)
		return;
	PropSheet_Changed( GetParent(hwnd), hwnd );
}

void ApplyOff(HWND hwnd)
{
	PropSheet_UnChanged( GetParent(hwnd), hwnd );

}

int f_DlgQuery;

UINT QueryApply( HWND hDlg, /* NMHDR *enmhdr, */ UINT id )
{
	UINT result;
	HWND hProp;

	if(f_DlgQuery){
		f_DlgQuery |= 2;
		goto cancel;
	}
	if( hDlg == PropSheet_GetCurrentPageHwnd(hProp = GetParent(hDlg)) )
		return IDYES;
#if	1
	PropSheet_SetCurSelByID(hProp, id);
#else
	PropSheet_SetCurSel(hProp, 0, id);
#endif
	f_DlgQuery = 1;
	result = MessageBox(hDlg,
		"Apply the change of this sheet?",
		"Property sheet",
		MB_YESNOCANCEL);
	if(result == IDCANCEL){	// stop to apply
		f_DlgQuery = FALSE;
cancel:	SetWindowLong( hProp, 
			DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
		return IDCANCEL;
	}
	else if(result == IDYES) // apply and continue
		ApplyOff(hDlg);
							// else skip and continue
	f_DlgQuery = FALSE;
	return result;
}

/***************************************************************************
						Modify the size
***************************************************************************/
static int page_width, page_height;

void AdjustPropPage( HWND hwnd )
{
	/***********************************************************************
	 WE DON't GUARANTEE THE FONT SIZE not SMALL(100%) nor LARGE(125%)!
	 ***********************************************************************/
	void AdjustPropSheet( HWND hwndPage, int cx, int cy, int, int );
//	int cxChar, cyChar;
	int fs;
	RECT rect;
	POINT pos;
#if 0
	OSVERSIONINFO osver;
	BOOL Windows2000;
	
	// Get the version of Windows.
	osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx( &osver );
	if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT
	 && osver.dwMajorVersion > 4 ) Windows2000 = TRUE;
	else Windows2000 = FALSE;
#endif

	fs = GetFontSize( 0, "Courier New", FALSE );
//	cxChar = (int)(((fs&0xffff0000) >> 16)/4);
//	cyChar = (int)((fs&0xffff)/8);
	GetWindowRect( hwnd, &rect );
	pos.x = rect.left; pos.y = rect.top;
	ScreenToClient( GetParent(hwnd), &pos );

	/* H A R D - C O D I N G   E X I S T ! */
//	SetWindowPos( hwnd, NULL, pos.x, pos.y, 280*cxChar, 142*cyChar, SWP_SHOWWINDOW );
//	AdjustPropSheet( hwnd, 280*cxChar, 142*cyChar );

#if 0
	SetWindowPos( hwnd, NULL, pos.x, pos.y,
		230*((fs&0xffff0000) >> 16)/4, 130*(fs&0xffff)/8, SWP_SHOWWINDOW );
	AdjustPropSheet( hwnd, 230*((fs&0xffff0000) >> 16)/4, 130*(fs&0xffff)/8, 
		(fs&0xffff0000) >> 16, fs&0xffff );
#else
	SetWindowPos( hwnd, NULL, pos.x, pos.y,
		page_width, page_height, SWP_SHOWWINDOW );
	AdjustPropSheet( hwnd, page_width, page_height, (fs&0xffff0000) >> 16, 
		fs&0xffff );
#endif
}

void AdjustPropSheet( HWND hwndPage, int cx, int cy, int fontwidth, int fontheight )
{
	/* hwndPage : arbitrary property page.
	   only to get a handle of the sheet.
	   cx: cy: specify the size of a dialog shown as a page. */
	HWND hwnd;
	HWND hTab;
	HWND hOK, hCancel, hApply, hHelp;
	RECT rect;
	POINT pos;
	int tabheight, tabwidth, pos_dx;
	void PullDownWindow( HWND hwnd, int pos_dx, int pos_y );
	
	hwnd = GetParent(hwndPage); // the handle for a property sheet.
	GetWindowRect( hwnd, &rect );
	pos.x = rect.left; pos.y = rect.top;
//	the parent of sheet exists but MoveWindow regards the pos. as screen. why?
//	ScreenToClient( GetParent(hwnd), &pos );


	/* H A R D - C O D I N G   E X I S T ! */
//	standard: fontheight = 16, large: 22
//	standard: fontwidth = 10,  large: 16
	tabheight = cy + 8 + 2*(fontheight+1); // standard = +42
	tabwidth  = cx + fontwidth*4/5; // standard = +8

	MoveWindow( hwnd, pos.x, pos.y, 
		2*fontwidth + tabwidth, 4*fontheight + tabheight, TRUE );

	hTab = PropSheet_GetTabControl( hwnd );
	GetWindowRect( hTab, &rect );
	pos.x = rect.left; pos.y = rect.top;
	ScreenToClient( hwnd, &pos );

	/* H A R D - C O D I N G   E X I S T ! */
	MoveWindow( hTab, pos.x, pos.y, tabwidth, tabheight, TRUE );

	hOK = GetDlgItem( hwnd, IDOK );
	hCancel = GetDlgItem( hwnd, IDCANCEL );
	hApply = GetDlgItem( hwnd, 0x3021 ); // SUPER HARD! TOO DANGEROUS!?
	hHelp = GetDlgItem( hwnd, IDHELP );

	GetWindowRect( hHelp, &rect );
	pos.x = rect.right; pos.y = rect.bottom;
	ScreenToClient(hwnd, &pos);
	pos_dx = tabwidth + fontwidth*2/3 - pos.x;

	/* H A R D - C O D I N G   E X I S T ! */

	PullDownWindow( hOK, pos_dx, tabheight - 4 + fontheight );
	PullDownWindow( hCancel, pos_dx, tabheight - 4 + fontheight );
	PullDownWindow( hApply, pos_dx, tabheight - 4 + fontheight );
	PullDownWindow( hHelp, pos_dx, tabheight - 4 + fontheight );
}

void PullDownWindow( HWND hwnd, int pos_dx, int pos_y )
{
	RECT rect;
	POINT pos;

	GetWindowRect( hwnd, &rect );
	pos.x = rect.left; pos.y = rect.top;
	ScreenToClient( GetParent(hwnd), &pos );
	MoveWindow( hwnd, pos.x + pos_dx, pos_y,
		rect.right-rect.left, rect.bottom-rect.top, TRUE );
}


/*
 ******************************	 TOP Page	********************************
 */

LRESULT CALLBACK TopTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	static char *top_messageJ =
		"           パラメータの設定 -- Property Sheets\n\n"
		" フォント関連         : Font, Font2, WinJFont, JFont2\n"
		" 表示関連             : Display, Loupe\n"
		" システム関連         : Resolution, System\n"
		" 用紙サイズ, 印刷関連 : Paper, Printer\n"
		" キー機能割り当て     : Key\n"
		" グラフィック関連     : Graphic\n"
		" そのほか             : Search, HyperTeX\n"
		" 起動時の設定         : REGISTRY";
	static char *top_helpJ = 
		"  各ページで [ヘルプ] を参照してください。また、「？」をクリック"
		"したあと、情報の欲しい所でマウスの左ボタンを押すと、情報があらわれ"
		"る箇所があります。";

	static char *top_messageE =
		"   Setting Parameters -- Property Sheets\n\n"
		" Fonts    : Font, Font2, WinJFont, JFont2\n"
		" Display  : Display, Loupe\n"
		" System   : Resolution, System\n"
		" Output   : Paper, Printer\n"
		" Key      : Key\n"
		" Graphics : Graphic\n"
		" Others   : Search, HyperTeX\n"
		" default  : REGISTRY";
	static char *top_helpE =
		"  For on line Help, push [HELP] button on each sheet. "
		"Click [?] button and push the left button of mouse on a spot you want"
		" to know its explanation.";

	BOOL result;
	static HWND hwnd1, hwnd2, hwnd3;

	switch(message){
		case WM_INITDIALOG:
			SetDlgItemText(hwnd, IDC_TOPTEXT, (f_English)?
				top_messageE:top_messageJ);
			SetDlgItemText(hwnd, IDC_TOPHELP, (f_English)?
				top_helpE:top_helpJ);
			result = TRUE;
mode:		sprintf(common_work, "Current Mode: %d", SetParaSection(-1));
			SetDlgItemText(hwnd, IDC_TOPMODE, common_work);
			return result;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PCONTENTS);
					break;

				case PSN_SETACTIVE:
					/* REMARK: We have to set fonts HERE! */
					hwnd1 = GetDlgItem( hwnd, IDC_TOPTEXT );
					{RECT rect;
						GetWindowRect( hwnd1, &rect );
						page_width = (rect.right - rect.left)*269/230;
						page_height = (rect.bottom - rect.top)*140/92;
					}
					AdjustPropPage(hwnd);
					hwnd2 = GetDlgItem( hwnd, IDC_TOPMODE );
					hwnd3 = GetDlgItem( hwnd, IDC_TOPHELP );
					SetFontJE(hwnd2);
					SetFont(12, hwnd1, !f_English?
						"ＭＳ ゴシック":"Courier New", !f_English );
					SetFont(11, hwnd3, !f_English?
						"ＭＳ ゴシック":"Courier New", !f_English );
					result = FALSE;
					goto mode;
				
				case PSN_KILLACTIVE:
					ReSetFont(hwnd1);
					ReSetFont(hwnd2);
					ReSetFont(hwnd3);
					break;
			}
			break;
	}
	return FALSE;
}


/*
 ******************************	  Loupe		******************************
 */

LRESULT CALLBACK LoupeTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	UINT	tmp;
	int		ret_val;
	static HWND	szWnd, scWnd, spWnd, szcWnd, sccWnd;
	static HWND hedit, hedit2, hedit3;
	static UINT f_change, f_cdiam, f_csize;
	static PARA_TAB para_tab[] =
	{
		{"isp",	  IDC_ISP,	 IDH_ISP, TAB_STRING, 0},
		{"",	  IDC_SRC,	 IDH_SRCSPECIAL, TAB_HELP, 0},
		{"",	  IDC_GSRC,	 IDH_GSRCSPECIAL, TAB_HELP, 0},
		{NULL, 0, 0, 0, 0}
	};


	switch(message){
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			f_cdiam = g_winData.dviwin.loupe.CTRL_size_scale & 0xffff;
			f_csize = g_winData.dviwin.loupe.CTRL_size_scale >> 16;

			szWnd = CreateUpDownControl(
				WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				50, 22, 20, 20, 
				hwnd,
				ID_UPDOWN,
				g_winData.hInstance,
				(HWND)GetDlgItem( hwnd, IDC_LEDIT1 ),
				1600, 10, 
				g_winData.dviwin.loupe.diam);

			szcWnd = CreateUpDownControl(
				WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				50, 22, 20, 20, 
				hwnd,
				ID_UPDOWN,
				g_winData.hInstance,
				(HWND)GetDlgItem( hwnd, IDC_EDIT2 ),
				1600, 10, 
				f_cdiam);

			scWnd = CreateUpDownControl(
				WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				50, 50, 20, 20,
				hwnd,
				ID_UPDOWN,
				g_winData.hInstance,
				(HWND)GetDlgItem( hwnd, IDC_LEDIT2 ),
				64, 1,
				g_winData.dviwin.loupe.div);

			sccWnd = CreateUpDownControl(
				WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				50, 50, 20, 20,
				hwnd,
				ID_UPDOWN,
				g_winData.hInstance,
				(HWND)GetDlgItem( hwnd, IDC_EDIT3 ),
				64, 1,
				f_csize);

			spWnd = CreateUpDownControl(
				WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				50, 50, 20, 20,
				hwnd,
				ID_UPDOWN,
				g_winData.hInstance,
				(HWND)GetDlgItem( hwnd, IDC_LSPEED ),
				128, 1,
				g_winData.dviwin.loupe.skip);
			if(exec_src_sp != NULL)
				SetDlgItemText( hwnd, IDC_SRC, exec_src_sp);
			if(exec_gsrc_sp != NULL)
				SetDlgItemText( hwnd, IDC_GSRC, exec_gsrc_sp);
			InitParaTab(para_tab, TRUE);
			InitAllPara(hwnd, para_tab, NULL);
			InitParaTab(para_tab, FALSE);

			f_change = 0;
			ret_val = TRUE;
			tmp = g_winData.dviwin.loupe.fShape;

res:		if(tmp & F_LCIRCLE)
				CheckRadioButton( hwnd, IDC_LSQUARE, IDC_LCIRCLE, IDC_LCIRCLE);
			else
				CheckRadioButton( hwnd, IDC_LSQUARE, IDC_LCIRCLE,
					(tmp & F_LMEASURE)?IDC_LMEASURE:IDC_LSQUARE );
			CheckDlgButton( hwnd, IDC_LEDGE, (tmp & F_LEDGE)?TRUE:FALSE); 
			CheckRadioButton( hwnd, IDC_LGRAY, IDC_LBLACK,
				(tmp & F_LCOLOR)/2 + IDC_LGRAY );

			return ret_val;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){
				case ID_SAVE:
					ReserveAllPara(hwnd, para_tab);
					tmp = IsDlgButtonChecked( hwnd, IDC_LCIRCLE )?1:0;
					if(IsDlgButtonChecked( hwnd, IDC_LMEASURE ))
						tmp = F_LMEASURE;
					if(IsDlgButtonChecked( hwnd, IDC_LWHITE ))
						tmp |= F_LWHITE;
					else if(IsDlgButtonChecked( hwnd, IDC_LBLACK ))
						tmp |= F_LBLACK;
					tmp |=	(GetDlgItemInt( hwnd, IDC_LSPEED, NULL, 1) << 16);
					if(IsDlgButtonChecked( hwnd, IDC_LEDGE ))
						tmp |= F_LEDGE;
					ReserveInt( "Settings", "LoupeMode", tmp );
					ReserveInt( "Settings", "LoupeDiam",
						GetDlgItemInt( hwnd, IDC_LEDIT1, NULL, 1) );
					ReserveInt( "Settings", "LoupeDiv",
						GetDlgItemInt( hwnd, IDC_LEDIT2, NULL, 1) );
					tmp = (GetDlgItemInt( hwnd, IDC_EDIT3, NULL, 1) << 16)
					   | GetDlgItemInt( hwnd, IDC_EDIT2, NULL, 1);
					ReserveInt( "Settings", "CTRLoupe", tmp );
					GetDlgItemText(hwnd, IDC_SRC, common_work, 0xff);
					ReserveString( "Settings", "src", common_work);
					GetDlgItemText(hwnd, IDC_GSRC, common_work, 0xff);
					ReserveString( "Settings", "gsrc", common_work);
					MessageSaved(hwnd);
					break;

				case ID_RESTORE:
					ApplyOn( hwnd, &f_change );
					SendMessage( szWnd, UDM_SETPOS, 0, 
						MAKELONG((WORD)RestoreInt(
							"Settings", "LoupeDiam", 250), 0));
					SendMessage( scWnd, UDM_SETPOS, 0, 
						MAKELONG((WORD)RestoreInt(
							"Settings", "LoupeDiv", 250), 0));
					tmp = RestoreInt("Settings", "CTRLoupe", (8<<16)|480 );
					SendMessage( szcWnd, UDM_SETPOS, 0, 
						MAKELONG(tmp&0xffff, 0));
					SendMessage( sccWnd, UDM_SETPOS, 0, MAKELONG(tmp>>16, 0));
					tmp = RestoreInt("Settings", "LoupeMode", 0);
					SendMessage( spWnd, UDM_SETPOS, 0, MAKELONG(tmp>>16, 0));
					ret_val = FALSE;
					RestoreString(common_work, 0xff, "Settings", "src", "");
					SetDlgItemText( hwnd, IDC_SRC, common_work);
					RestoreString(common_work, 0xff, "Settings", "gsrc", "");
					SetDlgItemText( hwnd, IDC_GSRC, common_work);
					ApplyOn(hwnd, &f_change);
					InitParaTab(para_tab, TRUE);
					RestoreAllPara(hwnd, para_tab, NULL);
					f_change = 31;
					goto res;

				case IDC_LSQUARE:
				case IDC_LMEASURE:
				case IDC_LCIRCLE:
				case IDC_LBLACK:
				case IDC_LWHITE:
				case IDC_LGRAY:
				case IDC_LEDGE:
					ApplyOn(hwnd, &f_change);
					f_change |= 2;
					break;

			}
			switch( HIWORD(wParam) ){
				case EN_CHANGE:
					switch( LOWORD(wParam) ){
						case IDC_LEDIT1:		// EDITTEXT
						case IDC_LEDIT2:		// EDITTEXT
						case IDC_EDIT2:			// EDITTEXT
						case IDC_EDIT3:			// EDITTEXT
							ApplyOn(hwnd, &f_change);
							f_change |= 1;
							break;
						case IDC_LSPEED:
							ApplyOn(hwnd, &f_change);
							f_change |= 2;
							break;
						case IDC_SRC:
							ApplyOn(hwnd, &f_change);
							f_change |= 4;
							break;
						case IDC_GSRC:
							ApplyOn(hwnd, &f_change);
							f_change |= 8;
							break;
						case IDC_ISP:
							if(!(f_change & INIT_APPLY) &&
							  CheckParaTab(para_tab, LOWORD(wParam))){ 
								ApplyOn(hwnd, &f_change);
								f_change |= 16;
							}
							break;
					}
			}
			break;

		case WM_HELP:
			if(!ShowWMHelp(lParam, para_tab))
				goto help;
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
help:				ShowWinHelp(IDH_PLOUPE);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_LOUPE)){
						case IDYES:			// change the current parameters
							g_winData.dviwin.loupe.diam =
								LOWORD(SendMessage( szWnd, UDM_GETPOS, 0, 0));
							if(g_winData.dviwin.loupe.diam < 10)
								g_winData.dviwin.loupe.diam = 10;
							else if(g_winData.dviwin.loupe.diam > 1600)
								g_winData.dviwin.loupe.diam = 1600;
							g_winData.dviwin.loupe.div = 
								LOWORD(SendMessage( scWnd, UDM_GETPOS, 0, 0));
							if(g_winData.dviwin.loupe.div < 1)
								g_winData.dviwin.loupe.div = 1;
							if(g_winData.dviwin.loupe.div > 64)
								g_winData.dviwin.loupe.div = 64;
							g_winData.dviwin.loupe.CTRL_size_scale = 
							  (GetDlgItemInt( hwnd, IDC_EDIT3, NULL, 1) << 16)
							 | GetDlgItemInt( hwnd, IDC_EDIT2, NULL, 1);
							if(f_change & 2){
								g_winData.dviwin.loupe.fShape = 
								(IsDlgButtonChecked( hwnd, IDC_LCIRCLE )?
									F_LCIRCLE:0)|
								(IsDlgButtonChecked( hwnd, IDC_LMEASURE )?
									F_LMEASURE:0)|
								(IsDlgButtonChecked( hwnd, IDC_LWHITE )?
									F_LWHITE:0)|
								(IsDlgButtonChecked( hwnd, IDC_LBLACK )?
									F_LBLACK:0)|
								(IsDlgButtonChecked( hwnd, IDC_LEDGE)?
									F_LEDGE:0);
								g_winData.dviwin.loupe.skip = 
									LOWORD(SendMessage( spWnd, UDM_GETPOS, 
										0, 0));
								if(g_winData.dviwin.loupe.skip < 1)
									g_winData.dviwin.loupe.skip = 4;
								InitLoupeWindow();
							}
							CheckMenu(ID_LMEASURE, 
								g_winData.dviwin.loupe.fShape & F_LMEASURE);
							if(f_change & 4){
								GetDlgItemText(hwnd,IDC_SRC, common_work,0xff);
								Free0(exec_src_sp);
								exec_src_sp = dup_string(common_work);
							}
							if(f_change & 8){
								GetDlgItemText(hwnd,IDC_GSRC, common_work,0xff);
								Free0(exec_gsrc_sp);
								exec_gsrc_sp = dup_string(common_work);
							}
							if(f_change & 16)
								SetAllPara(hwnd, para_tab);
							f_change = 0;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;
#if	0
				case PSN_KILLACTIVE:
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit);
					ReSetFont(hedit2);
					ReSetFont(hedit3);
//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit = GetDlgItem( hwnd, IDC_SRC );
					SetFontJE(hedit);
					SetMargin(hedit);
					hedit2 = GetDlgItem( hwnd, IDC_ISP );
					SetFontJE(hedit2);
					SetMargin(hedit2);
					hedit3 = GetDlgItem( hwnd, IDC_GSRC);
					SetFontJE(hedit3);
					SetMargin(hedit3);
					SetMargin(GetDlgItem(hwnd,IDC_LEDIT1));
					SetMargin(GetDlgItem(hwnd,IDC_LEDIT2));
					SetMargin(GetDlgItem(hwnd,IDC_LSPEED));
					SetMargin(GetDlgItem(hwnd,IDC_EDIT1));
					SetMargin(GetDlgItem(hwnd,IDC_EDIT2));
					SetMargin(GetDlgItem(hwnd,IDC_EDIT3));
					break;
			}
			break;
			
		case WM_DESTROY:
			break;
	}
	return FALSE;
}

/*
 ************************	   Display	  *******************************
 */

static int TransToGamma( int val )
{
	if(val <= 120){
		val *= 10;
		if(val < 10)
			val = 10;
	}else if(val <= 160)
		val = val*20 - 1200;
	else
		val = val*100 - 14000;
	return val;
}


static int TransFromGamma( int val )
{
	if(val < 0)
		val = -val;
	if(val <= 1200){
		val /= 10;
		if(val <= 0)
			val = 0;
	}else if(val <= 2000)
		val = (val + 1200)/20;
	else{
		val = (val + 14000)/100;
		if(val > 200)
			val = 200;
	}
	return val;
}

static int GetParaMInt(char **s)
{
	int	  val;
	char *pt;

	pt = *s;
	val = (*pt)?atoi(pt):0;
	if(*pt == '-')
		pt++;
	while(*pt >= '0' && *pt <= '9')
		pt++;
	if(*pt)
		pt++;
	*s = pt;
	return val;
}

//	-BMP
//	-scale
//	-t = f_scr_skip;
LRESULT CALLBACK DisplayTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	int	num, pos, sc, sub;
	RECT rect, rect2;
	int	x_pos, y_pos, y_diff;
	static BOOL	f_SetBMP;
	static UINT f_change;
	static HWND udhwnd[10];
	static HWND udWnd[2];
	static HWND trhwnd[5];
	char tmp[64];
	char *pt;
/*
	static UINT id_gamma[5] = 
		{IDC_BMPR, IDC_SCALE1R, IDC_SCALE2R, IDC_SCALE3R, IDC_SCALE4R};
*/
	static PARA_TAB para_tab[] = {
		{"t", IDC_T, IDH_T, TAB_INT, 0},
		{"bright", IDC_BRIGHT, IDH_BRIGHT, TAB_INT, 0},
		{"",	IDC_CONTRAST, IDH_GAMMA, TAB_HELP, 0},
		{NULL, 0, 0, 0}
	};

	switch( message )
	{
		case WM_INITDIALOG:
			if(!f_SetBMP){
				f_SetBMP = TRUE;
				SetBMP();
			}
			f_change = INIT_APPLY;
			InitParaTab(para_tab, TRUE);
			InitAllPara(hwnd, para_tab, udWnd);
			InitParaTab(para_tab, FALSE);
			for(num = pos = 0; pos < 10; ){		// BMP/scale
				if(!pos)
					sc = (!num)?GetXGray():scale[num-1].x;
				else
					sc = (!num)?GetYGray():scale[num-1].y;

				udhwnd[pos + num] = CreateUpDownControl(
					WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
					| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
					50, 22, 20, 20, 
					hwnd,
					ID_UPDOWN,
					g_winData.hInstance,
					(HWND)GetDlgItem( hwnd, num + ((!pos)?IDC_BMPX:IDC_BMPY) ),
					64, 1, sc );
				if(++num == 5){
					num	= 0;
					pos += 5;
				}
			}
			GetWindowRect( hwnd, &rect);
			GetWindowRect( GetDlgItem( hwnd, IDC_BMPY ),  &rect2 );
			y_pos = rect2.top -	 rect.top;
			x_pos = (sub = (rect2.right	 -	rect.left) )*255/183;
//			x_pos += (x_pos - 255)*2/5;;
			GetWindowRect( GetDlgItem( hwnd, IDC_SCALE4G), &rect2);
			y_diff = ((rect2.top - rect.top) - y_pos)/4;
			y_pos -= (y_pos+10)/20;

			for(num = 0; num < 5; num++){		// gamma
				trhwnd[num] = CreateWindow(
					TRACKBAR_CLASS,
					"",
					WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER|WS_TABSTOP,
//					255, 36 + 43*num,			// 40 , , , 212
					x_pos, y_pos + y_diff*num,
//					210,
					sub*210/183,
					32,
//					sub*32/183,
					hwnd,
					NULL,
					g_winData.hInstance,
					NULL);
/*
				SetWindowPos(trhwnd[num], GetDlgItem(hwnd, id_gamma[num]), 
					0, 0, 0, 0, 
//					x_pos, y_pos + y_diff*num, sub*210/183, 32, 0); //
					SWP_NOMOVE|SWP_NOSIZE); // |SWP_NOREDRAW|SWP_SHOWWINDOW|SWP_DRAWFRAME|SWP_FRAMECHANGED); // |SWP_SHOWWINDOW|SWP_DRAWFRAME|SWP_FRAMECHANGED);
*/
				SendMessage(trhwnd[num], TBM_SETRANGE,
					(WPARAM)1, (LPARAM)MAKELONG(1, 200));
				SendMessage(trhwnd[num], TBM_SETTIC,
					(WPARAM)0, (LPARAM)100);
/*
				GetWindowRect(trhwnd[num], &rect);
				InvalidateRect(trhwnd[num], &rect, TRUE );
				UpdateWindow(trhwnd[num]);
*/
				pos = (!num)?SetGamma(0):scale[num-1].gamma;
				if(pos < 0){
					CheckDlgButton( hwnd, IDC_BMPR + num, TRUE);
					pos = -pos;
				}
				sc = TransFromGamma(pos);
				SendMessage(trhwnd[num], TBM_SETPOS,
					(WPARAM)1, (LPARAM)sc);
				sprintf(tmp, "%d.%02d", pos/1000, pos/10 - pos/1000*100);
				SetDlgItemText( hwnd, IDC_BMPG + num, tmp);
			}
			f_change = 0;
/*
			InvalidateRect(hwnd, &rect, TRUE );
			UpdateWindow(hwnd);
*/
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){
				case IDC_BMPR:				// Reverse buttons
					ApplyOn( hwnd, &f_change );
					f_change |= 1;
					break;

				case IDC_SCALE1R:
				case IDC_SCALE2R:
				case IDC_SCALE3R:
				case IDC_SCALE4R:
					ApplyOn( hwnd, &f_change );
					f_change |= 2;
					break;

				case ID_SAVE:
				  {
					int tmp_scale[15];
					ReserveAllPara(hwnd, para_tab);

					for(num = 0; num < 15; num++){
						if(num < 10){
							pos = GetDlgItemInt( hwnd, IDC_BMPX + num, 
								NULL, 1 );
							if(pos < 0 || pos > 64)
								pos = 1;
							tmp_scale[(num<5)?(num*3):((num-5)*3+1)] = pos;
						}else{
							pos = TransToGamma(SendMessage(
								trhwnd[num-10], TBM_GETPOS, 0, 0));
							if( IsDlgButtonChecked( hwnd,num+(IDC_BMPR-10) ) )
								pos = -pos;
							tmp_scale[(num-10)*3+2] = pos;
						}
					}

					sprintf(tmp, "%d:%d:%d", tmp_scale[0], tmp_scale[1],
						tmp_scale[2]);
					ReserveStringPara("BMP", tmp);
					tmp[0] = 0;
					for(num = 3; num < 15; num++)
						sprintf(tmp + strlen(tmp), ":%d", tmp_scale[num]);
					ReserveStringPara("scale", tmp+1);
					break;
				  }

				case ID_RESTORE:
				  {
					int tmp_sc[15];

					ApplyOn( hwnd, &f_change );
					f_change = TRUE;
					InitParaTab(para_tab, TRUE);
					RestoreAllPara(hwnd, para_tab, udWnd);
					RestoreStringPara( tmp, 63, "BMP");
					pt = &tmp[0];
					for(num = 0; num < 15; num += 5)
						tmp_sc[num] = GetParaMInt(&pt);

					RestoreStringPara( tmp, 63, "scale");
					pt = &tmp[0];
					for(pos = 1; pos < 5; pos++){
						for(num = 0; num < 15; num += 5)
							tmp_sc[num + pos] = GetParaMInt(&pt);
					}

					for(num = 0; num < 15; num++){
						if( (pos = tmp_sc[num]) == 0)
							continue;
						if(num < 10){
							SendMessage( udhwnd[num], UDM_SETPOS, 0, 
								MAKELONG((WORD)pos, 0));
						}else{
							CheckDlgButton( hwnd, num+(IDC_BMPR-10),
								(pos>0)?FALSE:TRUE );
							if(pos<0)
								pos = -pos;
							SendMessage(trhwnd[num-10], TBM_SETPOS,
								(WPARAM)1, (LPARAM)TransFromGamma(pos));
							sprintf(tmp, "%d.%02d", 
								pos/1000, pos/10 - pos/1000*100);
							SetDlgItemText( hwnd, (IDC_BMPG - 10) + num, tmp);
						}
					}
					break;
				  }
			}

			switch( HIWORD(wParam) ){
				case EN_CHANGE:
					if(	 LOWORD(wParam) >= IDC_BMPX
					  && LOWORD(wParam) <= IDC_SCALE4Y){
						ApplyOn(hwnd, &f_change);
						f_change |= (	LOWORD(wParam) == IDC_BMPX
									  ||LOWORD(wParam) == IDC_BMPY)?
									1:2;
					}
					else if( !(f_change & INIT_APPLY)
						&& CheckParaTab(para_tab, LOWORD(wParam))){
							ApplyOn(hwnd, &f_change);
							f_change |= 4;
					}
					break;
			}
			break;

		case WM_HSCROLL:					// Trackbar controls
			for(num = 0; num < 5; num++){
				if( trhwnd[num] == (HWND)lParam )
					break;
			}
			if(num >= 5)
				break;
			ApplyOn(hwnd, &f_change);
			f_change |= (!num)?1:2;			// Change BMP/scale
			switch(LOWORD(wParam)){
				case TB_TOP:
				case TB_BOTTOM:
				case TB_LINEDOWN:
				case TB_LINEUP:
				case TB_THUMBPOSITION:
				case TB_THUMBTRACK:
				case TB_PAGEUP:
				case TB_PAGEDOWN:
					pos = TransToGamma(SendMessage((HWND)lParam, 
						TBM_GETPOS, 0, 0));
					sprintf(tmp, "%d.%02d", pos/1000, pos/10 - pos/1000*100);
					SetDlgItemText( hwnd, IDC_BMPG + num, tmp );
			}
			break;

		case WM_VSCROLL:					// Spin controls
			for(num = 0; num < 5; num++){
				if( udhwnd[num] == (HWND)lParam)
					break;
			}
			if(num >= 5)
				break;
						// change x-sacle -> copy it to y-scale
			pos = GetDlgItemInt( hwnd, IDC_BMPX + num, NULL, 1 );
			SendMessage( udhwnd[num+5], UDM_SETPOS, 0, 
				MAKELONG((WORD)pos, 0));
			break;

		case WM_HELP:
		  {
			static DWORD ids[] = {0, 0, 0, 0};

			ids[0] = (DWORD)GetWindowLong(((LPHELPINFO)lParam)->hItemHandle,
				GWL_ID);
			if(ids[0] >= IDC_BMPX  && ids[0] < IDC_T){
				if(ids[0] < IDC_BMPG)
					ids[1] = IDH_HVSCALE;
				else if(ids[0] < IDC_BMPR)
					ids[1] = IDH_GAMMA;
				else
					ids[1] = IDH_REVDISPLAY; 
/*
				WinHelp(g_winData.hMainWnd, GetHelpPath(),
					 HELP_CONTEXT, ids[1]);
*/
				ShowWinHelp(ids[1]);
/*
				WinHelp( ((LPHELPINFO)lParam)->hItemHandle,
					GetHelpPath(), HELP_WM_HELP, (DWORD)(LPVOID)ids);
 */
			}else if(!ShowWMHelp(lParam, para_tab))
					goto help;
		  }
		  break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
help:				ShowWinHelp(IDH_PDISPLAY);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_DISPLAY)){
						case IDYES:			// change the current parameters
						  {
							int tmp_scale[15];

							for(num = 0; num < 15; num++){
								if(num < 10){
									pos = GetDlgItemInt( hwnd, IDC_BMPX + num, 
										NULL, 1 );
									if(pos < 0 || pos > 64)
										pos = 1;
									tmp_scale[num] = pos;
								}else{
									pos = TransToGamma(SendMessage(
										trhwnd[num-10], TBM_GETPOS, 0, 0));
									if( IsDlgButtonChecked( hwnd,
										num+(IDC_BMPR-10) ) )
										pos = -pos;
									tmp_scale[num] = pos;
								}
							}
							if(f_change & 1){
								sprintf(tmp, "%d:%d:%d", 
									tmp_scale[0], tmp_scale[5], tmp_scale[10]);
//								SetXYGray(tmp_scale[0], tmp_scale[5]);
//								SetGamma(tmp_scale[10]);
								SetParaString("BMP", tmp);
								for(pos = 0; pos < 4; pos++)
									CheckMenu(ID_SCALE1+pos, 0);
							}
							if(f_change & 2){
								for(pos = 0; pos < 4; pos++){
									scale[pos].x = tmp_scale[pos+1];
									scale[pos].y = tmp_scale[pos+6];
									scale[pos].gamma = tmp_scale[pos+11];
								}
							}
							if(f_change & 4)
								SetAllPara(hwnd, para_tab);
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;
						  }
						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;
				case PSN_SETACTIVE:
					SetMargin(GetDlgItem(hwnd,IDC_BMPX));
					SetMargin(GetDlgItem(hwnd,IDC_BMPY));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE1X));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE1Y));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE2X));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE2Y));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE3X));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE3Y));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE4X));
					SetMargin(GetDlgItem(hwnd,IDC_SCALE4Y));
					SetMargin(GetDlgItem(hwnd,IDC_T));
					SetMargin(GetDlgItem(hwnd,IDC_BRIGHT));
					AdjustPropPage(hwnd);
					break;

#if	0
				case PSN_KILLACTIVE:
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
//				case PSN_QUERYCANCEL:		// cancel
			}
	}
	return FALSE;
}


/*
 ***************************	 Print	   ********************************
 */

static char *msg_optprt[] =
{
	"raw LIPS III(300dpi)",
	"raw LIPS IV (600dpi)",
	"raw ESC/Page(300dpi)",
	"raw ESC/Page(600dpi)",
	"raw ESC/P(180dpi)",
	"raw PC-PR(160dpi)",
	"raw NM   (180dpi)",
	"use CFG file",
	"define Execution"
};

static char *msg_topcfg = "llmmepno";

LRESULT CALLBACK PrintTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	char *msg;
	BOOL flag;
	static UINT f_change;
	static HWND udWnd[4];
	static BOOL f_changing;
	int s_pos, s_type;
	static HWND hedit;
	static PARA_TAB para_tab[] = {
		{"LM", IDC_LM, IDH_LM, TAB_LENGTH, 0},
		{"TM", IDC_TM, IDH_TM, TAB_LENGTH, 0},
		{"RM", IDC_RM, IDH_RM, TAB_LENGTH, 0},
		{"BM", IDC_BM, IDH_BM, TAB_LENGTH, 0},
		{"area", IDC_AREA, IDH_AREA, TAB_BOOL, 0},
		{"dviprt", IDC_DVIPRT, IDH_DVIPRT, TAB_STRING, 0},
		{NULL, 0, 0, 0}
	};
#	define	LAST_MSG2 (sizeof(msg_optprt)/sizeof(char*))

	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			for(s_pos = 0; s_pos < LAST_MSG2; )
				SendDlgItemMessage(hwnd, IDC_PRTCOMB, CB_ADDSTRING, 0,
					(LPARAM)msg_optprt[s_pos++]);
			InitParaTab(para_tab, TRUE);
			InitAllPara(hwnd, para_tab, udWnd);
			InitParaTab(para_tab, FALSE);
			f_change = 0;
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){

				case ID_SAVE:
					ReserveAllPara(hwnd, para_tab);
					break;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					RestoreAllPara(hwnd, para_tab, udWnd);
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
					break;

				case IDC_PRTDEF:
					if(!f_changing){
						flag = IsDlgButtonChecked( hwnd, IDC_PRTDEF );
						strcpy(common_work, "++");
						GetDlgItemText(hwnd, IDC_DVIPRT, common_work+1, 0xfff);
						if(flag){
							if(common_work[1] != '+')
								SetDlgItemText(hwnd, IDC_DVIPRT, common_work);
						}else if(common_work[1] == '+')
							SetDlgItemText(hwnd, IDC_DVIPRT, common_work+2);
					}
					break;

				case IDC_DEFDPI:
					if(!f_changing){
						GetDlgItemText(hwnd, IDC_DVIPRT, msg = common_work, 
							0x1000);
						if(*msg == '+')
							msg++;
						flag = IsDlgButtonChecked( hwnd, IDC_DEFDPI );
						if(*msg++ == '`'){
							if(flag){
								if(*msg >= 'a' && *msg <= 'z'){
									*msg &= ~0x20;
									SetDlgItemText(hwnd, IDC_DVIPRT, 
										common_work);
								}
							}else if(*msg <= 'Z' && *msg >= 'A'){
									*msg |= 0x20;
									SetDlgItemText(hwnd, IDC_DVIPRT, 
										common_work);
							}
						}
					}
					break;

				case IDC_PRTCFG:
					if( (msg = QueryCfgName()) != NULL){
						sprintf(common_work, "+`%c%s",
							IsDlgButtonChecked( hwnd, IDC_DEFDPI )?'O':'o',
							msg);
						SetDlgItemText(hwnd, IDC_DVIPRT, 
							IsDlgButtonChecked( hwnd, IDC_PRTDEF)?
								common_work:(common_work+1));
					}
					ToDviDir();
					break;
			   case	 IDC_AREA:
					goto check;
			}
			if( HIWORD(wParam) == EN_CHANGE ){
				if(LOWORD(wParam) == IDC_DVIPRT){
					f_changing = TRUE;
					GetDlgItemText(hwnd, IDC_DVIPRT, 
						msg = common_work + 0x1000, 0x1000);
					flag = FALSE;
					if(*msg == '+'){
						flag = TRUE;
						msg++;
					}
					CheckDlgButton(hwnd, IDC_PRTDEF, flag);
					s_pos = -1;
					if(*msg == '`'){
						CheckDlgButton(hwnd, IDC_DEFDPI, 
							(*++msg >= 'A' && *msg <= 'Z')?TRUE:FALSE);
						switch(*msg|0x20){
							case 'o': s_pos++;
							case 'n': s_pos++;
							case 'p': s_pos++;
							case 'e': s_pos+=2;
							case 'm': s_pos+=2;
							case 'l': s_pos++;
						}
						if((s_pos == 0 || s_pos == 2)
						  && msg[1] == 'D' && msg[2] == '6')
							s_pos++;
					}else
						s_pos = LAST_MSG2 - 1;
					if(s_pos >= 0)
						SendDlgItemMessage(hwnd, IDC_PRTCOMB, CB_SETCURSEL, 
							s_pos, 0);
					EnableWindow( GetDlgItem(hwnd, IDC_DEFDPI), 
						(s_pos == LAST_MSG2 -1)?FALSE:TRUE );
					f_changing = 0;
				}
check:			if(!(f_change & INIT_APPLY)
				  && CheckParaTab(para_tab, LOWORD(wParam))){
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
				}
			}else if( HIWORD(wParam) == CBN_SELCHANGE && !f_changing){
				s_type = SendDlgItemMessage(hwnd, IDC_PRTCOMB,
						CB_GETCURSEL, 0, 0L);
				s_pos = msg_topcfg[s_type];
				*(msg = common_work) = '+';
				if(s_pos){
					*++msg = '`';
					if(IsDlgButtonChecked( hwnd, IDC_DEFDPI ))
						s_pos &= ~0x20;
				}
				msg[1] = s_pos;
				msg[2] = 0;
				if(s_type == 1 || s_type == 3)
					strcpy(msg+2, "D600");
				SetDlgItemText( hwnd, IDC_DVIPRT, 
					IsDlgButtonChecked( hwnd, IDC_PRTDEF )?
						common_work:common_work+1);
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;


		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PPRINTER);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_PRINTER)){
						case IDYES:			// change the current parameters
							SetAllPara(hwnd, para_tab);
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;
					
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit = GetDlgItem( hwnd, IDC_DVIPRT );
					SetFontJE(hedit);
					SetMargin(hedit);
					SetMargin(GetDlgItem(hwnd,IDC_LM));
					SetMargin(GetDlgItem(hwnd,IDC_TM));
					SetMargin(GetDlgItem(hwnd,IDC_RM));
					SetMargin(GetDlgItem(hwnd,IDC_BM));
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit);
					break;

//				case PSN_QUERYCANCEL:		// cancel
			}
			break;
			
		case WM_DESTROY:
			break;

	}
	return FALSE;
}

/*
 ******************************		System	   ****************************
 */
extern int f_lupdown;
extern BOOL f_Wshow;
LRESULT CALLBACK SystemTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	static UINT f_change;
	static HWND udWnd[4];
	int num;
	char *fname;
	static HWND hedit1, hedit2, hedit3;

	static PARA_TAB para_tab[] = {
		{"log",	  IDC_LOG, IDH_LOG, TAB_STRING, 0},
		{"texhelp",	  IDC_TEXHELP, IDH_TEXHELP, TAB_STRING, 0},
		{"br",	  IDC_BR, IDH_BR,  TAB_INTK, 0},
		{"bf",	  IDC_BF, IDH_BF,  TAB_INTK, 0},
		{"bb",	  IDC_BB, IDH_BB,  TAB_INTK, 0},
		{"multi", IDC_MULTI, IDH_MULTI, TAB_INT, 0},
		{"base",  IDC_BASE, IDH_BASE, TAB_BOOL, 0},
		{"box",	  IDC_BOX, IDH_BOX, TAB_BOOL, 0},
		{"renew", IDC_RENEW, IDH_RENEW, TAB_BOOL, 0},
		{"button", IDC_BUTTON, IDH_BUTTON, TAB_BOOL, 0},	// 8
		{"file",  IDC_PFILE, IDH_FILE, TAB_PROC, 0},
		{"Wshow", IDC_WSHOW, IDH_WSHOW, TAB_BOOL, 0},
		{"",	  IDC_LUPDWN, IDH_LUPDWN, TAB_BOOL, 0},		// 11
		{"",	  IDC_PFILEB, IDH_FILE, TAB_HELP, 0},
		{"",	  IDC_DEFAULT, IDH_DEFAULT, TAB_HELP, 0},
		{NULL,	  0,	   0,		 0, 0}
	};

	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			if( (num = RestoreInt( "Settings", "cmulti", 0)) > 0 )
				SetParaInt("multi", num);
			InitParaTab(para_tab, TRUE);
			InitAllPara(hwnd, para_tab, udWnd);
			CheckDlgButton(hwnd, IDC_BUTTON, ChangeToolBar(-1));
			CheckDlgButton(hwnd, IDC_LUPDWN, (f_lupdown)?1:0);
			CheckDlgButton(hwnd, IDC_WSHOW, (f_Wshow)?1:0);
			InitParaTab(para_tab, FALSE);
			f_change = 0;
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){

				case ID_SAVE:
					ReserveAllPara(hwnd, para_tab);
					break;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					RestoreAllPara(hwnd, para_tab, udWnd);
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
					break;

				case IDC_DEFAULT:
					InitParaTab(para_tab, TRUE);
					DefaultAllPara(hwnd, para_tab, udWnd);
					CheckDlgButton(hwnd, IDC_LUPDWN, 0);
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
					break;

				case IDC_BASE:
				case IDC_BOX:
				case IDC_RENEW:
				case IDC_BUTTON:
				case IDC_LUPDWN:
				case IDC_WSHOW:
					goto check;

				case IDC_PFILEB:
					if( (fname = QueryGeneralName(
						"Query parameter file", 
						"Parameter file(*.par)", "*.par"
					 )) != NULL )
						SetDlgItemText(hwnd, IDC_PFILE, fname);
					break;
			}
			if( HIWORD(wParam) == EN_CHANGE ){
check:			if(!(f_change & INIT_APPLY)
				  && CheckParaTab(para_tab, LOWORD(wParam))){
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
				}
				para_tab[11].flag = FALSE;
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PSYSTEM);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_SYSTEM)){
						case IDYES:			// change the current parameters
							num = para_tab[0].flag;
							if(para_tab[8].flag)
								f_init |= INIT_BUTTON;
							SetAllPara(hwnd, para_tab);
							if(num){
								g_bLog = (g_szLogFileName != NULL || *g_szLogFileName != '-')?
									TRUE:FALSE;
								CheckMenu(ID_LOGOPEN, g_bLog);
							}
							ReserveInt("Settings", "cmulti", 
								GetParaInt("multi"));
							f_lupdown = IsDlgButtonChecked(hwnd, IDC_LUPDWN);
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit1);
					ReSetFont(hedit2);
					ReSetFont(hedit3);
					break;

//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit1 = GetDlgItem( hwnd, IDC_LOG );
					SetFontJE(hedit1);
					hedit2 = GetDlgItem( hwnd, IDC_PFILE );
					SetFontJE(hedit2);
					hedit3 = GetDlgItem( hwnd, IDC_TEXHELP );
					SetFontJE(hedit3);
					SetMargin(hedit1);
					SetMargin(hedit2);
					SetMargin(hedit3);
					SetMargin(GetDlgItem(hwnd,IDC_BR));
					SetMargin(GetDlgItem(hwnd,IDC_BF));
					SetMargin(GetDlgItem(hwnd,IDC_BB));
					SetMargin(GetDlgItem(hwnd,IDC_MULTI));
					break;
			}
			break;
		
		case WM_DESTROY:
			break;
	}
	return FALSE;
}


void GetGS_LIB(char *path)
{
	static	char *lib[] = {"fonts", "lib", "kanji", "vflib", "Resource",NULL};
	char buf[MAXPATH], buf2[MAXPATH], *fname;
	int len, len2, f_add, loop;

	strcpy(buf, fname = "gswin32c.exe");
	SearchFile(buf);
	if(*buf){
fdgs:	sprintf(path, "%s%s", buf, fname);
		if(getenv("GS_LIB") == NULL){	// It is not necessary for Ver.8.11 or later
			for(fname = buf; fname=strstr(fname, "gs"); ){
				fname += 2;
				if((len = atoi(fname)) >= 8){
					if(*++fname >= '0' && *fname <= '9')
						fname++;
					if(*fname == '.' && (len > 8 || atoi(fname+1) >= 11))
						return;
				}
			}
			f_add = 0;
			len = strlen(buf);			/* last charactter equals \ */
			if(len > 5 && !stricmp(buf + len - 5, "\\bin\\")){
				len -= 4;
				buf[len] = 0;
			}else{
				f_add = 1;
				sprintf(path + strlen(path), "^-I%s", buf);
			}
			for(len2 = len-3; len2 > 0; len2--){
				if(buf[len2] == '\\')
					break;
			}
			len2++;
			for(loop = 0; lib[loop]; loop++){
				strcpy(buf2, buf);
				strcpy(buf2+len, lib[loop]);
				if(!access(buf2,0)){
					sprintf(path + strlen(path), f_add?";%s":"^-I%s", buf2);
					f_add++;
				}
				if(len2 < 3)
					continue;
				strcpy(buf2+len2, lib[loop]);
				if(!access(buf2,0)){
					sprintf(path + strlen(path), f_add?";%s":"^-I%s", buf2);
					f_add++;
				}
			}
		}
	}else{
		strcpy(buf, fname = "gswin32.exe");
		SearchFile(buf);
		if(*buf)
			goto fdgs;
		*path = 0;
	}
}

static char *gform[] =
{
	"raw PBM",
	"monochrome GIF",
	"monochrome BMP",
	"BMP(16 colors)",
	"BMP(256 colors)",
	"BMP(full color)"
};

static char *cmode[] =
{
	"auto mode(p2)",
	"merge",
	"replace(def)",
	"replace(bak)",
	"patch",
	"patch2",
	"auto mode(rep)"
};

/*
 *******************************	 Graphic	 ****************************
 */
LRESULT CALLBACK GraphicTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
#define	LAST_GFORM	sizeof(gform)/sizeof(char *)
#define	LAST_CMODE	sizeof(cmode)/sizeof(char *)
	static UINT f_change;
	int tmp, s_pos;
	char *fname;
	static HWND hedit1, hedit2, hedit3;

	static PARA_TAB para_tab[] = {
		{"gsx",	 IDC_GSX,  IDH_GSX, TAB_STRING, 0},
		{"gdat", IDC_GDAT, IDH_GDAT, TAB_STRING, 0},
		{"gbox", IDC_GBOX, IDH_GBOX, TAB_BOOL, 0},
		{"gsize",  IDC_GSIZE, IDH_GSIZE, TAB_BOOL, 0},
		{"gfit",IDC_GFIT, IDH_GFIT, TAB_BOOL, 0},
		{"gow",	IDC_GOW, IDH_GOW, TAB_BOOL, 0},
		{"color",  IDC_CCOLOR, IDH_COLOR, TAB_BOOL, 0},
		{"spi", IDC_SPI, IDH_SPI, TAB_STRING, 0},
		{"gclip", IDC_GCLIP, IDH_GCLIP, TAB_BOOL, 0},
		{"",	IDC_GIF, IDH_GIF, TAB_INT, 0},
		{"",	IDC_TPIC, IDH_TPIC, TAB_HELP, 0},
		{"",	IDC_GS, IDH_HELPGS, TAB_HELP, 0},
		{"",	IDC_GSXB, IDH_GSX, TAB_HELP, 0},
		{"",	IDC_CMODE, IDH_CMODE, TAB_HELP, 0},
		{NULL,	 0,		  0,		0,	0}
	};

	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			InitParaTab(para_tab, TRUE);
			InitAllPara(hwnd, para_tab, NULL);
			InitParaTab(para_tab, FALSE);
			CheckRadioButton(hwnd, IDC_TPIC1, IDC_TPIC3,
				(GetParaInt("tpic") & 3) + IDC_TPIC1);
			if(GetParaInt("tpic") & 16)
				CheckDlgButton(hwnd, IDC_TPICTATE, TRUE);
			CheckRadioButton(hwnd, IDC_GS1, IDC_GS6,
				(GetParaInt("GS") &0x0f) + IDC_GS1);
			if(!(GetParaInt("GS") & 16))
				CheckDlgButton(hwnd, IDC_DPS, TRUE);
			for(s_pos = 0; s_pos < LAST_GFORM; )
				SendDlgItemMessage(hwnd, IDC_GIF, CB_ADDSTRING, 0,
					(LPARAM)gform[s_pos++]);
			SendDlgItemMessage(hwnd, IDC_GIF, CB_SETCURSEL, 
				GetParaInt("GIF"), 0);
			for(s_pos = 0; s_pos < LAST_CMODE; )
				SendDlgItemMessage(hwnd, IDC_CMODE, CB_ADDSTRING, 0,
					(LPARAM)cmode[s_pos++]);
			SendDlgItemMessage(hwnd, IDC_CMODE, CB_SETCURSEL, 
				GetParaInt("cmode"), 0);
			f_change = 0;
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){

				case ID_SAVE:
					ReserveAllPara(hwnd, para_tab);
					for(tmp=0; tmp<3; tmp++){
						if(IsDlgButtonChecked(hwnd, IDC_TPIC1+tmp)){
							s_pos = IsDlgButtonChecked(hwnd, IDC_TPICTATE)?16:0;
							ReserveIntPara("tpic", tmp+s_pos);
							break;
						}
					}
					for(tmp=0; tmp<6; tmp++){
						if(IsDlgButtonChecked(hwnd, IDC_GS1+tmp)){
							s_pos = IsDlgButtonChecked(hwnd, IDC_DPS)?0:16;
							ReserveIntPara("GS", tmp+s_pos);
							break;
						}
					}
					ReserveIntPara("GIF", SendDlgItemMessage(hwnd, IDC_GIF,
							CB_GETCURSEL, 0, 0L));
					ReserveIntPara("cmode", SendDlgItemMessage(hwnd, IDC_CMODE,
							CB_GETCURSEL, 0, 0L));
					break;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					RestoreAllPara(hwnd, para_tab, NULL);
					CheckRadioButton(hwnd, IDC_TPIC1, IDC_TPIC3,
						IDC_TPIC1 + (RestoreIntPara("tpic", 1) & 3));
					CheckDlgButton(hwnd, IDC_TPICTATE, 
						(RestoreIntPara("tpic", 1) & 16)?TRUE:FALSE);
					s_pos = RestoreIntPara("GS", 0);
					CheckRadioButton(hwnd, IDC_GS1, IDC_GS6, 
						IDC_GS1 + (s_pos&0x0f));
					CheckDlgButton(hwnd, IDC_DPS, !(s_pos&0x10));
					ApplyOn(hwnd, &f_change);
					SendDlgItemMessage(hwnd, IDC_GIF, CB_SETCURSEL, 
						RestoreIntPara("GIF", 0), 0);
					SendDlgItemMessage(hwnd, IDC_CMODE, CB_SETCURSEL, 
						RestoreIntPara("cmode", 0), 0);
					f_change |= 0xf;
					break;

				case IDC_TPIC1:
				case IDC_TPIC2:
				case IDC_TPIC3:
				case IDC_TPICTATE:
					ApplyOn(hwnd, &f_change);
					f_change |= 2;
					break;

				case IDC_GS1:
				case IDC_GS2:
				case IDC_GS3:
				case IDC_GS4:
				case IDC_GS5:
				case IDC_GS6:
				case IDC_DPS:
					ApplyOn(hwnd, &f_change);
					f_change |= 4;
					break;

				case IDC_GBOX:
				case IDC_GSIZE:
				case IDC_GFIT:
				case IDC_GOW:
				case IDC_GCLIP:
				case IDC_CCOLOR:
					goto check;

				case IDC_GSXB:
					if(AskYes("Automatic search?", "gswin32.exe") == TRUE){
						GetGS_LIB(common_work);
						if(*common_work)
							SetDlgItemText(hwnd, IDC_GSX, common_work);
						else
							ShowMessage( "Cannot find gswin32(c)",
								NULL , SM_OKCONT);
					}else if( (fname = QueryGeneralName(
						"Query Ghostscript (executable file)", 
						"Executable(*.exe;*.com;*.cmd;*.bat)",
						"*.exe;*.com;*.cmd;*.bat"
					 )) != NULL )
						SetDlgItemText(hwnd, IDC_GSX, fname);
					break;
			}
			switch(HIWORD(wParam)){
				case  EN_CHANGE:
check:				if(!(f_change & INIT_APPLY)
					  && CheckParaTab(para_tab, LOWORD(wParam))){
						ApplyOn(hwnd, &f_change);
						f_change |= 1;
					}
					break;
				case CBN_SELCHANGE:		// selection is changed
					if(!(f_change & INIT_APPLY)){
						ApplyOn(hwnd, &f_change);
						f_change |= 8;
					}
					break;
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PGRAPHIC);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_GRAPHIC)){
						case IDYES:			// change the current parameters
							if(f_change & 1)
								SetAllPara(hwnd, para_tab);
							if(f_change & 2){
								for(tmp=0; tmp<3; tmp++){
									if(IsDlgButtonChecked(hwnd, IDC_TPIC1+tmp)){
										s_pos = IsDlgButtonChecked(hwnd, IDC_TPICTATE)?16:0;
										SetParaInt("tpic", tmp+s_pos);
										break;
									}
								}
							}

							if(f_change & 4){
								for(tmp=0; tmp<6; tmp++){
									if(IsDlgButtonChecked(hwnd, IDC_GS1+tmp)){
										s_pos = IsDlgButtonChecked(hwnd, IDC_DPS)?0:16;
										SetParaInt("GS", tmp+s_pos);
									break;
									}
								}
							}
							if(f_change & 8){
								SetParaInt("GIF", 
									SendDlgItemMessage(hwnd, IDC_GIF,
									CB_GETCURSEL, 0, 0L)) ;
								SetParaInt("cmode", 
									SendDlgItemMessage(hwnd, IDC_CMODE,
									CB_GETCURSEL, 0, 0L)) ;
							}
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							InitParaTab(para_tab, FALSE);
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit1);
					ReSetFont(hedit2);
					ReSetFont(hedit3);
					break;
				
//				case PSN_QUERYCANCEL:		// cancel
//					break;

				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit1 = GetDlgItem( hwnd, IDC_GSX );
					hedit2 = GetDlgItem( hwnd, IDC_GDAT );
					hedit3 = GetDlgItem( hwnd, IDC_SPI );
					SetFontJE(hedit1);
					SetFontJE(hedit2);
					SetFontJE(hedit3);
					SetMargin(hedit1);
					SetMargin(hedit2);
					SetMargin(hedit3);
					break;
			}
			break;

		case WM_DESTROY:
			break;
	}
	return FALSE;
}


/*
 ******************************		Paper	   *****************************
 */

char *papersize_str[] =
{
/*
	"A3  29.70 x 42.00 cm",
	"A4  21.00 x 29.70 cm",
	"A5  14.85 x 21.00 cm",
	"B3  36.40 x 51.40 cm",
	"B4  25.70 x 36.40 cm",
	"B5  18.20 x 25.70 cm",
	"Post Card 10.00 x 14.80 cm",
	"Legal  21.59 x 35.56 cm",
	"Letter 21.59 x 27.94 cm",
	"Defined by User",
*/
	"A3   297 x 420 mm",
	"A4   210 x 297 mm",
	"A5   148 x 210 mm",
	"A6   105 x 148 mm",
	"A7    74 x 105 mm",
	"B3E  353 x 500 mm",
	"B4E  250 x 353 mm",
	"B5E  176 x 250 mm",
	"B6E  125 x 176 mm",
	"B3J  364 x 514 mm",
	"B4J  257 x 364 mm",
	"B5J  182 x 257 mm",
	"B6J  128 x 182 mm",
	"KIKU 127 x 188 mm",
	"46   127 x 188 mm",
	"NB   103 x 182 mm",
	"AB   210 x 257 mm",
	"Legal      8.5 x 14   in",
	"GovLegal   8.5 x 13   in",
	"Letter     8.5 x 11   in",
	"HalfLetter 5.5 x  8.5 in",
	"GovLetter  8   x 10.5 in",
	"Executive 7.25 x 14   in",
	"Post Card 100 x 148 mm",
	"SVGA  8.00 x  6.00 in",
	"XGA  10.24 x  7.68 in",
	"SXGA 12.80 x 10.24 in",
	"UVGA 10.67 x  8.00 in",
	"Defined by User",
};

char *para_paper[] =
{
	"A3",
	"A4",
	"A5",
	"A6",
	"A7",
	"E3",
	"E4",
	"E5",
	"E6",
	"B3",
	"B4",
	"B5",
	"B6",
	"J1", // kiku
	"J2", // 46
	"J3", // new book
	"J4", // AB
	"Legal",
	"GovLegal",
	"Letter",
	"HalfLetter",
	"GovLetter",
	"Executive",
	"H",
	"SVGA",
	"XGA",
	"SXGA",
	"UVGA",
	"F"
};

int trans_papersize[] = 
{
	SIZE_A3,
	SIZE_A4,
	SIZE_A5,
	SIZE_A6,
	SIZE_A7,
	SIZE_E3,
	SIZE_E4,
	SIZE_E5,
	SIZE_E6,
	SIZE_B3,
	SIZE_B4,
	SIZE_B5,
	SIZE_B6,
	SIZE_J1,
	SIZE_J2,
	SIZE_J3,
	SIZE_J4,
	SIZE_LEGAL,
	SIZE_GOVLEGAL,
	SIZE_LETTER,
	SIZE_HALFLETTER,
	SIZE_GOVLETTER,
	SIZE_EXECUTIVE,
	SIZE_PCARD,
	SIZE_SVGA,
	SIZE_XGA,
	SIZE_SXGA,
	SIZE_UVGA,
	SIZE_USR
};


LRESULT CALLBACK PaperTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	static UINT f_change;
	static HWND udWnd[7];
	char tmp[64];
	int s_pos, p_size, num, val0, val1, val;
	static struct KEY_TAB key_int[] = {
		{"OX", IDC_OX},
		{"OY", IDC_OY},
		{"edge", IDC_CUTEDGE},
		{NULL, 0}
	};
	static PARA_TAB para_tab[] =
	{
		{"OX",	IDC_OX, IDH_OX, TAB_LENGTH, 0},
		{"OY",	IDC_OY, IDH_OY, TAB_LENGTH, 0},
		{"HC",	IDC_HC, IDH_HC, TAB_BOOL, 0},
		{"VC",	IDC_VC, IDH_VC, TAB_BOOL, 0},
		{"HS",	IDC_HS, IDH_HS, TAB_LENGTH, 0},
		{"VS",	IDC_VS, IDH_VS, TAB_LENGTH, 0},
		{"edge", IDC_CUTEDGE, IDH_CUTEDGE, TAB_INT, 0},
		{"",	IDC_Y,	IDH_Y,	TAB_HELP, 0},
		{"",	IDC_PW, IDH_Y,	TAB_HELP, 0},
		{"",	IDC_PH, IDH_Y,	TAB_HELP, 0},
		{"",	IDC_GROUPBOX17, IDH_Y, TAB_HELP, 0},
		{NULL, 0, 0, 0 }
	};

#	define	LAST_SIZE (sizeof(papersize_str)/sizeof(char *))

	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			p_size = paper_type;

			for(num = 0; num < 7; num++){
				switch(num){
					case 0:
						val0 = 20; val1 = 20000; 
						val = (double)GetTextXSize()/GetXDpi()*254 + 0.5;
						break;
					case 1:
						val = GetYDpi();
						if(val == 0)
							val = GetXDpi();
						val = (double)GetTextYSize()/val*254 + 0.5;
						break;
					case 2:
						val0 = -20000; val1 = 20000;
						val = SPto10mm(OX);
						break;
					case 3:
						val = SPto10mm(OY);
						break;
					case 4:
						val0 = -4000; val1=4000; val = 0;
						break;
					case 5:
						break;
					case 6:
						val0 = 0; val1=1000; val = GetParaInt("edge");
				}
				udWnd[num] = CreateUpDownControl(
					WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
					| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
					50, 22, 20, 20, 
					hwnd,
					ID_UPDOWN,
					g_winData.hInstance,
					(HWND)GetDlgItem( hwnd, IDC_PW + num ),
					val1, val0, val );
			}

			for(s_pos = 0; s_pos < LAST_SIZE; )
				SendDlgItemMessage(hwnd, IDC_Y, CB_ADDSTRING, 0,
					(LPARAM)papersize_str[s_pos++]);

			for(s_pos = 0; s_pos < LAST_SIZE; s_pos++){
				if(trans_papersize[s_pos] == p_size)
					break;
			}
			if(s_pos >= LAST_SIZE)
				s_pos = LAST_SIZE - 1;
			SendDlgItemMessage(hwnd, IDC_Y, CB_SETCURSEL, s_pos, 0);

			if(HC){
				CheckDlgButton(hwnd, IDC_HC, TRUE);
				val = SPto10mm(HS);
				SendMessage( udWnd[4], UDM_SETPOS, 0, MAKELONG((WORD)val, 0));
			}
			if(VC){
				CheckDlgButton(hwnd, IDC_VC, TRUE);
				val = SPto10mm(VS);
				SendMessage( udWnd[5], UDM_SETPOS, 0, MAKELONG((WORD)val, 0));
			}
			CheckRadioButton(hwnd, IDC_RADIOBUTTON21, IDC_RADIOBUTTON22,
				(f_rotate)?IDC_RADIOBUTTON22:IDC_RADIOBUTTON21);

sel:		val0 = (s_pos < LAST_SIZE - 1)?FALSE:TRUE;
			EnableWindow(udWnd[0], val0);
			EnableWindow(GetDlgItem(hwnd, IDC_PW), val0);
			EnableWindow(udWnd[1], val0);
			EnableWindow(GetDlgItem(hwnd, IDC_PH), val0);
			EnableWindow(GetDlgItem(hwnd, IDC_TPW), val0);
			EnableWindow(GetDlgItem(hwnd, IDC_TPH), val0);

hvc:		val0 = IsDlgButtonChecked(hwnd, IDC_HC);
			EnableWindow(udWnd[4], val0);
			EnableWindow(GetDlgItem(hwnd, IDC_HS), val0);
			val0 = IsDlgButtonChecked(hwnd, IDC_VC);
			EnableWindow(udWnd[5], val0);
			EnableWindow(GetDlgItem(hwnd, IDC_VS), val0);
			if(f_change & INIT_APPLY){
				f_change = 0;
				return TRUE;
			}else
				return FALSE;

		case WM_COMMAND:

			switch( LOWORD(wParam) ){
				case ID_SAVE:
					tmp[0] = 0;
					s_pos = SendDlgItemMessage(hwnd, IDC_Y,
							CB_GETCURSEL, 0, 0L);
					if(s_pos >= 0 && s_pos < LAST_SIZE){
						strcpy(tmp, para_paper[s_pos]);
						if(s_pos == LAST_SIZE - 1){
							val0 = GetDlgItemInt( hwnd, IDC_PW, &val, TRUE);
							val1 = GetDlgItemInt( hwnd, IDC_PH, &val, TRUE);
							if(val0 < 20)
								val0 = 20;
							if(val0 > 20000)
								val0 = 20000;
							if(val1 < 20)
								val1 = 20;
							if(val1 > 20000)
								val1 = 20000;
							sprintf(tmp+1, print10mm(val0));
							strcat(tmp, ":");
							sprintf(tmp + strlen(tmp), print10mm(val1));
						}
						strcat(tmp,
							IsDlgButtonChecked(hwnd, IDC_RADIOBUTTON21)? 
							"P":"L");
						ReserveStringPara("y", tmp);
					}
					ReserveAllInt(hwnd, key_int);
					val = IsDlgButtonChecked(hwnd, IDC_HC);
					ReserveIntPara("HC", val);
					if(val)
						ReserveTabInt(hwnd, "HS", IDC_HS);
					val = IsDlgButtonChecked(hwnd, IDC_VC);
					ReserveIntPara("VC", val);
					if(val)
						ReserveTabInt(hwnd, "VS", IDC_VS);
					MessageSaved(hwnd);
					break;

				case ID_RESTORE:
					memset(tmp,0,sizeof(tmp));
					RestoreStringPara(tmp, 63, "Y");
					if(tmp[0]){
						for(s_pos= 0; s_pos < LAST_SIZE; s_pos++){
							if(strncmp(tmp, para_paper[s_pos],
							  strlen(para_paper[s_pos])) == 0)
								break;
						}
						if(s_pos < LAST_SIZE){
							val0 = (s_pos == LAST_SIZE-1)?TRUE:FALSE;
							EnableWindow(udWnd[0], val0);
							EnableWindow(GetDlgItem(hwnd, IDC_PW), val0);
							EnableWindow(GetDlgItem(hwnd, IDC_TPW), val0);
							EnableWindow(udWnd[1], val0);
							EnableWindow(GetDlgItem(hwnd, IDC_PH), val0);
							EnableWindow(GetDlgItem(hwnd, IDC_TPH), val0);
							if(val0){
								val = strlen(para_paper[s_pos]);
								SendMessage( udWnd[0], UDM_SETPOS, 0, 
									MAKELONG((WORD)atoi(tmp+val),0));
								while(tmp[val] && tmp[val++] != ':');
								if(tmp[val])
								  SendMessage( udWnd[1], UDM_SETPOS, 0, 
									MAKELONG((WORD)atoi(tmp+val),0));
							}
							val = strlen(tmp);
							if(val)
								CheckRadioButton(hwnd, 
									IDC_RADIOBUTTON21, IDC_RADIOBUTTON22,
									(tmp[val-1] == 'L')?
									IDC_RADIOBUTTON22:IDC_RADIOBUTTON21);
							SendDlgItemMessage(hwnd, IDC_Y,
								CB_SETCURSEL, s_pos, 0);
						}
					}
					RestoreTabInt(udWnd[2], "OX");
					RestoreTabInt(udWnd[3], "OY");

					val0 = RestoreIntPara("HC", 0);
					EnableWindow(udWnd[4], val0);
					EnableWindow(GetDlgItem(hwnd, IDC_HS), val0);
					RestoreTabInt(udWnd[4], "HS");

					val0 = RestoreIntPara("VC", 0);
					EnableWindow(udWnd[5], val0);
					EnableWindow(GetDlgItem(hwnd, IDC_VS), val0);
					RestoreTabInt(udWnd[5], "VS");

					RestoreTabInt(udWnd[6], "edge");

					ApplyOn(hwnd, &f_change);
					f_change = 15;
					break;

				case IDC_HC:
				case IDC_VC:
					ApplyOn(hwnd, &f_change);
					f_change |= 4;
					goto hvc;

				case IDC_RADIOBUTTON21:
				case IDC_RADIOBUTTON22:
					ApplyOn(hwnd, &f_change);
					f_change |= 1;
					break;
			}
			switch( HIWORD(wParam) ){
				case EN_CHANGE:
					switch( LOWORD(wParam) ){
						case IDC_PW:
						case IDC_PH:
							ApplyOn(hwnd, &f_change);
							f_change |= 1;
							break;
						case IDC_OX:
						case IDC_OY:
							ApplyOn(hwnd, &f_change);
							f_change |= 2;
							break;
						case IDC_HS:
						case IDC_VS:
							ApplyOn(hwnd, &f_change);
							f_change |= 4;
							break;
						case IDC_CUTEDGE:
							ApplyOn(hwnd, &f_change);
							f_change |= 8;
							break;
					}
					break;

				case CBN_SELCHANGE:		// selection is changed
					ApplyOn(hwnd, &f_change);
					f_change |= 1;
					s_pos = SendDlgItemMessage(hwnd, IDC_Y,
							CB_GETCURSEL, 0, 0L);
					goto sel;
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PPAPER);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_PAPER)){
						case IDYES:			// change the current parameters
						  if(f_change & 1){
							tmp[0] = 0;
							s_pos = SendDlgItemMessage(hwnd, IDC_Y,
								CB_GETCURSEL, 0, 0L);
							if(s_pos >= 0 && s_pos < LAST_SIZE)
							  strcpy(tmp, para_paper[s_pos]);
							if(s_pos == LAST_SIZE - 1){
								val0 = GetDlgItemInt( hwnd, IDC_PW, &val, TRUE);
								val1 = GetDlgItemInt( hwnd, IDC_PH, &val, TRUE);
								if(val0 < 20)
									val0 = 20;
								if(val0 > 20000)
									val0 = 20000;
								if(val1 < 20)
									val1 = 20;
								if(val1 > 20000)
									val1 = 20000;
								sprintf(tmp+1, print10mm(val0));
								strcat(tmp, ":");
								sprintf(tmp + strlen(tmp), print10mm(val1));
							}
							strcat(tmp, IsDlgButtonChecked(hwnd, IDC_RADIOBUTTON21)?
								"P":"L");
							SetParaString("y", tmp);
						  }

						  InitParaTab(para_tab, FALSE);
						  if(f_change & 2){
							para_tab[0].flag = para_tab[1].flag = TRUE;
						  }
//						  SetAllInt(hwnd, key_int);

						  if(f_change & 4){
							if(IsDlgButtonChecked(hwnd, IDC_HC))
								para_tab[4].flag = TRUE;
							if(IsDlgButtonChecked(hwnd, IDC_VC))
								para_tab[5].flag = TRUE;
						  }
						  if(f_change & 8)
							para_tab[6].flag = TRUE;
						  SetAllPara(hwnd, para_tab);
/*
							}
							HC = IsDlgButtonChecked(hwnd, IDC_HC);
							if(HC){
								val = GetDlgItemInt(hwnd, IDC_HS, &val0, TRUE);
								SetParaString("HS", print10mm(val));
							}
							VC = IsDlgButtonChecked(hwnd, IDC_VC);
							if(VC){
								val = GetDlgItemInt(hwnd, IDC_VS, &val0, TRUE);
								SetParaString("VS", print10mm(val));
							}
*/
						  InitParaTab(para_tab, FALSE);
						  f_change = 0;
						  g_bPropertySheetChange = TRUE;
						  break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;
#if	0
				case PSN_KILLACTIVE:
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
//				case PSN_QUERYCANCEL:		// cancel
//					break;
					
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					SetMargin(GetDlgItem(hwnd,IDC_PW));
					SetMargin(GetDlgItem(hwnd,IDC_PH));
					SetMargin(GetDlgItem(hwnd,IDC_OX));
					SetMargin(GetDlgItem(hwnd,IDC_OY));
					SetMargin(GetDlgItem(hwnd,IDC_HS));
					SetMargin(GetDlgItem(hwnd,IDC_VS));
					SetMargin(GetDlgItem(hwnd,IDC_CUTEDGE));
					break;
			}
			break;

		case WM_DESTROY:
			break;
	}
	return FALSE;
}


/*
 *********************************	 Font	  ******************************
 */
// *texroot	   : drive/directory	c:\ptex;d:
// *texpk	   : fonts				cmr10\0eufm10\0\0
// *subst	   : jfonts				min10\0tgoth10\0\0
// buf[0x1000] : work area
// dpi		   : dpi of fonts		dpi & dpi^1.2
//
// *texroot	   : TEXROOT="..."	or NULL
// *texpk	   : TEXPK="..."	or NULL
// *subst	   : F="..."		or NULL
// RETURN	   : -1	 tfm files matches
//				  0	 Cannot found fonts, texpk = NULL;
//				  1	 found (*texroot & *subst may be NULL)
int DetectFont(char **texroot, char **texpk, char **subst, char *buf, int dpi)
{
	char *s, *tmp;

	GuessFont(*texroot, *texpk, *subst, dpi);
	*texroot = *texpk = *subst = NULL;
	strncpy(s = buf, tmp_buf, 0xfff);
	if( (tmp = strstr(s, "TEXROOT=")) != NULL ){
		for(s = *texroot = tmp + 8; *s && *s!='\n'; s++);
		*s++ = 0;
	}
	if( (tmp = strstr(s, "TEXPK=")) != NULL ){
		for(s = *texpk = tmp + 6; *s && *s!='\n'; s++);
		*s = 0;
		for(s = *texpk; ; s++){
			if(*s == ';' && s > *texpk && *(s-1) != 'm')
				break;
			if(*s == 0){
				*texpk = NULL;
				return 0;
			}
//			if((*subst = checkjfm(*texpk)) != NULL)
//				return -1;
		}
		if( (tmp = strstr(s, "F=")) != NULL ){
			for(s = *subst = tmp + 2; *s && *s!='\n'; s++);
				*s = 0;
		}
	}
	return 1;
}


int GetGSS(char **tmptexroot, char **tmptexpk, char **find,	 char *tmp_pk)
{
	int i, drive, tmp;
	char *s;
	FILE *fp;

	if( (fp = fopenf(GetOutPath("gss" ), "rb")) == NULL)
		return 0;
	fread(tmp_pk, 0xfff, 1, fp);
	tmp_pk[0xfff] = 0;
	fclose(fp);
	for(i=drive=0; (tmp=tmp_pk[i])!= 0 && drive < 6; i++){
		if(tmp > ' '){
			switch(drive){
				case 0:
					if(tmp == '#'){
skpgss:					do{
							tmp_pk[i] = 0;
						}while(tmp_pk[++i] != '\n');
						i--;
						continue;
					}
					s = tmp_pk + i;
					drive = (tmp_pk[i+1]==':')?1:3;
					break;
				case 2:
				case 4:
					if(tmp == '#')
						goto skpgss;
					s = tmp_pk + i;
					drive++;
					break;
				case 3:
				case 5:
					if(tmp == ';')
						tmp_pk[i] = 0;
					break;
			}
		}else{
			tmp_pk[i] = 0;
			if(!(drive & 1))
				continue;
			switch(drive){
				case 1:
					*tmptexroot = s;
					break;
				case 3:
					*tmptexpk = s;
					break;
				case 4:
					*find = s;
					break;
			}
			drive++;
		}
	}
	tmp_pk[i] = tmp_pk[i+1] = 0;
	return 1;
}

void GetHDrive(char *s)
{
	int i, tmp, drive;
	char tmpname[0x10];

	drive = GetLogicalDrives();
	*s= 0;
	for(i=0, tmp = 1; i < 32; i++, tmp<<=1){
		if(drive & tmp){
			sprintf(tmpname, "%c:\\", i + 'A');
			if(GetDriveType(tmpname) == DRIVE_FIXED){
				sprintf(s, "%c:;", i + 'A');
				s += 3;
			}
		}
	}
	*(s-1) = 0;
}

#define	SEARCH_PK	"cmr10\0lcircle10\0dcr10\0ecr10\0msam10\0eufm10\0\0"
#define SEARCH_JFM	"min10\0tmin10\0\0"

LRESULT CALLBACK FontTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	static UINT f_change;
	int		tmp, i;
	char	*tmptexroot, *tmptexpk, *find;
	char	*tmpfontpath, *tmprootpath;
	char	tmpname[256];
	char	tmp_root[0x100];
	char	tmp_pk[0x1000];
	static HWND	udwnd[1];
	static HWND hedit1, hedit2, hedit3, hedit4;

	static char *tfms[] = {
		"cmr10", 
		"line10", "lcircle10", 
		"msam10", "eufm10", 
		"min10",  "tmin10"
	};
#	define	TOP_JFM	5

	static PARA_TAB para_tab[] =
	{
		{"TEXROOT",	 IDC_TEXROOT, IDH_PTEXROOT, TAB_STRING, 0},
		{"TEXPK",	 IDC_TEXPK,	  IDH_TEXPK,	TAB_STRING, 0},
		{"TEXFONTS", IDC_TEXFONTS,IDH_TEXFONTS, TAB_STRING, 0},
		{"F",		 IDC_F,		  IDH_F,		TAB_STRING, 0},
		{"",		 IDC_FTEST,	  IDH_CHECKFONT,TAB_HELP, 0},
		{"",		 IDC_CHECK,	  IDH_CHECKFONT,TAB_HELP, 0},
		{"",		 IDC_FDPI,	  IDH_CHECKFONT,TAB_HELP, 0},
		{"",		 IDC_TFMS,	  IDH_CHECKFONT,TAB_HELP, 0},
		{"",		 IDC_L,		  IDH_PL,		TAB_HELP, 0},
		{"",		 IDC_FB,	  IDH_FB,		TAB_HELP, 0},
		{"dpi",		 IDC_FDPI,	  IDH_CHECKFONT, TAB_INT, 0},
		{"",		 ID_GUESS,	  IDH_GUESS,	TAB_HELP, 0},
		{NULL,		 0, 0, 0, 0}
	};

	switch( message )
	{
		 case WM_INITDIALOG:
			for(tmp = 0; tmp < sizeof(tfms)/sizeof(char*); tmp++){
				SendDlgItemMessage( hwnd, IDC_TFMS, CB_ADDSTRING, 0, 
					(LPARAM)tfms[tmp]);
			}
			para_tab[10].type = TAB_INT;
			f_change = INIT_APPLY;
			InitParaTab(para_tab, TRUE);
			InitAllPara(hwnd, para_tab, udwnd);
			para_tab[10].type = TAB_HELP;
			InitParaTab(para_tab, FALSE);
			CheckRadioButton( hwnd, IDC_FB0, IDC_FB3, IDC_FB0 + f_sub_blank );
			CheckRadioButton( hwnd, IDC_L0,	 IDC_L2,  IDC_L0 + f_long_name );
			f_change = 0;
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){

				case ID_SAVE:
					GetDlgItemText( hwnd, IDC_TEXPK, tmp_pk, sizeof(tmp_pk));
/*
					if((find = checkjfm(tmp_pk)) != NULL){
						ShowWinHelp(IDH_ERRJFM);
						sprintf(tmp_pk, "%s\nCorrect TEXPK?", find);
						if(AskYes(tmp_pk, "Error") == TRUE)
							break;
					}
*/
					ReserveAllPara( hwnd, para_tab );
					for(tmp = IDC_FB0; tmp < IDC_FB3; tmp++){
						if(IsDlgButtonChecked( hwnd, tmp ))
							break;
					}
					ReserveIntPara("FB", tmp - IDC_FB0 );

					for(tmp = IDC_L0; tmp < IDC_L2; tmp++){
						if(IsDlgButtonChecked( hwnd, tmp ))
							break;
					}
					ReserveIntPara("L", tmp - IDC_L0);
					break;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					RestoreAllPara( hwnd, para_tab, NULL );
					tmp = RestoreIntPara("FB", WRONG_INT);
					if(tmp != WRONG_INT)
						CheckRadioButton( hwnd, IDC_FB0, IDC_FB3, 
							IDC_FB0 + tmp );
					tmp = RestoreIntPara("L", WRONG_INT);
					if(tmp != WRONG_INT)
						CheckRadioButton( hwnd, IDC_L0,	 IDC_L2,	
							IDC_L0 + tmp );
					ApplyOn(hwnd, &f_change);
					f_change |= 3;
					break;

				
				case IDC_L0:
				case IDC_L1:
				case IDC_L2:
				case IDC_FB0:
				case IDC_FB1:
				case IDC_FB2:
				case IDC_FB3:
					ApplyOn(hwnd, &f_change);
					f_change |= 2;
					break;

				case ID_GUESS:
					ChangeWaitCursor(1);
					DisplayWinMessage(hwnd, "");
					GetHDrive(tmptexroot = tmp_pk + 1);
					tmptexpk = SEARCH_PK;
					find = SEARCH_JFM;
					GetGSS(&tmptexroot, &tmptexpk, &find, tmp_pk);
												// tmp_pk+1:	C:;D:  etc.
					tmp = DetectFont(&tmptexroot, &tmptexpk, &find, 
						tmp_pk, GetXDpi());
					ChangeWaitCursor(0);
					DisplayMessage(NULL);

					if(tmp == 0 || tmptexpk == NULL){
						error(WARNING, "Cannot find fonts!");
						break;
					}
//					else if(tmp == -1)
//						goto tfmerr;
					if(tmptexroot)
						SetDlgItemText(hwnd, IDC_TEXROOT, tmptexroot);
					SetDlgItemText(hwnd, IDC_TEXPK, tmptexpk);
					if(find)
						SetDlgItemText(hwnd, IDC_F, find);
					CheckRadioButton( hwnd, IDC_L0,	 IDC_L2,  IDC_L0 + 2 );
					break;

				case IDC_CHECK:
					GetDlgItemText( hwnd, IDC_TEXPK, tmp_pk, sizeof(tmp_pk));
					tmpname[0] = 0;
					GetDlgItemText( hwnd, IDC_TFMS, tmpname, 256 );
//					if(!*tmpname){
//						if((find = checkjfm(tmp_pk)) != NULL){
// tfmerr:						ShowWinHelp(IDH_ERRJFM);
//							MessageBox( hwnd, find, "Warning", 
//								(MB_OK|MB_ICONEXCLAMATION));
//						}
//						break;
//					}
					if(IsDlgButtonChecked( hwnd, IDC_L0 ))
						tmpname[8] = 0;
					else if((tmp = strlen(tmpname)) > 8
					  && IsDlgButtonChecked( hwnd, IDC_L0+1 )){
						for(i = 4; i <= 8; i++)
							tmpname[i] = tmpname[tmp+i-8];
					}
					tmptexpk = pk_search_path;
					tmptexroot = root_search_path;
					tmprootpath = font_root_path?
							dup_string(font_root_path):NULL;
					tmpfontpath = font_search_path?
							dup_string(font_search_path):NULL;
					resolve_font_root_path();
					pk_search_path = tmp_pk;
					GetDlgItemText( hwnd, IDC_TEXROOT,
						root_search_path = tmp_root, 0xff);
					tmp = GetDlgItemInt( hwnd, IDC_FDPI, &tmp, TRUE );
					find = font_name_check(tmpname, tmp, tmp*5);
					if(find == NULL){
						MessageBox( hwnd, "Cannot find from TEXPK and TEXROOT!",
							tmpname, MB_OK|MB_ICONEXCLAMATION );
						goto qck;
					}
					strcpy( (char*)common_work + COMMON_SIZE - 0x1200, 
						to_font_name(find) );
					for(tmp = 0; tmp < TOP_JFM; tmp++){
						if(strcmp(tmpname, tfms[tmp]) == 0){
							find = font_name_check(tmpname, 5, 5);
							if(find == NULL){
								tmp = 1;
								break;
							}
							if(	 strcmpi(".tfm", find + strlen(find) - 4) == 0
							  && check_wintt(tmpname) == NULL ){
								strcat((char*)common_work + COMMON_SIZE-0x1200,
									"\nError in TEXPK for '.tfm'.\n"
									"It should only match jfm files.");
								tmp = 0;
							}else
								tmp = 1;
							break;
						}
					}
					MessageBox( hwnd, (char*)common_work + COMMON_SIZE - 0x1200, 
						!tmp?"Found but Error occured!":"Found!", 
						!tmp?(MB_OK|MB_ICONEXCLAMATION):MB_OK);
qck:				pk_search_path = tmptexpk;
					root_search_path = tmptexroot;
					Free0(font_root_path);
						font_root_path = tmprootpath;
					Free0(font_search_path);
						font_search_path = tmpfontpath;
					break;
			}
			switch( HIWORD(wParam) ){
				case EN_CHANGE:
					if( !(f_change & INIT_APPLY)
					  && LOWORD(wParam) != IDC_FDPI
					  && CheckParaTab(para_tab, LOWORD(wParam)) ){
						ApplyOn(hwnd, &f_change);
						f_change |= 1;
					}
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;
#if 0
		case WM_CONTEXTMENU:
			ShowWMContext(wParam, para_tab);
			break;
#endif
		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PFONT);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_FONT)){
						case IDYES:			// change the current parameters
							if(f_change & 1)
								SetAllPara(hwnd, para_tab);
							InitParaTab(para_tab, FALSE);
							if(f_change & 2){
								for(tmp = IDC_FB0; tmp < IDC_FB3; tmp++){
									if(IsDlgButtonChecked( hwnd, tmp ))
										break;
								}
								f_sub_blank = tmp - IDC_FB0;

								for(tmp = IDC_L0; tmp < IDC_L2; tmp++){
									if(IsDlgButtonChecked( hwnd, tmp ))
									break;
								}
								f_long_name = tmp - IDC_L0;
							}
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;


				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit1 = GetDlgItem( hwnd, IDC_TEXROOT );
					hedit2 = GetDlgItem( hwnd, IDC_TEXPK );
					hedit3 = GetDlgItem( hwnd, IDC_TEXFONTS );
					hedit4 = GetDlgItem( hwnd, IDC_F );
					SetFontJE(hedit1);
					SetFontJE(hedit2);
					SetFontJE(hedit3);
					SetFontJE(hedit4);
					SetMargin(hedit1);
					SetMargin(hedit2);
					SetMargin(hedit3);
					SetMargin(hedit4);
					SetMargin(GetDlgItem(hwnd,IDC_FDPI));
					sprintf((char*)common_work, "%d", GetXDpi());
					SetDlgItemText(hwnd, IDC_FDPI, (char*)common_work);
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit1);
					ReSetFont(hedit2);
					ReSetFont(hedit3);
					ReSetFont(hedit4);
					break;

//				case PSN_QUERYCANCEL:		// cancel
//					break;
					
			}
			break;
		
		case WM_DESTROY:
			break;
			
	}
	return FALSE;
}

void FlushPathCash(void){
	KeepPathCash(NULL, 0);
	Free0(path_cash);
	path_cash = NULL;
	f_path_cash = 0;
	SetParaFlag("Fkeep", !f_fkeep);
	SetParaFlag("Fkeep", f_fkeep);
	release_sfd_record();
}

/*
 *****************************	   Font2	 ******************************
 */
LRESULT CALLBACK Font2TabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	char *fname;
	char tmp[0x200];
	static UINT f_change;
	static HWND udWnd[2];
	static PARA_TAB para_tab[] = {
		{"gen",	   IDC_GEN,	   IDH_GEN, TAB_STRING, 0},
		{"ftt",	   IDC_FTT,	   IDH_FTT,	   TAB_PROC, 0},
		{"TEXSUBF",IDC_SUBFONT,IDH_SUBFONT,TAB_STRING, 0},
		{"TEXPKD", IDC_TEXPKD, IDH_TEXPKD, TAB_STRING, 0},
		{"TEXFLI", IDC_TEXFLI, IDH_TEXFLI, TAB_STRING, 0},
		{"A",	   IDC_A,	   IDH_A,	TAB_INT, 0},
		{"ttf",	   IDC_TTF,	   IDH_TTF, TAB_INT, 0},
		{"c",	   IDC_C,	   IDH_C,	TAB_BOOL, 0},
		{"Fkeep",  IDC_FKEEP,  IDH_FKEEP, TAB_BOOL, 0},
		{"virtual",IDC_VIRTUAL,IDH_VIRTUAL,TAB_BOOL, 0},
		{"Fod",	   IDC_FOD,	   IDH_FOD,	TAB_BOOL, 0},
		{"",	   IDC_GENB,   IDH_GEN, TAB_HELP, 0},
		{"",	   IDC_FTTB,   IDH_FTT,	   TAB_HELP, 0},
		{"",	   IDC_FLUSH,  IDH_FLUSH, TAB_HELP, 0},
		{NULL,		0,			0,		0,		0}
	};
	static HWND hedit1, hedit2, hedit3, hedit4, hedit5;

	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			InitParaTab(para_tab, TRUE);
			InitAllPara(hwnd, para_tab, udWnd);
			InitParaTab(para_tab, FALSE);
			f_change = 0;
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){
				FILE *fp;

				case ID_SAVE:
					ReserveAllPara(hwnd, para_tab);
					break;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					RestoreAllPara(hwnd, para_tab, udWnd);
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
					break;

				case IDC_C:
				case IDC_FKEEP:
				case IDC_VIRTUAL:
				case IDC_FOD:
					goto check;

				case IDC_GENB:
					if(AskYes("Automatic search?", "mktexpk/makepk/MaKeTeXPK")
					  == TRUE){
						*tmp = '`';
						strcpy(tmp+1, "mktexpk.exe");
						SearchFile(tmp+1);
						if(*(tmp+1)){
							strcat(tmp, 
							  "mktexpk.exe --dpi ^d --bdpi ^D --mag ^M ^s");
							SetDlgItemText(hwnd, IDC_GEN, tmp);
							break;
						}
						strcpy(tmp+1, "makepk.exe");
						SearchFile(tmp+1);
						if(*(tmp+1)){
							strcat(tmp, 
							  "makepk.exe ^s ^d ^D ^M");
							SetDlgItemText(hwnd, IDC_GEN, tmp);
							break;
						}
						strcpy(tmp+1, "MakeTeXPK.exe");
						SearchFile(tmp+1);
						if(*(tmp+1)){
							strcat(tmp, 
							  "MakeTeXPK.exe ^s ^d ^D ^M");
							SetDlgItemText(hwnd, IDC_GEN, tmp);
						}else
							ShowMessage("Cannot find mktexpk/makepk/MakeTeXPK",
								NULL , SM_OKCONT);
					}else
					if( (fname = QueryGeneralName(
						"Query template file to make fonts", 
						"Template file(*.*)", "*.*"
					 )) != NULL )
						SetDlgItemText(hwnd, IDC_GEN, fname);
					break;

				case IDC_FTTB:
					fname = "^x\\map\\ttfonts.map";
					fp = fopenf(fname, "r");
					if(fp != NULL){
						fclose(fp);
						if(AskYes(
						  "Use the map\\ttfonts.map in the directory of dviout?",
						  "Setting ftt:"))	goto set_ftt;
					}
					if( (fname = QueryGeneralName(
						"Query the map : tfm -> TrueType",
						"Font map(*.map)", "*.map"
					 )) != NULL ) 
set_ftt:			SetDlgItemText(hwnd, IDC_FTT, fname);
					break;

				case IDC_FLUSH:
					FlushPathCash();
					break;
			}
			if( HIWORD(wParam) == EN_CHANGE ){
check:			if(!(f_change & INIT_APPLY)
				  && CheckParaTab(para_tab, LOWORD(wParam))){
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
				}
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PFONT2);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_FONT2)){
						case IDYES:			// change the current parameters
							SetAllPara(hwnd, para_tab);
							f_change = 0;
							g_bPropertySheetChange = TRUE;;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit1);
					ReSetFont(hedit2);
					ReSetFont(hedit3);
					ReSetFont(hedit4);
					ReSetFont(hedit5);
					break;


//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit1 = GetDlgItem( hwnd, IDC_GEN );
					hedit2 = GetDlgItem( hwnd, IDC_FTT );
					hedit3 = GetDlgItem( hwnd, IDC_TEXPKD );
					hedit4 = GetDlgItem( hwnd, IDC_TEXFLI );
					hedit5 = GetDlgItem( hwnd, IDC_SUBFONT );
					SetFontJE(hedit1);
					SetFontJE(hedit2);
					SetFontJE(hedit3);
					SetFontJE(hedit4);
					SetFontJE(hedit5);
					SetMargin(hedit1);
					SetMargin(hedit2);
					SetMargin(hedit3);
					SetMargin(hedit4);
					SetMargin(hedit5);
					SetMargin(GetDlgItem(hwnd,IDC_A));
					SetMargin(GetDlgItem(hwnd,IDC_TTF));
					break;

			}
			break;

		case WM_DESTROY:
			break;

	}
	return FALSE;
}

/*
 ***************************  WinJFont	************************************
 */

static int f_Jfont = 1;
static int f_tfont = 0;

static int CALLBACK EnumFontProc( ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm, 
						   int nFontType, LPARAM lParam )
{
   // Load only TrueType fonts into the list box.
   //............................................
   if (nFontType & TRUETYPE_FONTTYPE){
	 if(!f_tfont){
get:
		if(	 lpntm->tmCharSet == SHIFTJIS_CHARSET
		  || lpntm->tmCharSet == HANGEUL_CHARSET 
		  || lpntm->tmCharSet == GB2312_CHARSET
		  || lpntm->tmCharSet == CHINESEBIG5_CHARSET ){
			  if(!f_Jfont)	return(TRUE);
		}else if(f_Jfont)	return(TRUE);
		if ( IsWindow( (HWND)lParam ) ){
			 SendMessage( (HWND)lParam, CB_ADDSTRING, 0, 
					  (LPARAM)lpelf->elfLogFont.lfFaceName );
//	error(14, "%s %d %d", lpelf->elfLogFont.lfFaceName, lpntm->tmFirstChar, lpntm->tmLastChar);
	   }
	 }
   }else if(f_tfont)
		goto get;
   return( TRUE );
}

#if 0
static int CALLBACK FindFontProc( ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm, 
						   int nFontType, LPARAM lParam )
{
	if(strcmp( lpelf->elfStyle, "Regular") == 0) 
		memcpy((LOGFONT*)lParam, &lpelf->elfLogFont, sizeof(LOGFONT));
	return TRUE;
}
#endif

static char *wj_result;

extern struct FONT_ATTR {
	char *key;
	int type;
} font_attr[];

static int GetCharSet(char *name)
{
	int i;

	for(i=0; font_attr[i].key[0] != 0x7f; i++){
		if((font_attr[i].type & 0x10000) && !strcmp(name, font_attr[i].key))
			return (font_attr[i].type & 0xffff);
	}
	return -1;
}

static BOOL CALLBACK WinJFontListProc( HWND hDlg, UINT message, 
								WPARAM wParam, LPARAM lParam )
{
	LOGFONT lf;
	HFONT hFont;
	HFONT hOldFont;
	HDC	hDC;
	int attr, i;
	char *s;
	HWND hwnd;
	HBRUSH	hOldBrush;
	static HWND hfontlist;

	switch( message )
	{
		case WM_INITDIALOG:
			f_tfont = 0;
			hfontlist = GetDlgItem(hDlg, IDC_WINJTTLIST);
			SetFontJE(hfontlist);
			for(attr=0; font_attr[attr].key[0] != 0x7f; attr++){
				if(font_attr[attr].type & 0x10000)
					SendDlgItemMessage( hDlg, IDC_CHARSET, CB_ADDSTRING, 0, 
						(LPARAM)font_attr[attr].key);
			}
			EnableWindow(GetDlgItem(hDlg, IDC_CHARSET), FALSE);
			EnableWindow(GetDlgItem(hDlg, IDC_JIS2UNI), FALSE);
			EnableWindow(GetDlgItem(hDlg, IDC_CID2UNI), FALSE);
			CheckDlgButton(hDlg, IDC_SPECIAL, TRUE);
start:		hDC = GetDC( hDlg );
			EnumFontFamilies( hDC, NULL, (FONTENUMPROC)EnumFontProc, 
				(LPARAM)hfontlist );
			ReleaseDC( hDlg, hDC );
			SendDlgItemMessage(hDlg, IDC_WINJTTLIST,
				CB_SETCURSEL, 0, 0);
			return TRUE;

		case WM_COMMAND:
			switch( wParam ){
				case IDC_USESET:
					EnableWindow(GetDlgItem(hDlg, IDC_CHARSET), 
					  IsDlgButtonChecked(hDlg, IDC_USESET));
				case IDC_ITALIC:
				case IDC_BOLD:
				case IDC_TULINE:
				case IDC_STRIKEOUT:
//				case IDC_REGULAR:
					goto slc;
				case IDC_UNICODE:
					EnableWindow(GetDlgItem(hDlg, IDC_JIS2UNI), 
					  IsDlgButtonChecked(hDlg, IDC_UNICODE));
					EnableWindow(GetDlgItem(hDlg, IDC_CID2UNI), 
					  IsDlgButtonChecked(hDlg, IDC_UNICODE));
					goto slc;
				case IDC_JIS2UNI:
					if(IsDlgButtonChecked(hDlg, IDC_JIS2UNI))
						CheckDlgButton(hDlg, IDC_CID2UNI, FALSE);
					goto slc;
				case IDC_CID2UNI:
					if(IsDlgButtonChecked(hDlg, IDC_CID2UNI))
						CheckDlgButton(hDlg, IDC_JIS2UNI, FALSE);
					goto slc;
				case IDC_SPECIAL:
					f_tfont = !IsDlgButtonChecked(hDlg, IDC_SPECIAL);
					SendDlgItemMessage(hDlg, IDC_WINJTTLIST, CB_RESETCONTENT,
						0, 0);
					hwnd = GetDlgItem(hDlg, IDC_SAMPLE);
					hDC = GetDC(hwnd); 
					hOldBrush = 
						SelectObject(hDC, GetStockObject( LTGRAY_BRUSH ));
					PatBlt(hDC, 1, 1, 400, 50, PATCOPY);
					SelectObject(hDC, hOldBrush);
					goto start;
				case ID_MYHELP:
					ShowWinHelp(IDH_TTSELECT);
					return TRUE;
				case IDOK:
					if(SendDlgItemMessage(hDlg, IDC_WINJTTLIST,
					  CB_GETCURSEL,0, 0) != CB_ERR){
						GetDlgItemText( hDlg, IDC_WINJTTLIST, 
						  wj_result = (char*)common_work, 128 );
						common_work[0x100] = '/';
						attr = 0x101;
						if(IsDlgButtonChecked(hDlg, IDC_ITALIC))
							common_work[attr++] = 'I';
						if(IsDlgButtonChecked(hDlg, IDC_BOLD))
							common_work[attr++] = 'B';
						if(IsDlgButtonChecked(hDlg, IDC_STRIKEOUT))
							common_work[attr++] = 'O';
						if(IsDlgButtonChecked(hDlg, IDC_TULINE))
							common_work[attr++] = 'U';
						if(IsDlgButtonChecked(hDlg, IDC_REGULAR))
							common_work[attr++] = 'R';
						if(IsDlgButtonChecked(hDlg, IDC_UNICODE)){
							common_work[attr++] = 'C';
							if(IsDlgButtonChecked(hDlg, IDC_JIS2UNI)){
								strcpy(common_work+attr, "[932]");
								attr+=5;
							}else if(IsDlgButtonChecked(hDlg, IDC_CID2UNI)){
								strcpy(common_work+attr, "[-2]");
								attr+=4;
							}
						}
						if(	 IsDlgButtonChecked(hDlg, IDC_USESET)
						  && SendDlgItemMessage(hDlg, IDC_CHARSET,
							   CB_GETCURSEL,0, 0) != CB_ERR){
							GetDlgItemText( hDlg, IDC_CHARSET, 
								common_work + 0x200, 32 );
							i = GetCharSet(common_work + 0x200);
							if(i >= 0){
								sprintf(common_work+attr, "(%d)", i);
								attr += strlen(common_work + attr);
							}
						}
						if(attr > 0x101){
							common_work[attr] = 0;
							strcat(common_work, common_work + 0x100);
						}
						common_work[0x100] = 0;
						if(!IsDlgButtonChecked(hDlg, IDC_SPECIAL))
							attr |= 0x1000;
						if(  strchr(common_work+0x101, 'O')
						  || strchr(common_work+0x101, 'U') ){
							sprintf(common_work+0x100, 
							  "This attribute can be used only in patch2 mode.\n"
							  "[Graphic] -> color speiclas(-cmode:)\n");
							if(MessageBox(hDlg, (char *)common_work+0x100,
							  "Warning", MB_OKCANCEL) == IDCANCEL)
								goto cancel;
						}
						goto enddlg;
					}
				case IDCANCEL:
cancel:				wj_result = NULL;
enddlg:				EndDialog( hDlg, 0 );
					return TRUE;
			}

			if(HIWORD(wParam) == CBN_SELCHANGE){
				char selectfont[36];

slc:			if(SendDlgItemMessage(hDlg, IDC_WINJTTLIST, CB_GETCURSEL,0, 0) 
					== CB_ERR) break;
				hwnd = GetDlgItem(hDlg, IDC_SAMPLE);
				hDC = GetDC(hwnd); 

				GetDlgItemText(hDlg, IDC_WINJTTLIST, lf.lfFaceName, LF_FACESIZE);
				attr = IsDlgButtonChecked(hDlg, IDC_UNICODE);
				if(	 IsDlgButtonChecked(hDlg, IDC_USESET)
					&& SendDlgItemMessage(hDlg, IDC_CHARSET, 
					  CB_GETCURSEL,0, 0) != CB_ERR){
					GetDlgItemText( hDlg, IDC_CHARSET, common_work, 32 );
					i = GetCharSet(common_work);
				}else
					i = -1;

				lf.lfCharSet = (i>=0)?i:
					((attr)?0:(f_Jfont?SHIFTJIS_CHARSET:ANSI_CHARSET));
					// 文字セット
				lf.lfHeight = 40;
				lf.lfWeight = IsDlgButtonChecked(hDlg, IDC_BOLD)?700:400;
					// フォントの太さ（標準400, 太字700, 0=デフォルト）
				lf.lfWidth	= 0;	 // デバイスのアスペクト比。
				lf.lfEscapement = 0; // テキスト行の角度。（1/10度単位）
				lf.lfOrientation = 0; // ベースラインの角度。（1/10度単位）
				lf.lfItalic = IsDlgButtonChecked(hDlg, IDC_ITALIC); 
					// 斜体フォント
				lf.lfUnderline = IsDlgButtonChecked(hDlg, IDC_TULINE); 
					// 下線付きフォント
				lf.lfStrikeOut = IsDlgButtonChecked(hDlg, IDC_STRIKEOUT);
					// 打ち消し線付きフォント
				lf.lfOutPrecision = OUT_DEFAULT_PRECIS; // 出力精度
				lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; // クリッピング精度
				lf.lfQuality = PROOF_QUALITY; // 出力品質。最高級。サイズが一致しないことあり。
				lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;

				hOldBrush = SelectObject(hDC, GetStockObject( LTGRAY_BRUSH ));
				PatBlt(hDC, 1, 1, 400, 50, PATCOPY);
				SelectObject(hDC, hOldBrush);
				hFont = CreateFontIndirect(&lf);
				hOldFont = SelectObject(hDC, hFont);

				s = f_Jfont?"泥部位愛あウと":"dviout for Win!";
				if(!attr)
					TextOut(hDC, 1, 1, s, f_Jfont?14:15);
				else{					/* unicode */ 
					if(!f_Jfont){
						for(i=0; i < 15; i++){
							common_work[2*i] = s[i];
							common_work[2*i+1] = 0;
						}
					}else
						MultiByteToWideChar(932, 0, s, -1,
							(LPWSTR)common_work, 0x100);
					if(TextOutW(hDC, 1, 1, (const unsigned short*)common_work,
					  f_Jfont?7:15) == 0){
						if( (i = GetLastError())
							== ERROR_CALL_NOT_IMPLEMENTED )
							error( ERRPAUSE, "The unicode version is\n"
									"not implemented in this OS." );
						else
							error( ERRPAUSE, "The OS returns the error"
									" code %d", i );
					}
				}
				GetTextFace(hDC, 32, selectfont );
				if(strcmp(selectfont, lf.lfFaceName))
					MessageBox(hDlg, 
						"Requested font is not available!\nIt is substituted.\n",
						"Warning", MB_OK);
				SelectObject(hDC, hOldFont);
				ReleaseDC(hwnd, hDC);
				DeleteObject(hFont);
			}
			break;

		case WM_DESTROY:
			ReSetFont(hfontlist);
			break;
	}
	return FALSE;
}

static char *hei_str[] =
{
	"normal",			// a
	"long 10%",		// b
	"long 20%",		// c
	"long 30%",		// d
	"long 40%",		// e
	"flat 10%",		// g
	"flat 20%",		// h
	"flat 30%",		// i
	"flat 40%"		// j
};

static char *sha_str[] =
{
	"normal",		// a
	"x +10 deg",	// b
	"x +20 deg",	// c
	"x +30 deg",	// d
	"x -10 deg",	// e
	"x -20 deg",	// f
	"x -30 deg",	// g
	"y +10 deg",	// h
	"y +20 deg",	// i
	"y +30 deg",	// j
	"y -10 deg",	// k
	"y -20 deg",	// l
	"y -30 deg"		// m
};

static char *kaiten_str[] =
{
	"horizontal",		 // 0
	"vertical",			 // 1
	"-horizontal",		 // 2
	"-vertical"			 // 3
};

static char *thin_str[] =
{
	"BaKoMa",			// 0
	"WinTeX",			// 1
	"direct"			// 2
};

#if 0
LRESULT CALLBACK NonJapaneseTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	switch(message){
		case WM_INITDIALOG:
			SetDlgItemText(hwnd, IDC_TOPTEXT,
				"\n\n\t\tThis sheet is not valid"
				"\n\n\t\t\t  for\n\n\t\tnon-Japanese Windows95/NT."
			);
			return TRUE;
	}
	return FALSE;
}
#endif

LRESULT CALLBACK WinJFontTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	static DWORD help[] = {
		IDC_JFONTLIST,	IDH_WJTRUETYPE,
		IDC_JHSCALE,	IDH_WJHSCALE,
		IDC_JVSCALE,	IDH_WJVSCALE,
		IDC_JFM,		IDH_WJJFM,
		IDC_SHATAI,		IDH_WJSHA,
		IDC_HEITAI,		IDH_WJHEI,
		IDC_KAITEN,		IDH_WJMUKI,
		IDC_JXPOS,		IDH_WJHPOSITION,
		IDC_JYPOS,		IDH_WJVPOSITION,
		IDC_JDEFINE,	IDH_WJDEFINE,
		IDC_JREMOVE,	IDH_WJREMOVE,
		IDC_JBOLD,		IDH_WJBOLD,
		IDC_JGET,		IDH_ADDFONT,
		IDC_CHANGEFONT,	IDH_CHANGEFONT,
		ID_RESTORE,		IDH_RESTORE,
		ID_SAVE,		IDH_PSAVE,
		IDC_DEFAULT,	IDH_DEFAULT,
		IDC_CHECK1,		IDH_JTT,
		0, 0
	};
	static int max_wjfont;
	static int max_jtexfont;
	static HWND udWnd[4];
	V_JFM *vjfm_tmp;
	int wjf, tf, num, val, val0, val1, pos;
	static UINT f_change;
	char szName[128], *pt;
	struct WINJF {
		short hsc;
		short vsc;
	};
	struct JFM {
		short hpos;
		short vpos;
		short thin;
		char rot;
		char sha;
		char hei;
		char pt;
	};
	static struct WINJF winjf[256];
	static struct JFM jfm[256];
	static HWND hedit, hcombo;

	switch( message )
	{
		case WM_INITDIALOG:
			if(f_init & INIT_ENDCFG){
				end_config();
				f_init &= ~INIT_ENDCFG;
			}
			if(!IsJapanese()){
				f_Jfont = 0;
				EnableWindow(GetDlgItem(hwnd, IDC_CHECK1), FALSE);
			}else
				CheckDlgButton(hwnd, IDC_CHECK1, f_Jfont);
			f_change = INIT_APPLY;
			val0 = 300;
			val1 = 4000;
			val = 1000;
			for(num=0; num < 4; num++){
				if(num == 2){
					val0 = -2000;
					val1 = 2000;
					val = 0;
				}
				udWnd[num] = CreateUpDownControl(
					WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
					| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
					50, 22, 20, 20, 
					hwnd,
					ID_UPDOWN,
					 g_winData.hInstance,
					(HWND)GetDlgItem( hwnd, IDC_JHSCALE + num ),
					val1, val0, val );
			}
			for(num = 0; num < sizeof(thin_str)/sizeof(char *); num++){
				SendDlgItemMessage(hwnd, IDC_JBOLD, CB_ADDSTRING, 0,
					(LPARAM)thin_str[num]);
			}
			for(num = 0; num < sizeof(kaiten_str)/sizeof(char *); num++){
				SendDlgItemMessage(hwnd, IDC_KAITEN, CB_ADDSTRING, 0,
					(LPARAM)kaiten_str[num]);
			}
			for(num = 0; num < sizeof(hei_str)/sizeof(char *); num++){
				SendDlgItemMessage(hwnd, IDC_HEITAI, CB_ADDSTRING, 0,
					(LPARAM)hei_str[num]);
			}
			for(num = 0; num < sizeof(sha_str)/sizeof(char *); num++){
				SendDlgItemMessage(hwnd, IDC_SHATAI, CB_ADDSTRING, 0,
					(LPARAM)sha_str[num]);
			}
			for(max_wjfont=0; max_wjfont < MAX_VFONT; max_wjfont++){
				if(vfont[max_wjfont] == &dummy)
					break;
				if(vfont[max_wjfont]->v_font_name[0] != ' '){
					max_wjfont = 0;
					break;
				}
			}
			for(wjf = 0; wjf < max_wjfont; wjf++){
				SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_ADDSTRING, 0,
					(LPARAM)(vfont[wjf]->v_font_name + 1));
				winjf[wjf].hsc = (short)(vfont[wjf]->width_adj);
				winjf[wjf].vsc = (short)(vfont[wjf]->height_adj);
			}
			max_jtexfont = 0;
			for(vjfm_tmp = vjfm_top; vjfm_tmp != NULL && max_jtexfont < 256; 
			  vjfm_tmp = vjfm_tmp->next){
				SendDlgItemMessage(hwnd, IDC_JFM, CB_ADDSTRING, 0,
					(LPARAM)(vjfm_tmp->name));
				jfm[max_jtexfont].hpos = (short)(vjfm_tmp->_xfat);
				jfm[max_jtexfont].vpos = (short)(vjfm_tmp->_yfat);
				jfm[max_jtexfont].thin = (short)(vjfm_tmp->thin);
				jfm[max_jtexfont].rot  = (short)(vjfm_tmp->rotation);
				jfm[max_jtexfont].hei  = (char)(vjfm_tmp->long_wide);
				jfm[max_jtexfont].sha  = (char)(vjfm_tmp->slant);
				jfm[max_jtexfont++].pt = (short)(vjfm_tmp->font_no);
			}
set0:		wjf = tf = 0;
			if(max_jtexfont > 0)
				wjf = jfm[0].pt;
set:		if(wjf < max_wjfont){
				SendDlgItemMessage(hwnd, IDC_JFONTLIST,
					CB_SETCURSEL, wjf, 0L);
				SendMessage( udWnd[0], UDM_SETPOS, 0, 
					MAKELONG((WORD)winjf[wjf].hsc, 0));
				SendMessage( udWnd[1], UDM_SETPOS, 0, 
					MAKELONG((WORD)winjf[wjf].vsc, 0));
			}
			if(tf < max_jtexfont){
				SendDlgItemMessage(hwnd, IDC_JFM,
					CB_SETCURSEL, tf, 0L);
				SendMessage( udWnd[2], UDM_SETPOS, 0, 
					MAKELONG((WORD)jfm[tf].hpos, 0));
				SendMessage( udWnd[3], UDM_SETPOS, 0, 
					MAKELONG((WORD)jfm[tf].vpos, 0));
				num = jfm[tf].hei - 'a';
				if(num > 'f' - 'a')
					num--;
				SendDlgItemMessage(hwnd, IDC_HEITAI,
					CB_SETCURSEL, num, 0L);
				SendDlgItemMessage(hwnd, IDC_SHATAI, 
					CB_SETCURSEL, jfm[tf].sha - 'a', 0L);
				SendDlgItemMessage(hwnd, IDC_KAITEN, 
					CB_SETCURSEL, jfm[tf].rot, 0L);
				SendDlgItemMessage(hwnd, IDC_JBOLD,
					CB_SETCURSEL, jfm[tf].thin, 0L);

			}
			if(f_Jfont)
				EnableWindow(GetDlgItem(hwnd, IDC_JBOLD), FALSE);
			if(f_change & INIT_APPLY){
				f_change = 0;
				return TRUE;
			}
j_num:		pos = SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_GETCURSEL, 0, 0L);
			if(pos >= 0){
				sprintf(common_work, " %d", pos+1);
				SetDlgItemText(hwnd, IDC_JFNUM, common_work);
			}
			return FALSE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){

				case ID_SAVE:
define:				strcpy((char*)common_work, "\n%version=2\n%vfont_list\n");
					num = 0;
					for(wjf = 0; wjf < max_wjfont; wjf++){
						num += strlen((char*)common_work+num);
						szName[0] = 0;
						SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_GETLBTEXT,
							wjf, (LPARAM)szName);
						wsprintf((char*)common_work + num,
							"%d,\042%s\042", wjf+1, szName);
						num += strlen((char *)common_work+num);
						if(winjf[wjf].hsc == 1000 && winjf[wjf].vsc == 1000)
							wsprintf((char *)common_work + num, "\n");
						else
							wsprintf((char *)common_work + num, ",%d,%d\n",
								winjf[wjf].hsc, winjf[wjf].vsc);
					}
					strcat((char*)common_work + num, "%jfm_list\n");
					for(tf = 0; tf < max_jtexfont; tf++){
						num += strlen((char*)common_work+num);
						szName[0] = 0;
						SendDlgItemMessage(hwnd, IDC_JFM, CB_GETLBTEXT,
							tf, (LPARAM)szName);
						wsprintf((char*)common_work + num,
							"%d,\042%s\042,%d,%d,0\n",
							num, szName, winjf[wjf].hsc, winjf[wjf].vsc);
						wsprintf((char*)common_work + num,
							"%s,%d,%c,%c,n,%d;%d;%d,,1,%d\n",
							szName, jfm[tf].pt+1,
							jfm[tf].hei, jfm[tf].sha,
							jfm[tf].thin,
							jfm[tf].hpos, jfm[tf].vpos,
							jfm[tf].rot);
					}
					if(message == WM_COMMAND){
						ReserveStringPara("vfn", (char*)common_work);
						MessageSaved(hwnd);
					}
					else
						SetParaStringDirect("vfn", (char*)common_work);
					break;

				case IDC_DEFAULT:
					strcpy((char*)common_work, vfn_org);
					goto r_new;

				case ID_RESTORE:
					RestoreStringPara((char*)common_work, 0x1000, "vfn");
r_new:				if(common_work[0] != '\n')
						break;
					num = 1;
r_err:				SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_RESETCONTENT,
						0, 0);
					SendDlgItemMessage(hwnd, IDC_JFM, CB_RESETCONTENT,
						0, 0);
					max_wjfont = max_jtexfont = 0;
					if(!num)
						break;
					num = 0;
					pos = 1;
					while(1){
						pt = (char*)common_work + pos;
						if(*pt == 0)
							break;
						while(common_work[pos] != 0){
							if(common_work[pos] == '\n'){
								common_work[pos++] = 0;
								break;
							}
							pos++;
						}

						/* キーワードのチェック */
						if (*pt == '%') {
							if (strcmp(pt+1, "vfont_list") == 0)
								num = 1;
							else if (strcmp(pt+1, "jfm_list") == 0)
								num = 2;
							continue;
						}

						if (num == 0)
							goto r_err;
						if (num == 1) {
							/* ベクトルフォントの情報を取得 */
							if (get_term(szName, pt, 2, DELIM1) == 0 ||
							  szName[0] != ' ')
								continue;
							SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_ADDSTRING, 0,
								(LPARAM)(szName+1));

							/* 幅のアジャスト */
							winjf[max_wjfont].hsc = 
								(get_term(szName, pt, 3, DELIM1))?
								atoi(szName):1000;

							/* 高さのアジャスト Tomiie */
							winjf[max_wjfont++].vsc = 
								(get_term(szName, pt, 4, DELIM1))?
								atoi(szName):1000;
						}else {
							/* 各 JFM に対応するベクトルフォントの番号、
							フォントの変形、およびフォント描画方法を取得 */
							if (get_term(szName, pt, 1, DELIM1) == 0)
								continue;
							SendDlgItemMessage(hwnd, IDC_JFM, CB_ADDSTRING, 0,
								(LPARAM)szName);
							if (get_term(szName, pt, 2, DELIM1) == 0)
								continue;
							jfm[max_jtexfont].pt = (short)(atoi(szName)-1);

							/* 長／平体のチェック */
							jfm[max_jtexfont].hei =
								(get_term(szName, pt, 3, DELIM1))?
								szName[0]:'a';

							/* 斜体のチェック */
							jfm[max_jtexfont].sha  =
								(get_term(szName, pt, 4, DELIM1))?
								szName[0]:'a';

							/* rotation の読み取り */
							jfm[max_jtexfont].rot  =
								(get_term(szName, pt, 9, DELIM1))?
								(atoi(szName)%4):0;

							/* フォント線幅調整パラメータの読み取り */
							val = get_term(szName, pt, 6, DELIM1);
							jfm[max_jtexfont].thin = 
								(val&&get_term(szName+64, szName, 1, DELIM2))?
								atoi(szName + 64):0;
							jfm[max_jtexfont].hpos = 
								(val&&get_term(szName+64, szName, 2, DELIM2))?
								atoi(szName + 64):0;
							jfm[max_jtexfont++].vpos = 
								(val&&get_term(szName+64, szName, 3, DELIM2))?
								atoi(szName + 64):0;

						}
					}
					ApplyOn(hwnd, &f_change);
					f_change = 1;
					goto set0;

				case IDC_CHANGEFONT:
					wjf = SendDlgItemMessage( hwnd, IDC_JFONTLIST, 
						CB_GETCURSEL, 0, 0);
					if(wjf == CB_ERR)
						break;

				case IDC_JGET:
					DialogBox( g_winData.hInstance,
						MAKEINTRESOURCE(IDD_WINJTT),
						hwnd, WinJFontListProc );
					if(wj_result == NULL)
						break;
					if(LOWORD(wParam) == IDC_JGET){
						if(max_wjfont >= MAX_VFONT)
							break;
						SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_ADDSTRING,
							 0,(LPARAM)wj_result);
						winjf[max_wjfont].hsc = 1000;
						winjf[wjf = max_wjfont++].vsc = 1000;
					}
					else{
						SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_DELETESTRING,
							wjf, 0);
						SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_INSERTSTRING,
							wjf,(LPARAM)wj_result);						
					}
					SendDlgItemMessage(hwnd, IDC_JFONTLIST, CB_SETCURSEL, wjf, 0);
					goto killend;

				case IDC_CHECK1:
					f_Jfont = IsDlgButtonChecked( hwnd, IDC_CHECK1);
					EnableWindow(GetDlgItem(hwnd, IDC_JBOLD), !f_Jfont);
					break;

				case IDC_JDEFINE:
					szName[0] = 0;
					GetDlgItemText( hwnd, IDC_JFM, szName, 128 );
					if(!szName[0])
						break;	
					wjf = SendDlgItemMessage( hwnd, IDC_JFONTLIST, 
						CB_GETCURSEL, 0, 0);
					if(wjf == CB_ERR)
						break;
					tf = SendDlgItemMessage( hwnd, IDC_JFM, CB_FINDSTRINGEXACT,
						-1, (LPARAM)szName);
					if(tf == CB_ERR){
						if(max_jtexfont >= 64)
							break;
						SendDlgItemMessage(hwnd, IDC_JFM, CB_ADDSTRING,
							 0,(LPARAM)szName);
						tf = max_jtexfont++;
					}

					jfm[tf].pt = (short)wjf;
					num = SendDlgItemMessage( hwnd, IDC_HEITAI, 
						CB_GETCURSEL, 0, 0);
					if(num == CB_ERR)
						num = 0;
					if(num > 4)
						num++;
					jfm[tf].hei = (char)('a' + num);
					num = SendDlgItemMessage( hwnd, IDC_SHATAI, 
						CB_GETCURSEL, 0, 0);
					if(num == CB_ERR)
						num = 0;
					jfm[tf].sha = (char)('a' + num);
					num = SendDlgItemMessage( hwnd, IDC_KAITEN, 
						CB_GETCURSEL, 0, 0);
					if(num == CB_ERR)
						num = 0;
					jfm[tf].rot = num;
					num = SendDlgItemMessage( hwnd, IDC_JBOLD, 
						CB_GETCURSEL, 0, 0);
					if(num == CB_ERR)
						num = 0;
					jfm[tf].thin = num;
					jfm[tf].hpos = GetDlgItemInt(hwnd, IDC_JXPOS, &num, TRUE);
					jfm[tf].vpos = GetDlgItemInt(hwnd, IDC_JYPOS, &num, TRUE);
					winjf[wjf].hsc = GetDlgItemInt(hwnd, IDC_JHSCALE, &num, TRUE);
					winjf[wjf].vsc = GetDlgItemInt(hwnd, IDC_JVSCALE, &num, TRUE);

					goto killend;

				case IDC_JREMOVE:
					wjf = SendDlgItemMessage( hwnd, IDC_JFONTLIST, 
						CB_GETCURSEL, 0, 0);
					if(wjf == CB_ERR)
						break;
					szName[0] = 0;
					GetDlgItemText( hwnd, IDC_JFM, szName, 128 );
					if(!szName[0])
						goto killwjfm;
					tf = SendDlgItemMessage( hwnd, IDC_JFM, CB_FINDSTRINGEXACT,
						-1, (LPARAM)szName);
					if(tf == CB_ERR || jfm[tf].pt != wjf){
killwjfm:				for(tf = 0; tf < max_jtexfont; tf++){
							if(jfm[tf].pt == wjf)
								goto set;
						}
						GetDlgItemText( hwnd, IDC_JFONTLIST, szName, 128 );
						wsprintf((char*)common_work, "Delete definition of %s?",
							szName);
						if(MessageBox( hwnd, (char*)common_work,
							"TrueType Font", MB_OKCANCEL) == IDCANCEL)
								break;
						SendDlgItemMessage( hwnd, IDC_JFONTLIST, 
							CB_DELETESTRING, wjf, 0 );
						max_wjfont--;
						for(num = wjf; num < max_wjfont; num++){
							winjf[num].hsc = winjf[num+1].hsc;
							winjf[num].vsc = winjf[num+1].vsc;
						}
						for(num = 0; num < max_jtexfont; num++){
							if(jfm[num].pt > wjf)
								jfm[num].pt--;
						}
						goto killend;
					}
					wsprintf((char*)common_work, "Delete definition of %s?",
						szName);
					if(MessageBox( hwnd, (char*)common_work,
						"TeX font", MB_OKCANCEL) == IDCANCEL)
							break;
					SendDlgItemMessage( hwnd, IDC_JFM, 
						CB_DELETESTRING, tf, 0 );
					max_jtexfont--;
					for(num = tf; num < max_jtexfont; num++){
						jfm[num].thin = jfm[num+1].thin;
						jfm[num].hpos = jfm[num+1].hpos;
						jfm[num].vpos = jfm[num+1].vpos;
						jfm[num].rot  = jfm[num+1].rot;
						jfm[num].hei  = jfm[num+1].hei;
						jfm[num].sha  = jfm[num+1].sha;
						jfm[num].pt	  = jfm[num+1].pt;
					}
killend:
					ApplyOn(hwnd, &f_change);
					f_change = 1;
					goto j_num;
			}
			switch( HIWORD(wParam) ){
				case CBN_SELCHANGE:
					if( LOWORD(wParam) == IDC_JFM ){
						tf = SendDlgItemMessage(hwnd, IDC_JFM, 
							CB_GETCURSEL, 0, 0L);
						if(tf < 0)
							break;
						wjf = jfm[tf].pt;
						goto set;
					}else if( LOWORD(wParam) == IDC_JFONTLIST)
						goto j_num;
			}
#if 0
			if( HIWORD(wParam) == EN_CHANGE ){
check:			if(!(f_change & INIT_APPLY)
				  && CheckParaTab(para_tab, LOWORD(wParam))){
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
				}
			}
#endif
			break;

		case WM_HELP:
			ShowCHelp(lParam, help);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PWINJFONT);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_WINJFONT)){
						case IDYES:			// change the current parameters
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							goto define;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;


				case PSN_KILLACTIVE:
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
					ReSetFont(hedit);
					ReSetFont(hcombo);
					break;

//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit = GetDlgItem( hwnd, IDC_JFM );
					hcombo = GetDlgItem( hwnd, IDC_JFONTLIST );
					SetFontJE(hedit);
					SetMargin(hedit);
					SetFontJE(hcombo);
					SetMargin(GetDlgItem(hwnd,IDC_JFM));
					SetMargin(GetDlgItem(hwnd,IDC_JXPOS));
					SetMargin(GetDlgItem(hwnd,IDC_JYPOS));
					SetMargin(GetDlgItem(hwnd,IDC_JHSCALE));
					SetMargin(GetDlgItem(hwnd,IDC_JVSCALE));
					break;
			}
			break;
			
		case WM_DESTROY:
			break;
	}
	return FALSE;
}

BOOL CALLBACK DlgChgFontProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
	#define	MAXBUF	 0x4000
	#define	FIRSTMAX 0x3000
	#define	MAXFONT	 0x100
	extern V_JFM *v_tfm;
	V_JFM *vjfm;
	FONT_INFO *font, *font1, *font2;
	char *name, *fname;
	int	pos;
	static char *tmpbuf;
	static char **jfm, **ttf, **ttf2;
	static int total;
	static int pt;
	static HWND hfontlist;

	switch( message )
	{
		case WM_INITDIALOG:
			hfontlist = GetDlgItem( hwnd, IDC_LISTBOX1 );
			SetFont( 10, hfontlist, IsJapanese()?"ＭＳ ゴシック":"Courier New", IsJapanese() );
			// SetFontJE(hfontlist);
			f_Jfont = 1;
reset:		total = pt = 0;
			tmpbuf = (char*)marea(MAXBUF);
			jfm = (char**)marea(sizeof(char **)*MAXFONT*3);
			ttf = jfm + MAXFONT;
			ttf2= ttf + MAXFONT;
			font1 = font2 = NULL;

			for (font = first_font_info; ; font = font->next_font) {
				if(font == NULL){
					if(!font1)
						break;
					if(!font2){
						font = font1;
						font1 = NULL;
						continue;
					}else{
						font = font2;
						font2 = NULL;
						continue;
					}
				}
				if(font->font_type == VIRTUAL_FONT){
					if(font2)
						continue;
					if(font1)
						font2 = font;
					else
						font1 = font;
					font = font->ext.local_font;
				}
#ifdef	USE_SUBFONT
				if(font->font_type == WINTT_FONT && font->sfd_id >= 0){
					name = fname = check_ftt(font->n);
					name--;
					while(*--name);
					name++;
				}else
#endif
				if(font->font_type == WINJTT_FONT)
					name = font->n;
				else
cont:				continue;
				for(pos = 0; pos < total; pos++){
					if(!strcmp(name, jfm[pos]))
						goto cont;
				}
				if(font ->font_type == WINJTT_FONT){
					vjfm = get_vjfm((font->ext.kdir)->fh);
					fname = (vjfm==v_tfm)?check_ftt(font->n)
						:(vfont[vjfm->font_no]->v_font_name + 1);
				}
				if(pt + strlen(name) + strlen(fname) >= FIRSTMAX || total >= MAXFONT)
					continue;
				strcpy(jfm[total] = tmpbuf+pt, name);
				pt += strlen(name) + 1;
				strcpy(ttf[total] = tmpbuf + pt, fname);
				pt += strlen(fname) + 1;
				ttf2[total++] = NULL;
			}
			if(!total){
				error(WARNING, "No Japanese TrueType font");
				goto quit;
			}
			for(pos = 0; pos < total; pos++){
				sprintf(common_work, "%-10s \"%s\"", jfm[pos], ttf[pos]);
				SendDlgItemMessage(hwnd, IDC_LISTBOX1, LB_ADDSTRING, 0, 
					(LPARAM)common_work);
			}
			SendDlgItemMessage(hwnd, IDC_LISTBOX1, LB_SETCURSEL, 0, 0L);
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){
				case IDC_ERACE:
					pos = SendDlgItemMessage(hwnd, IDC_LISTBOX1, LB_GETCURSEL, 0, 0L);
					if(pos < 0 || pos >= total)
						break;
					DialogBox( g_winData.hInstance,
						MAKEINTRESOURCE(IDD_WINJTT),
						hwnd, WinJFontListProc );
					if(!wj_result)
						break;
					if(pt + strlen(wj_result) >= MAXBUF){
						error(WARNING, "Too many changes");
						break;
					}
					strcpy(tmpbuf+pt, wj_result);
					ttf2[pos] = tmpbuf+pt;
					pt += strlen(tmpbuf+pt) + 1;
					SendDlgItemMessage(hwnd, IDC_LISTBOX1, LB_DELETESTRING, pos, 0);
					sprintf(common_work, "%-10s \"%s\"", jfm[pos], ttf2[pos]);
					SendDlgItemMessage(hwnd, IDC_LISTBOX1, LB_INSERTSTRING, pos, 
						(LPARAM)common_work);
					SendDlgItemMessage(hwnd, IDC_LISTBOX1, LB_SETCURSEL, pos, 0L);
					break;

				case IDC_DEFAULT:
					Free0(tmpbuf);
					Free0(jfm);
					SendDlgItemMessage(hwnd, IDC_LISTBOX1, LB_RESETCONTENT, 0, 0);
					fname = GetParaAny("ftt");
					DefineFTT((!fname || my_access(fname,0))?NULL:fname);
					goto quit0;

				case IDC_PHELP:
					ShowWinHelp(IDH_CHGFONT);
					break;

				case IDOK:
					for(pos = 0; pos < total; pos++){
						if(ttf2[pos])
							chg_ftt(jfm[pos], ttf2[pos]);
					}
quit0:				ClearFont();
				case IDCANCEL:
quit:				Free0(tmpbuf);
					Free0(jfm);
					EndDialog(hwnd, 0);
					return TRUE;
			}
			break;

		case WM_DESTROY:
			ReSetFont(hfontlist);
			break;
	}
	return FALSE;
}

/*
 *****************************	   JFont	 *******************************
 */
LRESULT CALLBACK JFontTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	static UINT f_change;
	static PARA_TAB para_tab[] =
	{
		{"TEXKNJ", IDC_TEXKNJ, IDH_TEXKNJ, TAB_STRING, 0},
		{"JC",	   IDC_JC,	   IDH_JC,	   TAB_PROC, 0},
		{"vfn",	   IDC_VFN,	   IDH_VFN,	   TAB_STRING, 0},
		{"nttF",   IDC_NTTF,   IDH_NTTF,   TAB_STRING, 0},
		{"G",      IDC_GG,     IDH_GG,     TAB_STRING, 0},
		{"S",	   IDC_S,	   IDH_S,	   TAB_INT, 0},
		{"J",	   IDC_J,	   IDH_J,	   TAB_INT, 0},
		{"ntt",	   IDC_NTT,	   IDH_NTT,	   TAB_BOOL, 0},
		{"g",	   IDC_G,	   IDH_G,	   TAB_BOOL, 0},
		{"Jfm",    IDC_IJFM,   IDH_IJFM,   TAB_BOOL, 0},
		{"Jbt",    IDC_JBT,    IDH_JBT,    TAB_BOOL, 0},
		{"Jgt",    IDC_JGT,    IDH_JGT,    TAB_BOOL, 0},
		{"",	   IDC_VFNB,   IDH_VFN,	   TAB_HELP, 0},
		{NULL,	   0, 0, 0, 0}
	};
	static HWND udWnd[2];
	static HWND hedit1, hedit2, hedit3, hedit4, hedit5;
	char *fname;

	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			InitParaTab(para_tab, TRUE);
			if(vfont_name == NULL || *vfont_name == '\n')
				para_tab[2].flag = FALSE;
			InitAllPara(hwnd, para_tab, udWnd);
			InitParaTab(para_tab, FALSE);
			f_change = 0;
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){

				case ID_SAVE:
					common_work[0] = 0;
					GetDlgItemText(hwnd, IDC_VFN, (char *)common_work, 0x1000);
					if(common_work[0] <= ' ')
						para_tab[2].type = TAB_HELP;
					ReserveAllPara(hwnd, para_tab);
					para_tab[2].type = TAB_STRING;
					break;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					RestoreStringPara(common_work, 0x1000, "vfn");
					if(common_work[0] == 0 || common_work[0] == '\n')
						para_tab[2].flag = FALSE;
					RestoreAllPara(hwnd, para_tab, udWnd);
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
					break;

				case IDC_NTT:
				case IDC_G:
				case IDC_IJFM:
				case IDC_JBT:
				case IDC_JGT:
					goto check;

				case IDC_VFNB:
					if( (fname = QueryGeneralName(
						"Query file to define Japanese fonts "
						"(Cancel for default)", 
						"Font description(*.vfn)", "*.vfn"
					 )) != NULL ) 
					SetDlgItemText(hwnd, IDC_VFN, fname);
					break;

			}
			if( HIWORD(wParam) == EN_CHANGE ){
check:			if(!(f_change & INIT_APPLY)
				  && CheckParaTab(para_tab, LOWORD(wParam))){
					ApplyOn(hwnd, &f_change);
					f_change = TRUE;
				}
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PJFONT2);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_JFONT)){
						case IDYES:			// change the current parameters
							common_work[0] = 0;
							GetDlgItemText(hwnd, IDC_VFN, 
								(char*)common_work, 256);
							if(!isalpha(*common_work) && *common_work != '^')
								para_tab[2].flag = 0;
							SetAllPara(hwnd, para_tab);
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit1);
					ReSetFont(hedit2);
					ReSetFont(hedit3);
					ReSetFont(hedit4);
					ReSetFont(hedit5);
					break;

//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit1 = GetDlgItem( hwnd, IDC_TEXKNJ );
					hedit2 = GetDlgItem( hwnd, IDC_JC );
					hedit3 = GetDlgItem( hwnd, IDC_VFN );
					hedit4 = GetDlgItem( hwnd, IDC_NTTF );
					hedit5 = GetDlgItem( hwnd, IDC_GG );
					SetFontJE(hedit1);
					SetFontJE(hedit2);
					SetFontJE(hedit3);
					SetFontJE(hedit4);
					SetFontJE(hedit5);
					SetMargin(hedit1);
					SetMargin(hedit2);
					SetMargin(hedit3);
					SetMargin(hedit4);
					SetMargin(hedit5);
					SetMargin(GetDlgItem(hwnd,IDC_S));
					SetMargin(GetDlgItem(hwnd,IDC_J));
					break;
			}
			break;
			
		case WM_DESTROY:
			break;
	}
	return FALSE;
}

/*
 *************************	   Resolution	  ******************************
 */
char *mag_str[] =
{
	"default",
	"magstep 0",
	"magstep 0.5",
	"magstep 1",
	"magstep 2",
	"magstep 3",
	"magstep 4",
	"magstep 5",
	"magstep 6",
	"magstep 7",
	"magstep 8",
	"magstep 9"
};

int TransMag(int val)
{
	switch(val){
		case 0:
			return -1;
		case 1:
			return 0;
		case 2:
			return 1095;
		default:
			return val-2;
	}
}

static int TransMagInv(int val)
{
	if(val == 0)
		val = 1;
	else if(val > 0){
		if(val == 1095)
			val = 2;
		else
			val += 2;
	}
	if(val < 0 || val > 12)
		val= 0;
	return val;
}

LRESULT CALLBACK ResolutionTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	static UINT f_change;
	BOOL tmp;
	int s_pos;
	ARG_TABLE *opt;
#	define	LAST_MAG (sizeof(mag_str)/sizeof(char*))
	static HWND udWnd[3];

	static PARA_TAB para_tab[] = {
		{"dpi",	 IDC_DPI,  IDH_HDPI, TAB_INT, 0},
		{"dpiv", IDC_DPIY, IDH_VDPI, TAB_INT, 0},
		{"e",	 IDC_E,	   IDH_E,    TAB_INT, 0},
		{"varf", IDC_VARF, IDH_VARF, TAB_BOOL, 0},
		{"mag",	 IDC_MAG,  IDH_MAG,  TAB_HELP, 0},
		{NULL, 0, 0, 0, 0}
	};
	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			if(dviout_dimension.DPI < 10)
				dviout_dimension.DPI = dviout_dimension.dpi;
			for(s_pos = 0; s_pos < LAST_MAG; )
				SendDlgItemMessage(hwnd, IDC_MAG, CB_ADDSTRING, 0,
					(LPARAM)mag_str[s_pos++]);
			SendDlgItemMessage(hwnd, IDC_MAG, CB_SETCURSEL, 
				TransMagInv(GetParaInt("mag")), 0);
			InitParaTab(para_tab, TRUE);
			opt = (ARG_TABLE*)SetPara("e", CHECK_OPTION);
			if( (tmp = *(int *)opt->var) == 0)
				*(int *)opt->var = 1000;
			InitAllPara(hwnd, para_tab, udWnd);
			if(!tmp)
				*(int *)opt->var = 0;
			if(GetXDpi() != GetYDpi())
				CheckDlgButton(hwnd, IDC_DIF_DPI, TRUE);
			else{
				EnableWindow(GetDlgItem(hwnd, IDC_DPIY), FALSE);
				EnableWindow(GetDlgItem(hwnd, IDC_TDPIY), FALSE);
				EnableWindow(udWnd[1], FALSE);
			}
			InitParaTab(para_tab, FALSE);
			f_change = 0;
			return TRUE;

		case WM_COMMAND:
			switch( LOWORD(wParam) ){

				case ID_SAVE:
					ReserveAllPara(hwnd, para_tab);
					if(!IsDlgButtonChecked(hwnd, IDC_DIF_DPI))
						ReserveIntPara("dpiv", 0);
					tmp = SendDlgItemMessage(hwnd, IDC_MAG, CB_GETCURSEL,
						0, 0);
					ReserveIntPara("mag", TransMag(tmp));
					break;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					para_tab[1].flag = FALSE;
					RestoreAllPara(hwnd, para_tab, udWnd);
					tmp = RestoreIntPara("dpiv", WRONG_INT);
					if(tmp != WRONG_INT){
						if(tmp){
							CheckDlgButton(hwnd, IDC_DIF_DPI, TRUE);
							SendMessage( udWnd[1], UDM_SETPOS, 0, 
								MAKELONG(tmp, 0));
						}
						else
							CheckDlgButton(hwnd, IDC_DIF_DPI, FALSE);
					}
					SendDlgItemMessage(hwnd, IDC_MAG, CB_SETCURSEL,
						TransMagInv(RestoreIntPara("mag", 0)), 0);
					ApplyOn(hwnd, &f_change);
					f_change = 7;;
					break;

				case IDC_DIF_DPI:
					tmp = IsDlgButtonChecked(hwnd, IDC_DIF_DPI);
					EnableWindow(GetDlgItem(hwnd, IDC_DPIY), tmp);
					EnableWindow(GetDlgItem(hwnd, IDC_TDPIY), tmp);
					EnableWindow(udWnd[1], tmp);
					ApplyOn(hwnd, &f_change);
					f_change |= 2;
					break;

				case IDC_VARF:
					goto check;
			}
			if( HIWORD(wParam) == EN_CHANGE ){
check:			if(!(f_change & INIT_APPLY)
				  && CheckParaTab(para_tab, LOWORD(wParam))){
					ApplyOn(hwnd, &f_change);
					f_change |= 1;
				}
			}
			else if( HIWORD(wParam) == CBN_SELCHANGE){		// selection is changed
				ApplyOn(hwnd, &f_change);
				f_change |= 4;
			}

			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PRESOLUTION);
					break;

				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_RESOLUTION)){
						case IDYES:			// change the current parameters
							SetAllPara(hwnd, para_tab);
							if(!IsDlgButtonChecked(hwnd, IDC_DIF_DPI))
								SetParaInt("dpiv", dviout_dimension.dpi);
							opt = (ARG_TABLE*)SetPara("e", CHECK_OPTION);
							if( (tmp = *(int *)opt->var) == 1000)
								*(int *)opt->var = 0;
							if(f_change & 4){
								tmp = SendDlgItemMessage(hwnd, IDC_MAG,
									CB_GETCURSEL, 0, 0);
								SetParaFlag("half", FALSE);
								SetParaInt("mag", TransMag(tmp));
							}
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;
#if	0
				case PSN_KILLACTIVE:
					if(f_DlgQuery){
						SetWindowLong( hwnd, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					SetMargin(GetDlgItem(hwnd,IDC_DPI));
					SetMargin(GetDlgItem(hwnd,IDC_DPIY));
					SetMargin(GetDlgItem(hwnd,IDC_E));
					break;
			}
			break;

		case WM_DESTROY:
			break;
	}
	return FALSE;
}


/*
 ************************	  KILLACTIVE:	  *******************************
 */

struct REG_PARA {
	char key[12];
	int type;
};

static struct REG_PARA reg_para[] =
{
	{"+ dpi",		TAB_INT},
	{"+ TEXROOT",	TAB_STRING},
	{"+ TEXPK",		TAB_STRING},
	{"+ TEXFONTS",	TAB_STRING},
	{"+ TEXSUBF",	TAB_STRING},
	{"+ L",			TAB_INT},
	{"+ area",		TAB_BOOL},
	{"+ LM",		TAB_LENGTH},
	{"+ TM",		TAB_LENGTH},
	{"+ BMP",		TAB_STRING},
	{"+ F",			TAB_STRING},
	{"+ FB",		TAB_INT},

	{"+ renew",		TAB_BOOL},
	{"+ multi",		TAB_INT},
	{"+ key",		TAB_KEY},
	{"+ scale",		TAB_PROC},
	{"+ t",			TAB_INT},
	{"+ bright",	TAB_INT},
	{"+ search",	TAB_INT},
	{"+ sFont",		TAB_STRING},
	{"+ sdpi",		TAB_INT},
	{"+ hyper",		TAB_INT},
	{"+ hyperoff",	TAB_INT},

	{"+ href",		TAB_INT},
	{"+ hname",		TAB_INT},
	{"+ hbuf",		TAB_INT},
	{"+ Browser",	TAB_STRING},
	{"+ ToEdit",	TAB_STRING},
	{"+ gen",		TAB_STRING},
	{"+ vfn",		TAB_STRING},
	{"+ JC",		TAB_PROC},
	{"+ S",			TAB_INT},
	{"+ J",			TAB_INT},
	{"+ Jbt",		TAB_BOOL},
	{"+ Jgt",		TAB_BOOL},
	{"+ Jfm",		TAB_BOOL},
	{"+ ntt",		TAB_BOOL},

	{"+ nttF",		TAB_STRING},
	{"+ varf",		TAB_BOOL},
	{"+ tpic",		TAB_INT},
	{"+ GS",		TAB_INT},
	{"+ GIF",		TAB_INT},
	{"+ gsx",		TAB_STRING},
	{"+ gdat",		TAB_STRING},
	{"+ gbox",		TAB_BOOL},
	{"+ gfit",		TAB_BOOL},
	{"+ gow",		TAB_BOOL},
	{"+ gclip",		TAB_BOOL},
	{"+ gsize",		TAB_BOOL},
	{"+ color",		TAB_BOOL},
	{"+ spi",		TAB_STRING},
	{"+ cmode",		TAB_INT},

	{"+ RM",		TAB_LENGTH},
	{"+ BM",		TAB_LENGTH},
	{"+ y",			TAB_PROC},
	{"+ br",		TAB_INT},
	{"+ bf",		TAB_INT},
	{"+ bb",		TAB_INT},
	{"+ log",		TAB_STRING},

	{"+ TEXPKD",	TAB_STRING},
	{"+ TEXFLI",	TAB_STRING},
	{"+ TEXKNJ",	TAB_STRING},
	{"+ G",			TAB_STRING},
	{"+ g",			TAB_BOOL},
	{"+ A",			TAB_INT},
	{"+ c",			TAB_BOOL},
	{"+ Fkeep",		TAB_BOOL},
	{"+ virtual",	TAB_BOOL},
	{"+ Fod",		TAB_BOOL},
	{"+ ttf",		TAB_INT},
	{"+ ftt",		TAB_PROC},
	{"- mag",		TAB_INT},
	{"+ dpiv",		TAB_INT},
	{"+ e",			TAB_INT},
	{"+ OX",		TAB_LENGTH},
	{"+ OY",		TAB_LENGTH},

	{"+ HC",		TAB_BOOL},
	{"+ HS",		TAB_LENGTH},
	{"+ VC",		TAB_BOOL},
	{"+ VS",		TAB_LENGTH},
	{"+ edge",		TAB_INT},
	{"+ button",	TAB_BOOL},
	{"+ base",		TAB_BOOL},
	{"+ box",		TAB_BOOL},
	{"+ Wshow",		TAB_BOOL},
	{"+ dviprt",	TAB_STRING},
	{"+ macro",		TAB_STRING},
	{"+ isp",		TAB_STRING},
	{"+ texhelp",	TAB_STRING},
	{"+ file",		TAB_PROC},		// this should be the last parameter

	{0, 0}
};

static void RestoreRegSub(int id, char *para)
{
	int val;

	switch(id){
		case TAB_BOOL:
			val = RestoreIntPara(para, WRONG_INT);
			if(val != WRONG_INT)
				SetParaFlag(para, val); 
			break;
		case TAB_INT:
			val = RestoreIntPara(para, WRONG_INT);
			if(val != WRONG_INT)
				SetParaInt(para, val);
			break;
		case TAB_LENGTH:
			val = RestoreIntPara(para, WRONG_INT);
			if(val != WRONG_INT){
				SetParaString(para, print10mm(val));
			}
			break;
		case TAB_PROC:
		case TAB_STRING:
			RestoreString((char*)common_work+0x1000, 0x2000, 
				ParaSection, para, "\001" );
			if(common_work[0x1000] != 1)
				SetParaStringDirect(para, (char*)common_work+0x1000);
			break;
		case TAB_KEY:
				LoadKeyTable();
			break;
	}
}

void RestoreRegistry(void)
{
	char tmp[1024];
	int pos;
	char *para;

	tmp[1023] = 0;

	RestoreStringPara(para = tmp, 1023, "restore");

	if(!*tmp || *tmp=='*'){
		for(pos = 0; reg_para[pos].key[0] != 0; pos++)
			RestoreRegSub(reg_para[pos].type, reg_para[pos].key + 2);
		return;
	}

	for(pos = 0; *para; para = tmp + pos){
		while(tmp[pos]){
			if(tmp[pos++] == ':'){
				tmp[pos-1] = 0;
				break;
			}
		}
		RestoreRegSub(*para - '0', para+1);
	}
}

static void MakeRegHelp(char *key)
{
	ARG_TABLE *para;
	int pos;

	strcpy(common_work, key);
	para = (ARG_TABLE*)SetPara(key+2, CHECK_OPTION);
	if(para!=NULL){
		pos = strlen(common_work);
		while(pos < 10)
			common_work[pos++] = ' ';
		common_work[pos++] = ':';
		common_work[pos] = 0;
		strcat((char*)common_work, para->message);
		pos = 0;
		while(common_work[++pos] >= ' ');
		common_work[pos] = 0;
	}
}

LRESULT CALLBACK RegistryTabProc( HWND hwnd, UINT message, 
									WPARAM wParam, LPARAM lParam)
{
	int reg_pos, ch, pos, tmp, f_all, type;
#	define	REG_CHECK	'+'
	char text[4];
	char mode[32];
	static HWND hedit;
	PARA_TAB para_tab[] =
	{
		{"", IDC_LOAD,		IDH_RROAD,	   TAB_HELP, 0},
		{"", IDC_REGIGNORE, IDH_RIGNORE,   TAB_HELP, 0},
		{"", ID_SAVE,		IDH_RSAVE,	   TAB_HELP, 0},
		{"", ID_RESTORE,	IDH_RRESTORE,  TAB_HELP, 0},
		{"", ID_CLEAR,		IDH_RCLEAR,	   TAB_HELP, 0},
		{"", IDC_ALLSET,	IDH_ALLSET,	   TAB_HELP, 0},
		{"", IDC_REGMODE,	IDH_REGMODE,   TAB_HELP, 0},
		{"", IDC_REGSTART,	IDH_REGLIST,   TAB_HELP, 0}, 
		{"", IDC_REG_DEF,	IDH_REGDEFAULT,TAB_HELP, 0}, 
		{"", IDC_REG_CUR,	IDH_REGCURRENT,TAB_HELP, 0}, 
		{"", IDC_REG_PRINT, IDH_REGPRINT,  TAB_HELP, 0}, 
		{"", IDC_NAME,		IDH_REGNAME,   TAB_HELP, 0}, 
		{NULL, 0, 0, 0}
	};

	type = 0;

	switch( message )
	{
		case WM_INITDIALOG:
			for(pos = 0; pos < 10; pos++){
				sprintf(text, "%c", pos + '0');
				SendDlgItemMessage(hwnd, IDC_REG_DEF, CB_ADDSTRING, 0,
					(LPARAM)text);
				SendDlgItemMessage(hwnd, IDC_REG_CUR, CB_ADDSTRING, 0,
					(LPARAM)text);
				SendDlgItemMessage(hwnd, IDC_REG_PRINT, CB_ADDSTRING, 0,
					(LPARAM)text);
			}
			SendDlgItemMessage(hwnd, IDC_REGSTART, LB_SETHORIZONTALEXTENT,
				700, 0);	// to hide \n\r
			tmp = SetParaSection(-1);
			goto restore;
show:		SendDlgItemMessage(hwnd, IDC_REG_DEF, CB_SETCURSEL,
				RestoreInt("Settings", "mode", 0), 0);
			SendDlgItemMessage(hwnd, IDC_REG_CUR, CB_SETCURSEL,
				tmp = SetParaSection(-1), 0);
			SendDlgItemMessage(hwnd, IDC_REG_PRINT, CB_SETCURSEL,
				RestoreIntPara("pmode", tmp), 0);
			mode[31] = 0;
			RestoreStringPara(mode, 31, "mode");
			SetDlgItemText(hwnd, IDC_NAME, mode);
show_para:	for(reg_pos = 0; reg_para[reg_pos].key[0] != 0; ){
				MakeRegHelp(reg_para[reg_pos++].key);
				SendDlgItemMessage(hwnd, IDC_REGSTART, LB_ADDSTRING, 0,
					(LPARAM)common_work); 
			}
			return TRUE;

		case WM_COMMAND:
			switch( wParam )
			{
				case IDC_LOAD:
					ch = REG_CHECK;
					goto check;

				case IDC_REGIGNORE:
					ch = ' ';
check:				reg_pos = SendDlgItemMessage(hwnd, IDC_REGSTART,
						LB_GETCURSEL, 0, 0L);
					if(reg_pos == CB_ERR){
						ShowMessage("No parameter is selected", 
							NULL, SM_OKCONT);
						break;
					}
					reg_para[reg_pos].key[0] = ch;
					SendDlgItemMessage(hwnd, IDC_REGSTART, 
						LB_DELETESTRING, reg_pos, 0);
					MakeRegHelp(reg_para[reg_pos].key);
					SendDlgItemMessage(hwnd, IDC_REGSTART, 
						LB_INSERTSTRING, reg_pos,
						(LPARAM)common_work);
					SendDlgItemMessage(hwnd, IDC_REGSTART, 
						LB_SETCURSEL, reg_pos, 0);
					break;

				case ID_SAVE:
					common_work[pos = 0] = f_all = 0;
					for(reg_pos = 0; reg_para[reg_pos].key[0] != 0; reg_pos++){
						if(reg_para[reg_pos].key[0] != REG_CHECK){
							f_all++;
							continue;
						}
						common_work[pos++] = reg_para[reg_pos].type + '0';
						tmp = 2;
						while((ch = reg_para[reg_pos].key[tmp++]) > ' '){
							if(ch == ':' || ch == '=')
								break;
							common_work[pos++] = ch;
						}
						common_work[pos++] = ':';
					}
					if(!f_all){
						common_work[0] = '*';
						pos = 1;
					}
					common_work[pos] = 0;
					ReserveStringPara("restore", common_work);
					GetDlgItemText(hwnd, IDC_NAME, mode, 31);
					ReserveStringPara("mode", mode);
					pos = GetDlgItemInt(hwnd, IDC_REG_DEF, &tmp, TRUE);
					ReserveInt("Settings", "mode", pos);
					pos = GetDlgItemInt(hwnd, IDC_REG_PRINT, &tmp, TRUE);
					if(pos == SetParaSection(-1))
						DeletePara("pmode");
					else
						ReserveIntPara("pmode", pos);
					MessageSaved(hwnd);
					break;

				case ID_RESTORE:
					tmp = SendDlgItemMessage(hwnd, IDC_REG_CUR,
						CB_GETCURSEL, 0, 0);
					SetParaSection( tmp );
restore:			RestoreStringPara(common_work, 0x1000, "restore");
					type = 1;
					if(!*common_work)
						goto show;
					if(*common_work == '*')
						goto all_set;
					for(reg_pos = 0; reg_para[reg_pos].key[0] != 0; )
						reg_para[reg_pos++].key[0] = ' ';
					pos = 0;
					while(1){
						if(common_work[pos] < '0' || common_work[pos++] > '9')
							break;
						for(tmp = 0; common_work[pos+tmp] != ':'; tmp++){
							if(common_work[pos + tmp] == 0)
								goto quit;
						}
						for(reg_pos = 0; reg_para[reg_pos].key[0] != 0; 
						  reg_pos++){
							if( (ch = strncmp(reg_para[reg_pos].key + 2, 
							  common_work + pos, tmp)) == 0){
								if((ch = reg_para[reg_pos].key[tmp+2]) <= ' '
								  || ch == ':' || ch == '='){
									reg_para[reg_pos].key[0] = REG_CHECK;
									break;
								}
							}
						}
						pos += tmp+1;
					}
					SendDlgItemMessage(hwnd, IDC_REGSTART, LB_RESETCONTENT,
						 0, 0);
					goto show;
quit:				break;

				case IDC_ALLSET:
all_set:			ch = REG_CHECK;
					goto set;

				case ID_CLEAR:
					ch = ' ';
set:				SendDlgItemMessage(hwnd, IDC_REGSTART, LB_RESETCONTENT,
						 0, 0);
					for(reg_pos = 0; reg_para[reg_pos].key[0] != 0; )
						reg_para[reg_pos++].key[0] = ch;
					if(type)
						goto show;
					goto show_para;
			}
			if( HIWORD(wParam) == CBN_SELCHANGE &&
				LOWORD(wParam) == IDC_REG_CUR){
					tmp = SendDlgItemMessage(hwnd, IDC_REG_CUR, 
						CB_GETCURSEL, 0, 0);
					SetParaSection(tmp);
					RestoreStringPara(mode, 31, "mode");
					SetDlgItemText(hwnd, IDC_NAME, mode);
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PREGISTRY);
					break;
#if	0
				case PSN_APPLY:
					if(!f_change)
						break;
					switch(QueryApply(hwnd, IDD_TAB_REGISTRY)){
						case IDYES:			// change the current parameters
							SetAllPara(hwnd, para_tab);
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;
#endif
//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hwnd);
					hedit = GetDlgItem( hwnd, IDC_NAME );
					SetFontJE(hedit);
					SetMargin(hedit);
					break;

				case PSN_KILLACTIVE:
					ReSetFont(hedit);
					break;
			}
			break;

		case WM_DESTROY:
			break;

	}
	return FALSE;
}


/*
 ****************************	  Search	 *****************************
 */
static char *color_str[] =
{
	"white",
	"yellow",
	"magenta",
	"red",
	"cyan",
	"green",
	"blue",
	"black",
	"reverse"
};

static char *color_shape[] =
{
	"character",
	"box fill",
	"box frame",
	"line",
	"line+char"
};


static UINT GetDColor( HWND hDlg )
{
	int c_pos, s_pos, f_rev;
	UINT color;

	c_pos = SendDlgItemMessage(hDlg, IDC_SCOLOR,
		CB_GETCURSEL, 0, 0L);
	if(c_pos == CB_ERR)
		c_pos = 0;
	s_pos = SendDlgItemMessage(hDlg, IDC_SSHAPE, CB_GETCURSEL, 0, 0L);
	f_rev = IsDlgButtonChecked( hDlg, IDC_SREVERSE )?1:0;
	if(s_pos == CB_ERR)
		s_pos = 0;
	if(s_pos == 0){			// character -> forground
		if(c_pos == 8){
			s_pos = 1;
			goto rev;			// rev & char -> rev & boxfill
		}
		color  = (f_rev)?(c_pos << 4):((7-c_pos) << 4);
		color |= 0x80;		// forground
	}else{
		if(c_pos == 8)
rev:		color = F_B_REV;
		else{
			color = (!f_rev)?(c_pos << 4):((7-c_pos)<<4);
		}
		switch(s_pos){
			case 1:	// box fill
				break;
			case 2:	// box frame
				color |= F_B_BOUNDARY;
				break;
			case 4:	// line + char
				color |= 0x10000;
			case 3:	// line
				color |= F_CB_ULINE;
				if(		IsDlgButtonChecked( hDlg, IDC_SEULINE ))
					color |= F_CB_UULINE;
				else if(IsDlgButtonChecked( hDlg, IDC_SOLINE  ))
					color |= F_CB_OLINE;
				if(		IsDlgButtonChecked( hDlg, IDC_SLLINE  ))
					color |= F_CB_LLINE;
		}
	}
	if(c_pos != 8 &&	IsDlgButtonChecked( hDlg, IDC_SREPLACE))
		color |= F_B_SET;
	return color;
}

static UINT GetDSColor(HWND hDlg)
{
	UINT color;
	color = GetDColor(hDlg);
	if(IsDlgButtonChecked( hDlg, IDC_ALLTARGET ))
		color |= 0x100;
	if(IsDlgButtonChecked( hDlg, IDC_SMOVE ))
		color |= 0x200;
	return color;
}


static int SetDColor( HWND hDlg, UINT s_color, int f_rev )
{
	int c_pos, s_pos, f_fg;

	if(f_rev & 0x1000){				// Initial setting
		SendDlgItemMessage(hDlg, IDC_SCOLOR, CB_RESETCONTENT, 0, 0);
		SendDlgItemMessage(hDlg, IDC_SSHAPE, CB_RESETCONTENT, 0, 0);
		for(c_pos = 0; c_pos < sizeof(color_str)/sizeof(char *); )
			SendDlgItemMessage(hDlg, IDC_SCOLOR, CB_ADDSTRING, 0,
				(LPARAM)color_str[c_pos++]);

		for(s_pos = 0; s_pos < sizeof(color_shape)/sizeof(char *); )
			SendDlgItemMessage(hDlg, IDC_SSHAPE, CB_ADDSTRING, 0,
					(LPARAM)color_shape[s_pos++]);
		f_rev &= 0x2001;
	}

	if(f_rev & 0x2000)
		f_rev &= 1;
	else
		// current mode is reverse?
		CheckRadioButton( hDlg, IDC_SNORMAL, IDC_SREVERSE, 
			 f_rev? IDC_SREVERSE:IDC_SNORMAL );

	CheckRadioButton( hDlg, IDC_SMERGE, IDC_SREPLACE, 
		 (s_color & 4)? IDC_SREPLACE:IDC_SMERGE );

	CheckRadioButton( hDlg, IDC_SULINE, IDC_SOLINE, 
		 IDC_SULINE + ((s_color & 0x3000)>>12) );

	CheckRadioButton( hDlg, IDC_SLLINE, IDC_SRLINE, 
		 (s_color & 0x4000)? IDC_SRLINE:IDC_SLLINE );

	CheckRadioButton( hDlg, IDC_ONETARGET, IDC_ALLTARGET, 
		 (s_color & 0x100)? IDC_ALLTARGET:IDC_ONETARGET );

	CheckRadioButton( hDlg, IDC_SNOMOVE, IDC_SMOVE, 
		 (s_color & 0x200)? IDC_SMOVE:IDC_SNOMOVE );

	f_fg = (s_color & 0x80)?1:0;

	if (s_color & 8)
		c_pos = 8;		// reverse
	else{
		c_pos = ((s_color & 0x70) >> 4);
		if((f_rev + f_fg) & 1)
			c_pos = 7 - c_pos;
	}
	SendDlgItemMessage(hDlg, IDC_SCOLOR, CB_SETCURSEL, c_pos, 0);

	if(s_color & 0x10000)
		s_pos = 4;		// line
	else if(s_color & 2)
		s_pos = 2;		// box frame
	else{
		if(f_fg)
			s_pos = 0;	// character
		else
			s_pos = (s_color & 0x8000)? 3:1;	// box fill or line
	}
	SendDlgItemMessage(hDlg, IDC_SSHAPE, CB_SETCURSEL, s_pos, 0);
	return s_pos;
}


//	Setting
//	 UINT search:f_s_color
//	 int  sdpi:f_s_dpi
LRESULT CALLBACK SearchTabProc( HWND hDlg, UINT message, 
									WPARAM wParam, LPARAM lParam)
{

	static HWND udWnd[1];
	static PARA_TAB para_tab[] =
	{
		{"sdpi", IDC_SDPI, IDH_SDPI, TAB_INT, 0},
		{"sFont",IDC_SFONT,	IDH_SFONT,	TAB_STRING, 0},
		{"",	 IDC_SSHAPE,  IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_SCOLOR,  IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_SMERGE,  IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_SREPLACE,	IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_SNORMAL,  IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_SREVERSE,	IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_ONETARGET,	 IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_ALLTARGET,	 IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_SNOMOVE,  IDH_PSEARCH, TAB_HELP, 0},
		{"",	 IDC_SMOVE,	 IDH_PSEARCH, TAB_HELP, 0},
		{NULL, 0, 0, 0, }
	};
	static int f_rev;
	int c_pos, s_pos;
	static UINT f_change;
	UINT id;
	BOOL flag;
	static HWND hedit;
	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			f_rev = (SetGamma(0) < 0)?1:0;
			InitParaTab(para_tab, TRUE);
			InitAllPara(hDlg, para_tab, udWnd);
			InitParaTab(para_tab, FALSE);
			s_pos = SetDColor( hDlg, f_s_color, f_rev | 0x1000 );
enable:
			flag = (s_pos >= 3);
			for(id = IDC_SLLINE; id <= IDC_GROUPBOX6; ){
				EnableWindow( GetDlgItem( hDlg, id ), flag );
				if(id++ == IDC_SOLINE)
					id = IDC_GROUPBOX5;
			}
			if(f_change & INIT_APPLY)
				f_change = 0;
			break;

		case WM_COMMAND:
			switch( wParam )
			{
				case ID_SAVE:
					ReserveAllPara(hDlg, para_tab);
					ReserveIntPara("search", GetDSColor(hDlg));
					return TRUE;

				case ID_RESTORE:
					InitParaTab(para_tab, TRUE);
					RestoreAllPara(hDlg, para_tab, udWnd);
					s_pos = SetDColor( hDlg, 
						RestoreIntPara("search", F_B_REDC),
						f_rev | 0x1000 );
					ApplyOn(hDlg, &f_change);
					f_change = 3;
					goto enable;

				case IDC_SNORMAL:
				case IDC_SREVERSE:
					if(f_rev != (wParam == IDC_SREVERSE)?1:0){
						s_pos = SetDColor( hDlg, GetDSColor(hDlg), 
							f_rev | 0x2000 );
						f_rev = 1 - f_rev;
						goto enable;
					}
					return TRUE;

				case IDC_SMERGE:
				case IDC_SREPLACE:
				case IDC_SLLINE:
				case IDC_SRLINE:
				case IDC_SULINE:
				case IDC_SEULINE:
				case IDC_SOLINE:
				case IDC_ONETARGET:
				case IDC_ALLTARGET:
				case IDC_SNOMOVE:
				case IDC_SMOVE:
					ApplyOn(hDlg, &f_change);
					f_change |= 1;
					break;
			 }
			 switch( HIWORD(wParam) ){
				case CBN_SELCHANGE:		// selection is changed
					if(	 LOWORD(wParam) == IDC_SCOLOR
					 || LOWORD(wParam) == IDC_SSHAPE ){
						ApplyOn(hDlg, &f_change);
						f_change |= 1;
//						c_pos = SendDlgItemMessage(hDlg, IDC_SCOLOR,
//							CB_GETCURSEL, 0, 0L);
						s_pos = SendDlgItemMessage(hDlg, IDC_SSHAPE, 
							CB_GETCURSEL, 0, 0L);
						goto enable;
					}
					break;

				case EN_CHANGE:
					if(!(f_change & INIT_APPLY)
						  && CheckParaTab(para_tab, LOWORD(wParam))){
						ApplyOn(hDlg, &f_change);
						f_change |= 2;
					}
					break;
			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PSEARCH);
					break;

				case PSN_APPLY:
					c_pos = GetDSColor(hDlg);
					if(!f_change && c_pos == f_s_color)
						break;
					switch(QueryApply(hDlg, IDD_TAB_SEARCH)){
						case IDYES:			// change the current parameters
							if(f_change & 2)
								SetAllPara(hDlg, para_tab);
							f_s_color = c_pos;
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
						return TRUE;
					}
#endif
					ReSetFont(hedit);
					break;

//				case PSN_QUERYCANCEL:		// cancel
//					break;
					
				case PSN_SETACTIVE:
					AdjustPropPage(hDlg);
					hedit = GetDlgItem( hDlg, IDC_SFONT );
					SetFontJE(hedit);
					SetMargin(hedit);
					SetMargin(GetDlgItem(hDlg,IDC_SDPI));
					break;

			}
			break;
		
		case WM_DESTROY:
			break;
	}
	return FALSE;
}



/*
 ***********************	 History	 **********************************
 */
//	Setting
//	 UINT hyper:f_h_color
//	 int  hyperoff:f_hyper
//	 int  href:max_h_box, hname:max_h_name, hbuf:max_hyper_str
extern int max_h_box;
extern int max_h_name;
extern int max_hyper_str;
LRESULT CALLBACK HyperTabProc( HWND hDlg, UINT message, 
									WPARAM wParam, LPARAM lParam )
{
	static HWND udWnd[3];
	static int f_rev;
	static UINT f_change;
	int c_pos, s_pos, tmp;
	UINT id;
	BOOL flag;
	char *fname;
	static HWND hedit, hedit2;
	static PARA_TAB para_tab[] =
	{
		{"href",  IDC_HURL,	   IDH_HREF,  TAB_INT, 0},
		{"hname", IDC_HNAME,   IDH_HNAME, TAB_INT, 0},
		{"hbuf",  IDC_HSTRING, IDH_HBUF,  TAB_INTK, 0},
		{"Browser", IDC_BROWSER, IDH_BROWSER, TAB_STRING, 0},
		{"ToEdit",IDC_TOEDIT, IDH_TOEDIT, TAB_STRING, 0},
		{"",	  IDC_HDISABLE, IDH_HYPEROFF, TAB_HELP, 0},
		{"",	  IDC_HOUTER,  IDH_HYPEROFF, TAB_HELP, 0},
		{"",	  IDC_SPBROWSER,  IDH_BROWSER, TAB_HELP, 0},
		{"",	  IDC_SSHAPE,  IDH_PHYPERTEX, TAB_HELP, 0},
		{"",	  IDC_SCOLOR,  IDH_PHYPERTEX, TAB_HELP, 0},
		{"",	  IDC_SMERGE,  IDH_PHYPERTEX, TAB_HELP, 0},
		{"",	  IDC_SREPLACE,	 IDH_PHYPERTEX, TAB_HELP, 0},
		{"",	  IDC_SNORMAL,	IDH_PHYPERTEX, TAB_HELP, 0},
		{"",	  IDC_SREVERSE,	 IDH_PHYPERTEX, TAB_HELP, 0},
		{NULL, 0, 0, 0, 0}
	};

	switch( message )
	{
		case WM_INITDIALOG:
			f_change = INIT_APPLY;
			f_rev = (SetGamma(0) < 0)?1:0;

			InitParaTab(para_tab, TRUE);
			InitAllPara(hDlg, para_tab, udWnd);
			InitParaTab(para_tab, FALSE);
			if(f_hyper & 1)
				CheckDlgButton(hDlg, IDC_HDISABLE, TRUE);
			else if(f_hyper & 2)
				CheckDlgButton(hDlg, IDC_HOUTER, TRUE);
			if(browser != NULL && *browser)
				CheckDlgButton(hDlg, IDC_SPBROWSER, TRUE);
			else
				EnableWindow(GetDlgItem( hDlg, IDC_BROWSER ), FALSE);
			s_pos = SetDColor( hDlg, f_h_color, f_rev | 0x1000 );
enable:
			flag = (s_pos >= 3);
			for(id = IDC_SLLINE; id <= IDC_GROUPBOX6; ){
				EnableWindow( GetDlgItem( hDlg, id ), flag );
				if(id++ == IDC_SOLINE)
					id = IDC_GROUPBOX5;
			}
			if(f_change & INIT_APPLY)
				f_change = 0;
			break;

		case WM_COMMAND:
			switch( wParam )
			{
				case ID_SAVE:
					if(IsDlgButtonChecked(hDlg, IDC_HDISABLE))
						tmp = 1;
					else if(IsDlgButtonChecked(hDlg, IDC_HOUTER))
						tmp = 2;
					else tmp = 0;
					ReserveIntPara("hyper", GetDSColor(hDlg));
					ReserveIntPara("hyperoff", tmp);
					ReserveAllPara(hDlg, para_tab);
					if(!IsDlgButtonChecked(hDlg, IDC_SPBROWSER))
						ReserveStringPara("Browser", "");
					return TRUE;

				case ID_RESTORE:
					ApplyOn(hDlg, &f_change);
					f_change = 7;
					tmp = RestoreIntPara("hyperoff", 0);
					CheckDlgButton(hDlg, IDC_HDISABLE, (tmp&1)?TRUE:FALSE);
					EnableWindow( GetDlgItem( hDlg, IDC_HOUTER),
						(tmp&1)?FALSE:TRUE);
					CheckDlgButton(hDlg, IDC_HOUTER, (tmp&2)?TRUE:FALSE);
					InitParaTab(para_tab, TRUE);
					SetDlgItemText(hDlg, IDC_BROWSER, "");
					RestoreAllPara(hDlg, para_tab, udWnd);
					GetDlgItemText(hDlg, IDC_BROWSER, 
						(char *)common_work, 0x1000);
					flag = (*common_work <= 0x20)?FALSE:TRUE;
					CheckDlgButton(hDlg, IDC_SPBROWSER, flag);
					EnableWindow(GetDlgItem( hDlg, IDC_BROWSER ), flag);
					s_pos = SetDColor( hDlg,
						RestoreIntPara("hyper", F_B_SKY),
						f_rev | 0x1000 );
					goto enable;

				case IDC_SMERGE:
				case IDC_SREPLACE:
				case IDC_SLLINE:
				case IDC_SRLINE:
				case IDC_SULINE:
				case IDC_SEULINE:
				case IDC_SOLINE:
					ApplyOn(hDlg, &f_change);
					f_change |= 1;
					break;

				case IDC_TOEDIT:
					ApplyOn(hDlg, &f_change);
					f_change |= 8;

				case IDC_SPBROWSER:
					ApplyOn(hDlg, &f_change);
					flag = IsDlgButtonChecked(hDlg, IDC_SPBROWSER);
					EnableWindow(GetDlgItem( hDlg, IDC_BROWSER ), flag);
					if(	 flag 
					  && (fname = QueryGeneralName(
						"Query WWW Browser (executable file)",
						"Executable(*.exe;*.com;*.cmd;*.bat)",
						"*.exe;*.com;*.cmd;*.bat"
						)) != NULL)
						SetDlgItemText(hDlg, IDC_BROWSER, fname);
					f_change |= 4;
					break;

				case IDC_HDISABLE:
					EnableWindow( GetDlgItem( hDlg, IDC_HOUTER),
						IsDlgButtonChecked( hDlg, IDC_HDISABLE)?FALSE:TRUE);
				case IDC_HOUTER:
					ApplyOn(hDlg, &f_change);
					f_change |= 2;
					break;

				case IDC_SNORMAL:
				case IDC_SREVERSE:
					if(f_rev != (wParam == IDC_SREVERSE)?1:0){
						s_pos = SetDColor( hDlg, GetDSColor(hDlg), 
							f_rev |= 0x2000 );
						f_rev = 1 - f_rev;
						goto enable;
					}
					return TRUE;

			 }
			 switch( HIWORD(wParam) ){
				case CBN_SELCHANGE:		// selection is changed
					if(	 LOWORD(wParam) == IDC_SCOLOR
					 || LOWORD(wParam) == IDC_SSHAPE ){
						ApplyOn(hDlg, &f_change);
						f_change |= 1;
//						c_pos = SendDlgItemMessage(hDlg, IDC_SCOLOR,
//							CB_GETCURSEL, 0, 0L);
						s_pos = SendDlgItemMessage(hDlg, IDC_SSHAPE, 
							CB_GETCURSEL, 0, 0L);
						goto enable;
					}
					break;

				case EN_CHANGE:
					if(!(f_change & INIT_APPLY)
						  && CheckParaTab(para_tab, LOWORD(wParam))){
						ApplyOn(hDlg, &f_change);
						f_change |= 4;
					}
					break;

			}
			break;

		case WM_HELP:
			ShowWMHelp(lParam, para_tab);
			break;

		case WM_NOTIFY:
			switch(((NMHDR*)lParam)->code){
				case PSN_HELP:
					ShowWinHelp(IDH_PHYPERTEX);
					break;

				case PSN_APPLY:
					c_pos = GetDColor(hDlg);
					if(!f_change && c_pos == f_h_color)
						break;
					switch(QueryApply(hDlg, IDD_TAB_HYPER)){
						case IDYES:			// change the current parameters
							if(f_change & 1)
								f_h_color = c_pos;
							if(f_change & 2){
								f_hyper &= ~3;
								if(IsDlgButtonChecked(hDlg, IDC_HDISABLE))
									f_hyper |= 1;
								else if(IsDlgButtonChecked(hDlg, IDC_HOUTER))
									f_hyper |= 2;
								SendMessage( g_winData.toolbar.hWndToolBar, TB_CHECKBUTTON,
									ID_HYPER, MAKELONG((f_hyper&1)?FALSE:TRUE,0) );
							}
							if(f_change & 12){
								SetAllPara(hDlg, para_tab);
								if(!IsDlgButtonChecked(hDlg, IDC_SPBROWSER))
									SetParaStringDirect("Browser", "");
							}
							f_change = 0;
							g_bPropertySheetChange = TRUE;
							break;

						case IDCANCEL:		// cancel to apply
							return TRUE;

						case IDNO:			// skip to apply
							f_change |= NO_APPLY;
					}
					break;

				case PSN_KILLACTIVE:
#if	0
					if(f_DlgQuery){
						SetWindowLong( hDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );		
						return TRUE;
					}
#endif
					ReSetFont(hedit);
					ReSetFont(hedit2);
					break;
					
//				case PSN_QUERYCANCEL:		// cancel
//					break;
				
				case PSN_SETACTIVE:
					AdjustPropPage(hDlg);
					hedit = GetDlgItem( hDlg, IDC_BROWSER );
					SetFontJE(hedit);
					SetMargin(hedit);
					hedit2 = GetDlgItem( hDlg, IDC_TOEDIT );
					SetFontJE(hedit2);
					SetMargin(hedit2);
					SetMargin(GetDlgItem(hDlg,IDC_HURL));
					SetMargin(GetDlgItem(hDlg,IDC_HNAME));
					SetMargin(GetDlgItem(hDlg,IDC_HSTRING));
					break;
			}
			break;
		
		case WM_DESTROY:
			break;
	}
	return FALSE;
}


//////////////////////////////////////////////////////////////////////
//								Install								//
//////////////////////////////////////////////////////////////////////
static int i_dpi;
static int i_pdpi;
static int i_youshi;
static int i_landscape;
static int i_ret;
static int i_program;

static char *i_texroot;
static char *i_texpk;
static char *i_f;
static char *i_printer;
static char *i_gen;
static char *i_gsx;

static BOOL CALLBACK Dlg1Funct( HWND, UINT, UINT, LONG );
static BOOL CALLBACK Dlg2Funct( HWND, UINT, UINT, LONG );

static BOOL CALLBACK 
Dlg1Funct( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	int s_pos;
	char tmp[32];
	char i_tmp[64];
	char i_msg[0x100];
	static HWND hwnd;

#	define	LAST_SIZE (sizeof(papersize_str)/sizeof(char *))

	switch( message )
	{
		case WM_INITDIALOG:
			s_pos = GetLPTName((char *)i_printer, -1);
			if(s_pos > 0 && i_printer[0] == 0){
				s_pos = 0;
				goto no_prt;
			}
			sprintf(tmp, "LPT%d", s_pos);
			DeviceCapabilities(i_printer, tmp, DC_ENUMRESOLUTIONS,
				i_tmp, NULL);
			s_pos = DeviceCapabilities(i_printer, tmp, DC_ENUMRESOLUTIONS,
				NULL, NULL);
			DeviceCapabilities(i_printer, tmp, DC_ENUMRESOLUTIONS,
				i_tmp, NULL);
no_prt:		sprintf(i_msg, 
				(s_pos > 0)?
				"Default Windows System printer:\n  %s with %d dpi\n":
				"Default Windows System printer:\n  %s\n",
				i_printer, *((int *)i_tmp) );
			SetDlgItemText(hDlg, IDC_TOPTEXT, i_msg);

			CreateUpDownControl(
				WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				50, 22, 20, 20, 
				hDlg,
				ID_UPDOWN,
				g_winData.hInstance,
				(HWND)GetDlgItem( hDlg, IDC_EDIT1 ),
				10000, 10, i_dpi );

			hwnd=CreateUpDownControl(
				WS_CHILD | WS_VISIBLE | WS_BORDER | UDS_ARROWKEYS
				| UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_NOTHOUSANDS,
				50, 22, 20, 20, 
				hDlg,
				ID_UPDOWN,
				g_winData.hInstance,
				(HWND)GetDlgItem( hDlg, IDC_EDIT2 ),
				10000, 10, i_pdpi?i_pdpi:i_dpi );

			CheckDlgButton(hDlg, IDC_CHECK1, i_pdpi?TRUE:FALSE); 
			EnableWindow( GetDlgItem( hDlg, IDC_EDIT2), i_pdpi?TRUE:FALSE);
			for(s_pos = 0; s_pos < LAST_SIZE-1; )
				SendDlgItemMessage(hDlg, IDC_COMBOBOX2, CB_ADDSTRING, 0,
					(LPARAM)papersize_str[s_pos++]);
			SendDlgItemMessage(hDlg, IDC_COMBOBOX2, CB_SETCURSEL, i_youshi, 0);

			CheckRadioButton( hDlg, IDC_RADIOBUTTON1, IDC_RADIOBUTTON2, 
				(i_landscape)?IDC_RADIOBUTTON2:IDC_RADIOBUTTON1);
			SetFocus(GetDlgItem(hDlg, IDC_NEXT));
			break;

		case WM_COMMAND:
			switch(LOWORD(wParam)){
				case IDC_NEXT:
					i_dpi = GetDlgItemInt(hDlg, IDC_EDIT1, &s_pos, TRUE);
					if(i_dpi <= 10 || i_dpi >= 10000)
						i_dpi = 300;
					if(IsDlgButtonChecked(hDlg, IDC_CHECK1)){
						i_pdpi = GetDlgItemInt(hDlg, IDC_EDIT2, &s_pos, TRUE);
						if(i_pdpi <= 10 || i_pdpi >= 10000){
							i_pdpi = 0;
							CheckDlgButton(hDlg, IDC_CHECK1, FALSE);
						}
					}else
						i_pdpi = 0;
					if(i_dpi > 1000 && i_pdpi == 0 &&
					  AskYes(
						IsJapanese()?
						"解像度(dpi:)がプレビューには大き過ぎるので，\n"
						"パフォーマンスが落ちる可能性があります．\n"
						"表示と印刷とで異なる解像度を使いますか？\n"
						:
						"Resolution is rather high value for preview.\n"
						"The performance may be low.\n"
						"Define different dpi in preview?\n",
						"Warning")){
						sprintf(i_tmp, "%d", 600);
						SetDlgItemText(hDlg, IDC_EDIT1, i_tmp);
						CheckDlgButton(hDlg, IDC_CHECK1, TRUE);
						sprintf(i_tmp, "%d", i_dpi);
						SetDlgItemText(hDlg, IDC_EDIT2, i_tmp);
						goto chk;
					}
					i_youshi = SendDlgItemMessage(hDlg, IDC_COMBOBOX2,
						CB_GETCURSEL, 0, 0L);
					if(i_youshi < 0 || i_youshi >= LAST_SIZE - 1)
						i_youshi = 1;
					i_landscape = 
						IsDlgButtonChecked(hDlg, IDC_RADIOBUTTON2)?1:0;

				case IDCANCEL:
					i_ret = LOWORD(wParam);
					EndDialog(hDlg, 0);
					return 1;

				case IDC_CHECK1:
chk:				EnableWindow( GetDlgItem( hDlg, IDC_EDIT2), 
						IsDlgButtonChecked(hDlg, IDC_CHECK1));
					EnableWindow(hwnd, IsDlgButtonChecked(hDlg, IDC_CHECK1));
					break;

				case ID_MYHELP:
					ShowWinHelp(IDH_HDPI);
					break;

			}
	}
	return 0;
}

static BOOL CALLBACK 
Dlg2Funct( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	static int ff_init;
	int result;
	char tmp_pk[0x2000];
	char *texroot, *texpk, *texf;

	switch( message )
	{
		case WM_INITDIALOG:
			ff_init = 1;
			SetDlgItemText(hDlg, IDC_EDIT1, i_texroot);
			SetDlgItemText(hDlg, IDC_EDIT2, i_texpk);
			if(!*i_texpk)
				EnableWindow( GetDlgItem( hDlg, IDC_NEXT), FALSE );
			ff_init = 0;
			SetFocus(GetDlgItem(hDlg, IDC_BUTTON1));
			break;

		case WM_COMMAND:
			switch(LOWORD(wParam)){
				case IDC_BUTTON1:
					ChangeWaitCursor(1);
					DisplayWinMessage(hDlg, "");
					GetHDrive(texroot = tmp_pk+1);
					texpk = SEARCH_PK;
					texf = SEARCH_JFM;
					GetGSS(&texroot, &texpk, &texf, tmp_pk);
					result = DetectFont(&texroot, &texpk, &texf, 
						tmp_pk, i_dpi);
					ChangeWaitCursor(0);
					DisplayMessage(NULL);
					if(result == 0 || texpk == NULL){
						texf = "Cannot find fonts!";
//						goto err;
//					}
//					else if(result == -1){
//						ShowWinHelp(IDH_ERRJFM);
err:					MessageBox( hDlg, texf, "Warning", 
							(MB_OK|MB_ICONEXCLAMATION));
						break;
					}
					if(texroot)
						SetDlgItemText(hDlg, IDC_EDIT1, texroot);
					SetDlgItemText(hDlg, IDC_EDIT2, texpk);
					if(texf)
						strcpy(i_f, texf);
					SetFocus(GetDlgItem(hDlg, IDC_NEXT));
					break;

				case ID_MYHELP:
					ShowWinHelp(IDH_TEXPK);
					break;

				case IDC_BACK:
				case IDC_NEXT:
					GetDlgItemText(hDlg, IDC_EDIT1, i_texroot, 0x100);
				case IDCANCEL:
					i_ret = LOWORD(wParam);
					EndDialog(hDlg, 0);
					return 1;
			}
			switch( HIWORD(wParam) ){
				case EN_CHANGE:
					if(LOWORD(wParam) == IDC_EDIT2 && !ff_init){
						GetDlgItemText(hDlg, IDC_EDIT2, i_texpk, 0x1000);
						EnableWindow( GetDlgItem( hDlg, IDC_NEXT), 
							(*i_texpk)?TRUE:FALSE );
					}
			}
			break;
	}
	return 0;
}

static BOOL CALLBACK 
Dlg3Funct( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	char *sz;
	char tmp[0x400];
	static char f;

	switch( message )
	{
		case WM_INITDIALOG:
			SetDlgItemText(hDlg, IDC_EDIT1, i_gen);
			SetDlgItemText(hDlg, IDC_EDIT2, i_gsx);
			if(i_program & 1)
				CheckDlgButton(hDlg, IDC_CHECK1, TRUE);
			if(i_program & 2)
				CheckDlgButton(hDlg, IDC_CHECK2, TRUE);
			f = 0;
			SetFocus(GetDlgItem(hDlg, IDC_GENB));
			break;

		case WM_COMMAND:
			switch(LOWORD(wParam)){
				case IDC_GENB:
					if(AskYes("Automatic search?", "mktexpk/makepk/MaKeTeXPK")
					  == TRUE){
						*tmp = '`';
						strcpy(tmp+1, "mktexpk.exe");
						SearchFile(tmp+1);
						if(*(tmp+1)){
							strcat(tmp, 
							  "mktexpk.exe --dpi ^d --bdpi ^D --mag ^M ^s");
							SetDlgItemText(hDlg, IDC_EDIT1, tmp);
							goto fcs;
						}
						strcpy(tmp+1, "makepk.exe");
						SearchFile(tmp+1);
						if(*(tmp+1)){
							strcat(tmp, 
							  "makepk.exe ^s ^d ^D ^M");
							SetDlgItemText(hDlg, IDC_EDIT1, tmp);
							goto fcs;
						}
						strcpy(tmp+1, "MakeTeXPK.exe");
						SearchFile(tmp+1);
						if(*(tmp+1)){
							strcat(tmp, 
							  "MakeTeXPK.exe ^s ^d ^D ^M");
							SetDlgItemText(hDlg, IDC_EDIT1, tmp);
						}else
							ShowMessage("Cannot find mktexpk/makepk/MakeTeXPK",
								NULL , SM_OKCONT);
					}else if( (sz = QueryGeneralName(
						"Query font generation(executable file)", 
						"Executable(*.exe;*.com;*.cmd;*.bat)",
						"*.exe;*.com;*.cmd;*.bat"
						)) != NULL )
							SetDlgItemText(hDlg, IDC_EDIT1, sz);
fcs:				SetFocus(GetDlgItem(hDlg, IDC_NEXT));
					break;

				case IDC_GSXB:
					if(AskYes("Automatic search?", "gswin32.exe") == TRUE){
						GetGS_LIB(common_work);
						if(*common_work)
							SetDlgItemText(hDlg, IDC_EDIT2, common_work);
						else
							ShowMessage( "Cannot find gswin32(c)",
								NULL , SM_OKCONT);
					}else if( (sz = QueryGeneralName(
						"Query Ghostscript (executable file)", 
						"Executable(*.exe;*.com;*.cmd;*.bat)",
						"*.exe;*.com;*.cmd;*.bat"
					 )) != NULL )
						SetDlgItemText(hDlg, IDC_EDIT2, sz);
					goto fcs;

				case ID_MYHELP:
					ShowWinHelp((f++&1)?IDH_GSX:IDH_GEN);
					break;

				case IDC_BACK:
				case IDC_NEXT:
					GetDlgItemText(hDlg, IDC_EDIT1, i_gen, 0x200);
					GetDlgItemText(hDlg, IDC_EDIT2, i_gsx, 0x100);
					i_program &= ~3;
					if(IsDlgButtonChecked(hDlg, IDC_CHECK1))
						i_program |= 1;
					if(IsDlgButtonChecked(hDlg, IDC_CHECK2))
						i_program |= 2;
				case IDCANCEL:
					i_ret = LOWORD(wParam);
					EndDialog(hDlg, 0);
					return 1;
			}
	}
	return 0;
}

int RestoreClassString( char* str, int size, char* szKey, 
	char* key, char* def )
{
	HKEY hKey = NULL;
	DWORD dwType = REG_SZ;
	LONG lResult;
	DWORD copysize = size;
	str[0] = 0;
	if(RegOpenKeyEx( HKEY_CLASSES_ROOT, szKey, 0, KEY_READ, &hKey ) 
		!= ERROR_SUCCESS)
	{
		goto copydef;
	}
	lResult = RegQueryValueEx( hKey, key, 0, &dwType, (LPBYTE)str, &copysize );
	if( lResult == ERROR_MORE_DATA )
	{
		char* szData  = (char*)marea( copysize*sizeof(char) + 1 );
		RegQueryValueEx( hKey, key, 0, &dwType, (LPBYTE)szData, &copysize );
		lstrcpyn( str, szData, size );
		str[size - 1] = '\0';
		Free( szData );
		RegCloseKey( hKey );
		return lstrlen(str);
	}
	else if( lResult == ERROR_SUCCESS ){
		RegCloseKey( hKey );
		goto quit;
	}
copydef:
	RegCloseKey( hKey );
	if( lstrlen(str) == 0 )
	{
		int l = lstrlen( def );
		if( size <= l - 1 )
		{
			lstrcpyn( str, def, size );
			str[size-1] = '\0';
			return size - 1;
		}
		else
		{
			lstrcpyn( str, def, l + 1 );
			str[l] = '\0';
			return l;
		}
	}
quit:
	return lstrlen(str);
}

static BOOL ReserveClassString( char* szKey, char* key, char* sz )
{
	HKEY hKey;
	DWORD dwDisposition;

	if( RegCreateKeyEx( HKEY_CLASSES_ROOT, szKey, 
		0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, 
		NULL, &hKey, &dwDisposition ) != ERROR_SUCCESS )
	{
		MessageBox( NULL, "Error in RegCreateKey", NULL, MB_OK );
		return FALSE;
	}
	RegSetValueEx( hKey, key, 0, REG_SZ, (BYTE *)sz, lstrlen(sz)+1 );
	RegCloseKey( hKey );
	return	TRUE;
}

static void RelateExt(char *ext, char *name, char *show, 
	char *icon, char *path)
{
	char szKey[256];

	ReserveClassString(ext, NULL, name);		// .dvi		= dvifile
	ReserveClassString(name, NULL, show);		// dvifile	= TeX dvi file
												// dvifile\DefaultIcon = icon
	strcpy(szKey, name);
	strcat(szKey, "\\Defaulticon");
	ReserveClassString(szKey, NULL, icon);	
										// dvifile\Shell\open\command = path
	strcpy(szKey, name);
	strcat(szKey, "\\Shell\\open\\command");
	ReserveClassString(szKey, NULL, path);
}

void RelateDVI(void)
{
	char para[0x1800];

	strcpy(para, GetOutPath("exe"));
	strcpy(para + 0x400, para);
	strcat(para, ",1");
	strcat(para + 0x400, " %1");
	RelateExt(".dvi", "dvifile", "TeX DVI file", para, para + 0x400);
}

BOOL SetStartMenu(void)
{
	char para[0x1800];
	int s_pos;

	strcpy(para, GetOutPath("exe"));
	s_pos = strlen(para);
	if(s_pos < 10 || CallExplorer(START_EXPL, NULL, NULL, NULL) == 0)
		return FALSE;
	CallExplorer(CREATE_GROUP, "dviout", NULL, NULL);
	para[s_pos] = 0;
	CallExplorer(CREATE_ICON, "dviout", "dviout for Windows", para);
	if(IsJapanese()){
		strcpy(para + s_pos - 3, "hlp");
		CallExplorer(CREATE_ICON, "dviout", "Help for dviout", para);
	}
	strcpy(para + s_pos - 4, "e.hlp");
	if(access(para, 0) == 0)
		CallExplorer(CREATE_ICON, "dviout", "Help in English", para);
	strcpy(para + s_pos - 10, 
		(IsJapanese())?"hypertex\\hyper2.dvi":"sample\\sample.dvi");
	if(access(para, 0) == 0)
		CallExplorer(CREATE_ICON, "dviout", "sample dvi file", para);
	if(IsJapanese()){
		strcpy(para + s_pos - 10, "DOC\\dvioutQA.html");
		if(access(para, 0) == 0)
			CallExplorer(CREATE_ICON, "dviout", "Troubles in dviout", para);
		strcpy(para + s_pos - 10, "DOC\\dviouttips.html");
		if(access(para, 0) == 0)
			CallExplorer(CREATE_ICON, "dviout", "Tips on dviout", para);
	}else{
		strcpy(para + s_pos - 10, "DOC\\dviouttipse.html");
		if(access(para, 0) == 0)
			CallExplorer(CREATE_ICON, "dviout", "Tips on dviout", para);
	}
	CallExplorer(END_EXPL, NULL, NULL, NULL);
	return TRUE;
}


BOOL InstallPara( void )
{
	BOOL IsPC98(void);
	char para[0x1800], tmp[8];
	int s_pos, f_renew_old, c_mode, p_mode;
	char *pt;

	i_dpi = GetXDpi();
	i_texroot = (char*)marea(0x1600);
	i_gsx = i_texroot + 0x100;
	i_gen = i_gsx + 0x100;
	i_f	  = i_gen + 0x200;
	i_printer = i_f + 0x80;
	i_texpk = i_printer + 0x80;
	*i_texroot = *i_f = *i_texpk = *i_gen = *i_gsx = 0;
	i_program = 3;
	i_youshi = 1;
	c_mode = SetParaSection(-1);
	f_kakuto = FALSE;
	p_mode = RestoreIntPara("pmode", c_mode);
	if(c_mode != p_mode){
		sprintf(tmp, "para%d", p_mode);
		i_pdpi = RestoreInt(tmp, "dpi", GetXDpi());
	}else
		i_pdpi = 0;
	if(c_mode == p_mode)
		p_mode = 9;
	pt = GetParaString("TEXPK");
	if(pt != NULL){
		strcpy(i_texpk, pt);
		pt = GetParaString("TEXROOT");
		if(pt != NULL)
			strcpy(i_texroot, pt);
	}
	pt = GetParaString("gen");
	if(pt != NULL)
		strcpy(i_gen, pt);
	pt = GetParaString("gsx");
	if(pt != NULL)
		strcpy(i_gsx, pt);
	for(s_pos = 0; s_pos < LAST_SIZE-1; s_pos++){
		if(trans_papersize[s_pos] == paper_type){
			i_youshi = s_pos;
			break;
		}
	}
	f_renew_old = f_renew;
	f_renew = 0;
dlg1:
	DialogBox( g_winData.hInstance, MAKEINTRESOURCE(IDD_INST1),
							g_winData.dviwin.hWnd, Dlg1Funct);
	if(i_ret == IDCANCEL)
		goto can_quit;

dlg2:
	DialogBox( g_winData.hInstance, MAKEINTRESOURCE(IDD_INST2),
							g_winData.dviwin.hWnd, Dlg2Funct);
	if(i_ret == IDC_BACK)
		goto dlg1;
	if(i_ret == IDCANCEL)
		goto can_quit;

	DialogBox( g_winData.hInstance, MAKEINTRESOURCE(IDD_INST3),
							g_winData.dviwin.hWnd, Dlg3Funct);
	if(i_ret == IDC_BACK)
		goto dlg2;
	if(i_ret == IDCANCEL){
can_quit:
		Free0(i_texroot);
		f_renew = f_renew_old;
		return FALSE;
	}

	sprintf(para, "dpi=%d\n", i_dpi);
	sprintf(para + strlen(para), "y=%s%c\n", 
		para_paper[i_youshi], (i_landscape)?'L':'P');
	sprintf(para + strlen(para), "TEXROOT=" "\x22" "%s" "\x22" "\n", i_texroot);
	sprintf(para + strlen(para), "TEXPK=" "\x22" "%s" "\x22" "\n", i_texpk);
	sprintf(para + strlen(para), "gen=" "\x22" "%s" "\x22" "\n", i_gen);
	sprintf(para + strlen(para), "gsx=" "\x22" "%s" "\x22" "\n", i_gsx);
	if(*i_f)
		sprintf(para + strlen(para), "F=%s\n", i_f);
	if(f_osversion<0 && IsPC98()){
		strcat(para, "Wshow=+\n");
		CheckMenu( ID_CSHOW, TRUE );
	}
	SetPara(para, SAVE_REG);
	if(i_pdpi && c_mode != p_mode){
		ReserveIntPara("pmode", p_mode);
		SetParaSection(p_mode);
		ReserveIntPara("dpi", i_pdpi);
		RestoreString(i_texpk, 1024, ParaSection, "restore", "");
		if(!i_texpk[0])
			ReserveString(ParaSection, "restore", "2dpi:");
		RestoreString(i_texpk, 32, ParaSection, "mode", "");
		if(!i_texpk[0])
			ReserveString(ParaSection, "mode", "Default Printer");
		SetParaSection(c_mode);
	}else							// delete pmode
		DeletePara("pmode");
	if(!c_mode){
		RestoreString(i_texpk, 32, ParaSection, "mode", "");
		if(!i_texpk[0])
			ReserveString(ParaSection, "mode", "Default");
	}
									//	relate ".dvi"
	if(i_program & 1)
		RelateDVI();
									// start up menu
	if(i_program & 2)
		SetStartMenu();
									// copy dviout.def if KAKUTO version
	if(f_kakuto && (pt = strstr(i_texroot, "\\fonts")) != NULL) {
		strcpy(pt, "\\tex\\latex\\graphics\\dvips.def");
		pt += 20;
		if(my_access(i_texroot, 0) != FAILURE){
			strcpy(pt, "dviout.def");
			if(my_access(i_texroot, 0) == FAILURE){
				pt[-1]=0;
				SetPath(i_texpk, i_texroot);
				SetPath(i_texroot, "^x\\GRAPHIC\\LATEX2E\\dviout.def");
				sprintf(common_work, "copy %s %s", i_texroot, i_texpk);
				system(common_work);
			}
		} 
	}
	Free0(i_texroot);
	error(C_MSG, 
		IsJapanese()?
		"この画面は，右の [L] [S] ボタンで大きさを調整できます.\n\n"
		"細かいパラメータの設定は，Option → Setup Parameters... で行います． たとえば\n\n"
		"[Display] プレビュー画面における，紙面の表示サイズやコントラスト調整を行います．\n"
		"  実際に調整して，その状態を設定できます．\n\n"
		"一般に，次回以降の dviout にも設定を有効にするには [Save] を，今回有効に"
		"するには，\n[Ok] を押します．"
		"設定内容の詳細は，[Help] や [？] を使って参照してください．\n\n"
		"[Graphic] 画像関連で，カラーのPS画像取り込みには，-GIF: を設定します．\n\n"
		"[Common] エディターとの相互ジャンプには，-src: を設定して，source specialを\n"
		"用います．\n\n"
		"PDFファイルへの変換が，ニコニコマークのボタン（cf. View → Change Tool Buttons）\n"
		"で可能（要dvipdfm(x))．\n\n"
		"詳しくは，Help → Help topics/Tips on dviout/Troubles in dviout を参照して下さい．"
		:
		"This window can be changed its size by [L]/[S] button in the right side.\n\n"
		"Parameters can be modified by Property Sheets (Option->Setup Parameters...):\n\n"
/*
		"Generating Fonts: If mktexpk or MakeTeXPK is installed, Metafont\n"
		"    easily makes fonts which are requested by dviout.\n"
		"    For example, write as\n"
		"      `mktexpk ^s ^d ^D ^M cx\n"
		"    in a box after [gen:] in [Font2].\n"
		"    Here mktexpk in the above is replaced by MakeTeXPK if necessary.\n"
		"    cx is a <MODE> and may be replaced by blank in case of default.\n\n"
*/
		"[Display]  Preset the magnification and contrast of preview screens.\n\n"
		"On the sheets, push [Save] to define default, [Apply] or [Ok] to apply\n"
		"    the parameters to the current session and use [Help] or [?] for help.\n\n"
		"[Graphic]  Setting for graphics.\n"
		"  For example, arrange -GIF: to use colored PostScript graphics.\n\n"
		"[Common]  Set -src: for source special which enables the jumps to an editor.\n\n"
		"For more information, see  Help → Help topics/Tips on dviout etc..."
	);
	error(DATATITLE, "Some other parameters");	// title
	f_renew = f_renew_old;
	return TRUE;
}

BOOL CallExplorer( int type, char *group, char *name, char *path )
{
	HSZ hszService, hszTopic;
	static char szExecCode[1024];
	static HCONV g_hConv;

#define DDE_TIMEOUT		 3000

	if(type != START_EXPL && g_hConv == NULL)
		return 0;

	switch( type )
	{
		case START_EXPL:

			hszService = DdeCreateStringHandle( g_ddeData.idInst, 
				"PROGMAN", 0 );
			hszTopic   = DdeCreateStringHandle( g_ddeData.idInst, 
				"PROGMAN", 0 );
			g_hConv	   = DdeConnect( g_ddeData.idInst, hszService, 
				hszTopic, NULL );
			if( g_hConv == NULL )
			{
				WinExec( "PROGMAN.EXE", SW_SHOWNORMAL );
				g_hConv = DdeConnect( g_ddeData.idInst, hszService, 
					hszTopic, NULL );
			}
			DdeFreeStringHandle( g_ddeData.idInst, hszService );
			DdeFreeStringHandle( g_ddeData.idInst, hszTopic );
			if(g_hConv == NULL)
				return FALSE;
			break;

		case END_EXPL:
			DdeDisconnect( g_hConv );
			g_hConv = NULL;
			break;

		case CREATE_GROUP:
			wsprintf( szExecCode, "[CreateGroup(%s)]", group );
			DdeClientTransaction( szExecCode, sizeof(szExecCode), g_hConv, 
				NULL, CF_TEXT, XTYP_EXECUTE, DDE_TIMEOUT, NULL );
			break;;

		case CREATE_ICON:
			wsprintf( szExecCode, "[ShowGroup(%s,5)]", group );
			DdeClientTransaction( szExecCode, sizeof(szExecCode), g_hConv, 
				NULL, CF_TEXT, XTYP_EXECUTE, DDE_TIMEOUT, NULL );
			wsprintf( szExecCode, "[AddItem(\"%s\",\"%s\",\"%s\")]", 
				path, name, path );
			DdeClientTransaction( szExecCode, sizeof(szExecCode), g_hConv, 
				NULL, CF_TEXT, XTYP_EXECUTE, DDE_TIMEOUT, NULL );
			break;;

		case DELETE_GROUP:
			wsprintf( szExecCode, "[DeleteGroup(%s)]", group );
			DdeClientTransaction( szExecCode, sizeof(szExecCode), g_hConv, 
				NULL, CF_TEXT, XTYP_EXECUTE, DDE_TIMEOUT, NULL );
			break;

		case DELETE_ICON:
			wsprintf( szExecCode, "[ShowGroup(%s,5)]", group );
			DdeClientTransaction( szExecCode, sizeof(szExecCode), g_hConv, 
				NULL, CF_TEXT, XTYP_EXECUTE, DDE_TIMEOUT, NULL );
			wsprintf( szExecCode, "[DeleteItem(%s)]", name );
			DdeClientTransaction( szExecCode, sizeof(szExecCode), g_hConv, 
				NULL, CF_TEXT, XTYP_EXECUTE, DDE_TIMEOUT, NULL );
			break;
	}
	return TRUE;
}

#ifdef	USE_ETF
/* ttfont.c */
char *ffname(char *);

static ETF_INFO *etf_info;
static int short *etf_fdx;
static int etf_numc;
static int etf_numf;
static ETF_IMAGE *etf_img;

static char *GetImageName(char *path, int flag)
{
#ifdef UNIX
	char name[MAXFILE];

	get_fname(path, name);
	sprintf(common_work, "%c %s", flag?'+':' ', name);
#else
	char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], ext[MAXEXT];

	fnsplit(path, drive, dir, name, ext);
	sprintf(common_work, "%c %s%s", flag?'+':' ', name, ext);
#endif
	return common_work;
}

static char *GetFontName(FONT_INFO *font, int flag)
{
	char *msg, *name;

	switch(font->font_type){
		case CMTTF:
			msg = "TT";
			break;
		case VIRTUAL_FONT:
			msg = "VF";
			break;
		case PK_FONT:
			msg = "PK";
			break;
		case TT_FONT:
			msg = "JTT";
			break;
		case WINJTT_FONT:
			msg = "JFM";
			break;
		case WINTT_FONT:
			msg = "TFM";
			break;
		default:
			msg = "?";
			break;
	}
	if(font->font_type == TT_FONT)
		name = font->ext.kdir->name;
	else if(font->font_type == WINTT_FONT || font->font_type == WINJTT_FONT)
		name = font->n;
	else
		name = font->name;
	sprintf(common_work, "%c %-12s %-3s", flag?'+':' ', ffname(name), msg);
	if(font->font_type == PK_FONT)
		sprintf(common_work + strlen(common_work), " (%d/%d)", 
		font->sdpi&0xffff, font->sdpi>>16);
	return common_work;
}

static BOOL CALLBACK DlgETFFont( HWND hdwnd, UINT message, 
	UINT wParam, LONG lParam)
{
	static char *INI_PARA = "initial.par";
	int count, i, j, flag;
	static HWND hedit;
	ETF_IMAGE *im;

	switch(message){
		case WM_COMMAND:
			switch(LOWORD(wParam)){
				case IDC_ETFADD:
				case IDC_ETFDEL:
					count = SendDlgItemMessage(hdwnd, IDC_ETFFONT,
						LB_GETCURSEL, 0, 0L);
					if(count < 0)
						break;
					else if(count < etf_numf){
						for(i = 0; count != etf_fdx[i] && i < etf_numc; i++);
						GetFontName(etf_info[i].font, 
							(LOWORD(wParam) == IDC_ETFADD)?1:0); 
					}else{
						i = count - etf_numf;
						for(im = etf_img; im && i-- > 0;)
							im = im->next;
						if(!im)
							break;
						GetImageName(im->image,
							(LOWORD(wParam) == IDC_ETFADD)?1:0); 
					}
					SendDlgItemMessage(hdwnd, IDC_ETFFONT, 
						LB_DELETESTRING, count, 0);
					SendDlgItemMessage(hdwnd, IDC_ETFFONT, 
						LB_INSERTSTRING, count, (LPARAM)common_work);
					SendDlgItemMessage(hdwnd, IDC_ETFFONT, 
						LB_SETCURSEL, count, 0);
					common_work[0] = 0;
					break;

				case IDOK:
					for(i = count = j = 0; count < etf_numf; count++){
						SendDlgItemMessage(hdwnd, IDC_ETFFONT, 
							LB_GETTEXT, count, (LPARAM)common_work);
						flag = (common_work[0] == '+')?1:0;
						while(i < etf_numc && etf_fdx[i] <= count){
							if(etf_fdx[i] == count)
								etf_fdx[i] = flag?j:(-1);
							i++;
						}
						if(flag)
							j++;
					}
					for(im = etf_img; im; im = im->next){
						SendDlgItemMessage(hdwnd, IDC_ETFFONT, 
							LB_GETTEXT, count++, (LPARAM)common_work);
						if(common_work[0] != '+')
							im->flag = 0;
					}
					common_work[0] = 0;
					if(IsDlgButtonChecked(hdwnd, IDC_INIT)){
						GetDlgItemText(hdwnd, IDC_MES_LIST, common_work, 
							0x1000);
						i = strlen(common_work);
						while(--i > 0 && common_work[i] <= 0x20);
						common_work[i+1] = 0;
						if(i > 1 && i < 0x400)
							ReserveString("FILE", "inipar", common_work);
						if(!i)
							common_work[0] = 1;		// delete initial.par
					}
				case IDCANCEL:
					EndDialog(hdwnd, LOWORD(wParam));
				return TRUE;
			}
			break;

		case WM_INITDIALOG:
			hedit = GetDlgItem( hdwnd, IDC_MES_LIST );
			SetFontJE(hedit);
			SetMargin(hedit);
			for(count = i = 0; i < etf_numc; i++){
				if(etf_fdx[i] == count){
					SendDlgItemMessage(hdwnd, IDC_ETFFONT, LB_ADDSTRING, 0,
						(LPARAM)GetFontName(etf_info[i].font, 1)); 
					count++;
				}
			}
			for(im = etf_img; im; im=im->next)
				SendDlgItemMessage(hdwnd, IDC_ETFFONT, LB_ADDSTRING, 0,
					(LPARAM)GetImageName(im->image, 1));

			i = GetAddMemory(INI_PARA, NULL, 0);
			if(i > 0 && i < COMMON_SIZE){
				CheckDlgButton(hdwnd, IDC_INIT, TRUE);
iniset:			GetAddMemory(INI_PARA, common_work, i);
				common_work[i] = 0;
				SetDlgItemText(hdwnd, IDC_MES_LIST, common_work);
			}else{
				i = RestoreString(common_work, 0x1000, "FILE", "inipar", "");
				if(i > 1)
					goto iniset;
			}
			common_work[0] = 0;
			break;

		case WM_DESTROY:
			ReSetFont(hedit);
			break;
	}
	return FALSE;
}

BOOL ArrangeETFFont(ETF_INFO *fon, short int *fdx, int numc, int numf,
	ETF_IMAGE *img)
{
	etf_info = fon;
	etf_numc = numc;
	etf_numf = numf;
	etf_fdx =  fdx;
	etf_img = img;

	return
		(DialogBox( g_winData.hInstance, MAKEINTRESOURCE(IDD_ETFFONT), 
		g_winData.dviwin.hWnd, DlgETFFont ) == IDOK)?TRUE:FALSE;
}
#endif
