#define	STRICT
#include	<windows.h>
#include	<windowsx.h>
#include	<commctrl.h>
#include	<tchar.h>
#include	"kctrl.h"
#include	"resource.h"
#include	"basewin.h"
#include	"controls.h"
#include	"tools.h"
#include	"appmain.h"
#include	"dialog.h"

#ifdef	_WIN32_WCE
#include	<addrstor.h>
#include	<windbase.h>
#endif	/* _WIN32_WCE */

enum {
	MODE_FILE, MODE_BOOKMARK, MODE_FOLDER
} ;

#define		WM_USER_VIEW	(WM_USER+1)
#define		MAX_FN			128
#define		MAX_BOOKMARK	20
#define		is_kanji(x)		(((x)>=0x81 && (x)<=0x9F)||((x)>=0xE0 && (x)<=0xFC))

TCHAR		MessageBuf[ 512 ] ;
TCHAR		g_szFilePath[ MAX_PATH ] = TEXT("") ;
DWORD		g_dwTabSize = 8 ;
DWORD		g_dwHMargin = 1 ;
TCHAR		g_szEditor[ MAX_PATH ] = TEXT("") ;
TCHAR		g_szBaseDir[ MAX_PATH ] = TEXT("\\") ;

BOOL		g_bDeleteReg = FALSE ;		/* レジストリを削除する場合*真* */
LPTSTR		g_szFilename[ MAX_FN ] ;
DWORD		g_dwFilesize[ MAX_FN ] ;
BOOL		g_bMarked[ MAX_FN ] ;
DWORD		g_dwNumFilename = 0 ;
LPTSTR		g_szMarkName[ MAX_BOOKMARK ] ;
DWORD		g_dwMarkPos[ MAX_BOOKMARK ] ;
DWORD		g_dwNumMark = 0 ;
BYTE		g_szContent[ 1024 ] ;

KeyMapInfo	g_NarrowKeyMapInfo[] = {
	{ VK_RETURN, 0, FV_FUNC_ENTER },
	{ VK_ESCAPE, 0, FV_FUNC_ESC },
	{ VK_UP,     0, FV_FUNC_PRIOR },
	{ VK_DOWN,   0, FV_FUNC_NEXT },
	{ VK_LEFT,   0, FV_FUNC_PRIOR },
	{ VK_RIGHT,  0, FV_FUNC_NEXT },
	{ VK_PRIOR,  0, FV_FUNC_PRIOR },
	{ VK_NEXT,   0, FV_FUNC_NEXT },
	{ VK_HOME,   0, FV_FUNC_HOME },
	{ VK_END,    0, FV_FUNC_END },
	{ VK_BACK,   0, FV_FUNC_PRIOR },
	{ ' ',       1, FV_FUNC_NEXT },
	{ 0,         0, 0 }
} ;

BOOL CALLBACK	AboutDlgFunc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) ;

DWORD
CalcStrCols( LPCTSTR text )
{
	TCHAR	c ;
	DWORD	col ;

	col = 0 ;
	while ( c = *text++ ) {
		if ( is_hankaku( c ) ) {
			col ++ ;
		} else {
			col += 2 ;
		}
	}
	return col ;
}

void
ShowSIP( BOOL bShow )
{
	SIPINFO		si ;

	memset( &si, 0, sizeof si ) ;
	si.cbSize = sizeof si ;
	if ( SHSipInfo && SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 ) ) {
		if ( bShow ) {
			si.fdwFlags |= SIPF_ON ;
		} else {
			si.fdwFlags &= ~SIPF_ON ;
		}
		SHSipInfo( SPI_SETSIPINFO, 0, &si, 0 ) ;
	}
}

void
clear_filename()
{
	DWORD		i ;

	for ( i = 0 ; i < g_dwNumFilename ; i ++ ) {
		if ( g_szFilename[ i ] ) {
			LocalFree( g_szFilename[ i ] ) ;
		}
	}
	for ( i = 0 ; i < MAX_FN ; i ++ ) {
		g_szFilename[ i ] = 0 ;
	}
	g_dwNumFilename = 0 ;
}

void
add_filename( LPCTSTR fn, DWORD size, BOOL bMarked )
{
	DWORD	i, j, len = _tcslen( fn ) ;

	if ( g_dwNumFilename >= MAX_FN ) {
		return ;
	}
	for ( i = 0 ; i < g_dwNumFilename ; i ++ ) {
		if ( _tcsicmp( fn, g_szFilename[ i ] ) < 0 ) {
			for ( j = g_dwNumFilename ; j > i ; j -- ) {
				g_szFilename[ j ] = g_szFilename[ j - 1 ] ;
				g_dwFilesize[ j ] = g_dwFilesize[ j - 1 ] ;
				g_bMarked[ j ] = g_bMarked[ j - 1 ] ;
			}
			break ;
		}
	}
	g_szFilename[ i ] = (LPTSTR) LocalAlloc( LPTR, (len + 1) * sizeof (TCHAR) ) ;
	_tcscpy( g_szFilename[ i ], fn ) ;
	g_dwFilesize[ i ] = size ;
	g_bMarked[ i ] = bMarked ;
	g_dwNumFilename ++ ;
}

/*
 * しおりの一覧をクリアする
 */
void
clear_bookmark()
{
	DWORD		i ;

	for ( i = 0 ; i < g_dwNumMark ; i ++ ) {
		if ( g_szMarkName[ i ] ) {
			LocalFree( g_szMarkName[ i ] ) ;
		}
	}
	for ( i = 0 ; i < MAX_BOOKMARK ; i ++ ) {
		g_szMarkName[ i ] = 0 ;
	}
	g_dwNumMark = 0 ;
}

/*
 * しおりにファイルを追加する
 */
void
add_bookmark( LPCTSTR fn, DWORD pos )
{
	DWORD	i, len = _tcslen( fn ) ;

	for ( i = 0 ; i < g_dwNumMark ; i ++ ) {
		if ( !_tcsicmp( g_szMarkName[ i ], fn ) ) {
			g_dwMarkPos[ i ] = pos ;
			return ;
		}
	}
	if ( g_dwNumMark >= MAX_BOOKMARK ) {
		LocalFree( g_szMarkName[ g_dwNumMark - 1 ] ) ;
		for ( i = g_dwNumMark - 1 ; i > 0 ; i -- ) {
			g_szMarkName[ i ] = g_szMarkName[ i - 1 ] ;
			g_dwMarkPos[ i ] = g_dwMarkPos[ i - 1 ] ;
		}
		g_szMarkName[ 0 ] = (LPTSTR) LocalAlloc( LPTR, (len + 1) * sizeof (TCHAR) ) ;
		_tcscpy( g_szMarkName[ 0 ], fn ) ;
		g_dwMarkPos[ 0 ] = pos ;
		return ;
	}
	g_szMarkName[ g_dwNumMark ] = (LPTSTR) LocalAlloc( LPTR, (len + 1) * sizeof (TCHAR) ) ;
	_tcscpy( g_szMarkName[ g_dwNumMark ], fn ) ;
	g_dwMarkPos[ g_dwNumMark ] = pos ;
	g_dwNumMark ++ ;
}

/*
 * しおりにファイルがあるか調べる
 */
BOOL
find_bookmark( LPCTSTR path, LPDWORD pos )
{
	DWORD	i ;

	for ( i = 0 ; i < g_dwNumMark ; i ++ ) {
		if ( !_tcsicmp( g_szMarkName[ i ], path ) ) {
			if ( pos ) {
				*pos = g_dwMarkPos[ i ] ;
			}
			return TRUE ;
		}
	}
	return FALSE ;
}

/*
 * しおりを削除する
 */
BOOL
delete_bookmark( LPCTSTR path )
{
	DWORD	i ;

	for ( i = 0 ; i < g_dwNumMark ; i ++ ) {
		if ( !_tcsicmp( g_szMarkName[ i ], path ) ) {
			LocalFree( g_szMarkName[ i ] ) ;
			for ( ; i < g_dwNumMark - 1 ; i ++ ) {
				g_szMarkName[ i ] = g_szMarkName[ i + 1 ] ;
				g_dwMarkPos[ i ] = g_dwMarkPos[ i + 1 ] ;
			}
			g_dwNumMark -- ;
			return TRUE ;
		}
	}
	return FALSE ;
}

/*
 * バッファからしおりを取得する
 */
void
load_bookmark( LPCTSTR str )
{
	TCHAR		c ;
	BOOL		bPos ;
	TCHAR		pos[ 20 ], *posptr ;
	TCHAR		name[ MAX_PATH ], *nameptr;

	clear_bookmark() ;
	bPos = FALSE ;
	nameptr = name ;
	posptr = pos ;
	while ( c = *str++ ) {
		if ( c == TEXT('\n') ) {
			*nameptr = *posptr = 0 ;
			if ( *name ) {
				add_bookmark( name, _ttol( pos ) ) ;
			}
			bPos = FALSE ;
			nameptr = name ;
			posptr = pos ;
		} else if ( c == TEXT('\t') ) {
			bPos = TRUE ;
		} else if ( c == TEXT('\r') ) {
			continue ;
		} else if ( bPos ) {
			*posptr++ = c ;
		} else {
			*nameptr++ = c ;
		}
	}
	*nameptr = *posptr = 0 ;
	if ( *name ) {
		add_bookmark( name, _ttol( pos ) ) ;
	}
}

/*
 * しおりをバッファに格納する
 */
void
save_bookmark( LPTSTR str )
{
	DWORD	i ;

	for ( i = 0 ; i < g_dwNumMark ; i ++ ) {
		_tcscpy( str, g_szMarkName[ i ] ) ;
		str += _tcslen( str ) ;
		*str++ = TEXT('\t') ;
		wsprintf( str, TEXT("%d"), g_dwMarkPos[ i ] ) ;
		str += _tcslen( str ) ;
		*str++ = TEXT('\r') ;
		*str++ = TEXT('\n') ;
	}
	*str = 0 ;
}

/*
 * ファイルの一覧を取得する
 */
BOOL
GetFilenames( LPCTSTR dir )
{
	WIN32_FIND_DATA	find ;
	HANDLE			hFind ;
	BOOL			bMarked ;
	TCHAR			findPath[ MAX_PATH ], *ptr ;

	clear_filename() ;
	/* ファイル検索用のワイルドカードを作成する */
	_tcscpy( findPath, dir ) ;
	catdir( findPath, TEXT("*.*"), NULL ) ;
	/* ファイルを検索する */
	hFind = FindFirstFile( findPath, &find ) ;
	if ( hFind != INVALID_HANDLE_VALUE ) {
		do {
			if ( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
				continue ;
#ifdef	_WIN32_WCE
			} else if ( find.dwFileAttributes & FILE_ATTRIBUTE_INROM ) {
				continue ;
			} else if ( find.dwFileAttributes & FILE_ATTRIBUTE_ROMSTATICREF ) {
				continue ;
			} else if ( find.dwFileAttributes & FILE_ATTRIBUTE_ROMMODULE ) {
				continue ;
#endif	/* _WIN32_WCE */
			}
			/* バイナリファイルは除外 */
			ptr = _tcsrchr( find.cFileName, TEXT('.') ) ;
			if ( ptr ) {
				if ( !_tcsicmp( ptr, TEXT(".BMP") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".2BP") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".WAV") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".LNK") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".DLL") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".TTF") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".CPL") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".EXE") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".LZH") ) ) {
					continue ;
				} else if ( !_tcsicmp( ptr, TEXT(".ZIP") ) ) {
					continue ;
				}
			}
			_tcscpy( findPath, dir ) ;
			catdir( findPath, find.cFileName, NULL ) ;
			bMarked = find_bookmark( findPath, NULL ) ;
			add_filename( find.cFileName, find.nFileSizeLow, bMarked ) ;
		} while ( FindNextFile( hFind, &find ) ) ;
		FindClose( hFind ) ;
	}
	if ( g_dwNumFilename ) {
		return TRUE ;
	}
	add_filename( TEXT("<No Files>"), 0, FALSE ) ;
	return FALSE ;
}

/*
 * フォルダの一覧を取得する
 */
BOOL
GetFolders( LPCTSTR dir )
{
	WIN32_FIND_DATA	find ;
	HANDLE			hFind ;
	TCHAR			findPath[ MAX_PATH ] ;

	clear_filename() ;
	if ( _tcscmp( dir, TEXT("\\") ) ) {
		add_filename( TEXT(".."), 0, FALSE ) ;
	}
	/* ファイル検索用のワイルドカードを作成する */
	_tcscpy( findPath, dir ) ;
	catdir( findPath, TEXT("*.*"), NULL ) ;
	/* ファイルを検索する */
	hFind = FindFirstFile( findPath, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		return FALSE ;
	}
	do {
		if ( !(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
			continue ;
		}
		if ( !_tcscmp( find.cFileName, TEXT(".") ) ) {
			continue ;
		} else if ( !_tcscmp( find.cFileName, TEXT("..") ) ) {
			continue ;
		}
		add_filename( find.cFileName, find.nFileSizeLow, FALSE ) ;
	} while ( FindNextFile( hFind, &find ) ) ;
	FindClose( hFind ) ;
	return TRUE ;
}

/*
 * しおりの一覧を取得する
 */
void
GetBookMarks()
{
	DWORD		i ;

	clear_filename() ;
	add_filename( TEXT("(Directory)"), 0, FALSE ) ;
	for ( i = 0 ; i < g_dwNumMark ; i ++ ) {
		add_filename( g_szMarkName[ i ], g_dwMarkPos[ i ], FALSE ) ;
	}
}

/*
 * ファイルの一部内容を取得する
 */
BOOL
GetFileContent( LPCTSTR path )
{
	DWORD	nRead ;
	HANDLE	hFile ;

	hFile = CreateFile( path,
				GENERIC_READ,
				FILE_SHARE_READ,
				NULL,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				NULL ) ;
	if ( hFile == INVALID_HANDLE_VALUE ) {
		return FALSE ;
	}
	memset( g_szContent, 0, sizeof g_szContent ) ;
	ReadFile( hFile, g_szContent, sizeof g_szContent, &nRead, NULL ) ;
	g_szContent[ sizeof g_szContent - 1 ] = 0 ;
	CloseHandle( hFile ) ;
	return TRUE ;
}

/*
 * フォルダ内のファイル一覧を取得する
 */
BOOL
GetFolderContent( LPCTSTR dir, DWORD maxLine )
{
	LPBYTE			dst ;
	WIN32_FIND_DATA	find ;
	HANDLE			hFind ;
	DWORD			count = 0 ;
	BYTE			sjis[ MAX_PATH ] ;
	TCHAR			findPath[ MAX_PATH ], *ptr ;

	dst = g_szContent ;
	*dst = 0 ;
	if ( !*g_szFilePath ) {
		return FALSE ;
	}
	/* ファイル検索用のワイルドカードを作成する */
	_tcscpy( findPath, dir ) ;
	catdir( findPath, TEXT("*.*"), NULL ) ;
	/* ファイルを検索する */
	hFind = FindFirstFile( findPath, &find ) ;
	if ( hFind == INVALID_HANDLE_VALUE ) {
		return FALSE ;
	}
	do {
		if ( !_tcscmp( find.cFileName, TEXT(".") ) ) {
			continue ;
		} else if ( !_tcscmp( find.cFileName, TEXT("..") ) ) {
			continue ;
#ifdef	_WIN32_WCE
		} else if ( find.dwFileAttributes & FILE_ATTRIBUTE_INROM ) {
			continue ;
		} else if ( find.dwFileAttributes & FILE_ATTRIBUTE_ROMSTATICREF ) {
			continue ;
		} else if ( find.dwFileAttributes & FILE_ATTRIBUTE_ROMMODULE ) {
			continue ;
#endif	/* _WIN32_WCE */
		}
		/* バイナリファイルは除外 */
		ptr = _tcsrchr( find.cFileName, TEXT('.') ) ;
		if ( ptr ) {
			if ( !_tcsicmp( ptr, TEXT(".BMP") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".2BP") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".WAV") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".LNK") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".DLL") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".TTF") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".CPL") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".EXE") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".LZH") ) ) {
				continue ;
			} else if ( !_tcsicmp( ptr, TEXT(".ZIP") ) ) {
				continue ;
			}
		}
		unicode2sjis( find.cFileName, sjis, sizeof sjis ) ;
		if ( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
			*dst++ = '[' ;
			strcpy( (LPSTR) dst, (LPSTR) sjis ) ;
			dst += strlen( (LPSTR) dst ) ;
			*dst++ = ']' ;
		} else {
			strcpy( (LPSTR) dst, (LPSTR) sjis ) ;
			dst += strlen( (LPSTR) dst ) ;
		}
		*dst++ = '\n' ;
		if ( ++ count >= maxLine ) {
			break ;
		}
	} while ( FindNextFile( hFind, &find ) ) ;
	FindClose( hFind ) ;
	*dst = 0 ;
	return TRUE ;
}

BOOL
ExecProgram( LPCTSTR fn )
{
#ifdef	_WIN32_WCE
	if ( *g_szEditor ) {
		PROCESS_INFORMATION		pi ;

		if ( CreateProcess( g_szEditor, fn,
							NULL, NULL, FALSE,
							0,
							NULL, NULL, NULL,
							&pi ) ) {
			CloseHandle( pi.hProcess ) ;
			CloseHandle( pi.hThread ) ;
			return TRUE ;
		}
	} else {
		SHELLEXECUTEINFO		sei ;

		memset( &sei, 0, sizeof sei ) ;
		sei.cbSize = sizeof sei ;
		sei.fMask = 0 ;
		sei.hwnd = NULL ;
		sei.lpVerb = TEXT("Open") ;
		sei.lpFile = fn ;
		sei.lpParameters = NULL ;
		sei.lpDirectory = NULL ;
		sei.nShow = SW_SHOW ;
		if ( ShellExecuteEx( &sei ) ) {
			return TRUE ;
		}
	}
#endif	/* _WIN32_WCE */
	return FALSE ;
}

BOOL
copy_line( LPCSTR src, LPSTR dst, DWORD len, LPCSTR *newsrc )
{
	BOOL	bKanji ;
	DWORD	w, char_len, pos = 0 ;
	BYTE	c ;

	w = len ;
	while ( c = *src ++ ) {
		if ( c == '\t' ) {
			bKanji = FALSE ;
			char_len = g_dwTabSize - (pos % g_dwTabSize) ;
		} else {
			bKanji = is_kanji( c ) ;
			char_len = bKanji ? 2 : 1 ;
		}
		if ( c == '\r' ) {
			continue ;
		} else if ( c == '\n' ) {
			src ++ ;
			break ;
		} else if ( len < char_len ) {
			if ( c == '\t' ) {
				src ++ ;
			}
			break ;
		}
		len -= char_len ;
		pos += char_len ;
		if ( c == '\t' ) {
			do {
				*dst ++ = ' ' ;
			} while ( -- char_len ) ;
		} else {
			*dst ++ = c ;
		}
		if ( bKanji ) {
			c = *src ++ ;
			if ( !c ) {
				src -- ;
				dst -- ;
				break ;
			}
			*dst ++ = c ;
		}
	}
	*dst = 0 ;
	*newsrc = src - 1 ;
	return c != 0 ;
}

/*
 * メインウィンドウ
 */
class MainWindow : public Window {
private:
	MainApp		*m_pApp ;		/* アプリケーションへのポインタ */
	HWND		m_hwndCB ;		/* CommandBarのハンドル */
	HICON		m_hIcon ;		/* アプリアイコンのハンドル */
	HWND		m_hwndFile ;	/* 一覧領域のハンドル */
	HWND		m_hwndContent ;	/* 内容領域のハンドル */
	HWND		m_hwndView ;	/* 詳細内容領域のハンドル */
	DWORD		m_dwTopPos ;	/* 一番上のコントロールのY座標 */
	TCHAR		m_szCurDir[ MAX_PATH ] ;
	BOOL		m_bNarrow ;		/* 画面が狭い場合*真* */
	DWORD		m_dwMode ;		/* 現在の画面モード */

	DWORD	CreateCommandBar() ;

public:
	MainWindow( MainApp * ) ;
	~MainWindow() ;

	BOOL	Create() ;
	void	WMCreate( HWND hWnd ) ;
	void	WMDestroy() ;
	LRESULT	WMCommand( HWND hWnd, UINT msg, WPARAM wp, LPARAM lp ) ;
	void	WMSetFocus() ;
	BOOL	WMClose() ;
	LRESULT	WMWndProc( HWND hWnd,  UINT msg, WPARAM wParam, LPARAM lParam, BOOL *bDefault ) ;
	void	WMInitMenuPopup( HMENU hmenuPopup, UINT uPos, BOOL fSystemMenu ) ;
	BOOL	OpenFileView( DWORD pos ) ;
	void	CloseFileView() ;

	static	BOOL	RegisterClass( HINSTANCE hInst ) ;
	static	LPCTSTR	GetClassName() { return szClassName ; }

	static	int		file_proc( int index, const BYTE **ptr, int *len ) ;
	static	int		content_proc( int index, const BYTE **ptr, int *len ) ;

	static	DWORD	m_dwMaxFileCol ;
	static	DWORD	m_dwMaxContentCol ;
	static	DWORD	m_dwMaxContentLine ;
} ;

/*-------------------------------------------------------------------------*
 * MainApp
 *-------------------------------------------------------------------------*/
MainApp::MainApp()
{
	m_pMainWnd = 0 ;
	clear_filename() ;
	clear_bookmark() ;
}

MainApp::~MainApp()
{
	clear_filename() ;
	clear_bookmark() ;
}

BOOL
MainApp::Create( HINSTANCE hInstance )
{
	m_hInst = hInstance ;

	if ( !MainWindow::RegisterClass( m_hInst ) ) {
		return FALSE ;
	}
	if ( !BigListRegisterClass( m_hInst ) ) {
		return FALSE ;
	}
	if ( !LineEditRegisterClass( m_hInst ) ) {
		return FALSE ;
	}
	if ( !FileViewRegisterClass( m_hInst ) ) {
		return FALSE ;
	}

#ifdef	_WIN32_WCE
	m_hAccl = LoadAccelerators( m_hInst,
								MAKEINTRESOURCE(IDR_ACCELERATOR1) ) ;
#else	/* _WIN32_WCE */
	m_hAccl = LoadAccelerators( GetModuleHandle(NULL),
								MAKEINTRESOURCE(IDR_ACCELERATOR1) ) ;

#endif	/* _WIN32_WCE */

	GetReg() ;

	m_pMainWnd = new MainWindow( this ) ;
	if ( !m_pMainWnd ) {
		return FALSE ;
	}
	if ( !m_pMainWnd->Create() ) {
		return FALSE ;
	}

	/* 画面を前面にする */
	SetForegroundWindow( m_pMainWnd->get_hwnd() ) ;
	return TRUE ;
}

int
MainApp::Run()
{
	MSG		msg ;

	while ( GetMessage( &msg, NULL, 0, 0 ) ) {
		if ( !TranslateAccelerator( m_pMainWnd->get_hwnd(), m_hAccl, &msg ) ) {
			TranslateMessage( &msg ) ;
		}
		DispatchMessage( &msg ) ;
	}
	return msg.wParam ;
}

#define		REG_BASEKEY		TEXT("Software\\Gawaro\\")
#define		VAR_EDITOR		TEXT("Editor")
#define		VAR_BASEDIR		TEXT("InitDir")
#define		VAR_BOOKMARK	TEXT("BookMark")
#define		VAR_TABSIZE		TEXT("TabSize")
#define		VAR_HMARGIN		TEXT("HMargin")

/*
 * レジストリからの情報取得
 */
BOOL
MainApp::GetReg()
{
	HKEY	hk ;
	LONG	lret ;
	LPTSTR	name ;
	LPBYTE	lpData ;
	DWORD	dwType, cbData ;
	TCHAR	subkey[ MAX_PATH ] ;

	_tcscpy( subkey, REG_BASEKEY ) ;
	_tcscat( subkey, szTitleName ) ;
	/* レジストリキーをオープンする */
	lret = RegOpenKeyEx( HKEY_CURRENT_USER, subkey, 0, KEY_QUERY_VALUE, &hk ) ;
	if ( lret != ERROR_SUCCESS ) {
		return FALSE ;
	}
	/* エディタープログラム名 */
	name = VAR_EDITOR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) g_szEditor ;
	cbData = sizeof g_szEditor ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
	/* ディレクトリ名 */
	name = VAR_BASEDIR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) g_szBaseDir ;
	cbData = sizeof g_szBaseDir ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
	/* しおり */
	name = VAR_BOOKMARK ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) MessageBuf ;
	cbData = sizeof MessageBuf ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
	if ( lret == ERROR_SUCCESS ) {
		load_bookmark( MessageBuf ) ;
	}
	/* TabSize */
	name = VAR_TABSIZE ;
	dwType = REG_DWORD ;
	lpData = (LPBYTE) &g_dwTabSize ;
	cbData = sizeof g_dwTabSize ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
	/* HMargin */
	name = VAR_HMARGIN ;
	dwType = REG_DWORD ;
	lpData = (LPBYTE) &g_dwHMargin ;
	cbData = sizeof g_dwHMargin ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
	/* レジストリをクローズする */
	RegCloseKey( hk ) ;
	return TRUE ;
}

/*
 * レジストリへの情報設定
 */
BOOL
MainApp::SetReg() const
{
	HKEY	hk ;
	LONG	lret ;
	LPTSTR	name ;
	LPBYTE	lpData ;
	TCHAR	subkey[ MAX_PATH ] ;
	DWORD	ret, dwType, cbData ;

	_tcscpy( subkey, REG_BASEKEY ) ;
	_tcscat( subkey, szTitleName ) ;
	/* レジストリキーを作成する */
	lret = RegCreateKeyEx( HKEY_CURRENT_USER, subkey, 0, TEXT(""), 0,
#ifdef	_WIN32_WCE
						   0,
#else	/* _WIN32_WCE */
						   KEY_ALL_ACCESS,
#endif	/* _WIN32_WCE */
						   NULL, &hk, &ret ) ;
	if ( lret != ERROR_SUCCESS ) {
		return FALSE ;
	}
	/* エディタープログラム名 */
	name = VAR_EDITOR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) g_szEditor ;
	cbData = (_tcslen(g_szEditor) + 1) * sizeof (*g_szEditor) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* ディレクトリ名 */
	name = VAR_BASEDIR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) g_szBaseDir ;
	cbData = (_tcslen(g_szBaseDir) + 1) * sizeof (*g_szBaseDir) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* しおり */
	save_bookmark( MessageBuf ) ;
	name = VAR_BOOKMARK ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) MessageBuf ;
	cbData = (_tcslen(MessageBuf) + 1) * sizeof (*MessageBuf) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* TabSize */
	name = VAR_TABSIZE ;
	dwType = REG_DWORD ;
	lpData = (LPBYTE) &g_dwTabSize ;
	cbData = sizeof g_dwTabSize ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* HMargin */
	name = VAR_HMARGIN ;
	dwType = REG_DWORD ;
	lpData = (LPBYTE) &g_dwHMargin ;
	cbData = sizeof g_dwHMargin ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* レジストリをクローズする */
	RegCloseKey( hk ) ;
	return TRUE ;
}

/*
 * レジストリ情報削除
 */
void
MainApp::DeleteReg() const
{
	TCHAR	subkey[ MAX_PATH ] ;

	_tcscpy( subkey, REG_BASEKEY ) ;
	_tcscat( subkey, szTitleName ) ;
	RegDeleteKey( HKEY_CURRENT_USER, subkey ) ;
}

/*-------------------------------------------------------------------------*
 * MainWindow
 *-------------------------------------------------------------------------*/
DWORD	MainWindow::m_dwMaxFileCol = 40 ;
DWORD	MainWindow::m_dwMaxContentCol = 40 ;
DWORD	MainWindow::m_dwMaxContentLine = 10 ;

MainWindow::MainWindow( MainApp *pApp )
{
	m_pApp = pApp ;
	m_hIcon = 0 ;
	_tcscpy( m_szCurDir, TEXT("\\") ) ;
	m_dwMode = MODE_FILE ;
}

MainWindow::~MainWindow()
{
	if ( m_hIcon ) {
		::DeleteObject( m_hIcon ) ;
	}
}

void
MainWindow::WMCreate( HWND hWnd )
{
	RECT		rect ;
	DWORD		height = 2, tw, th ;
	DWORD		x1, x2, x3, y1, y2, y3 ;
	DWORD		w1, w2, w3, h1, h2, h3 ;
	HINSTANCE	hInst = m_pApp->get_inst() ;

	m_hwnd = hWnd ;
	/* 表示領域を求める */
	GetClientRect( m_hwnd, &rect ) ;
	tw = rect.right ;
	th = rect.bottom ;
	m_bNarrow = rect.right <= 400 ;
	/* アイコンを作成しタスクバーに登録する */
	m_hIcon = (HICON) LoadImage( m_pApp->get_inst(), MAKEINTRESOURCE(IDI_APPICON),
								 IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR ) ;
	if ( m_hIcon ) {
		SendMessage( hWnd, WM_SETICON, FALSE, (LPARAM)m_hIcon ) ;
	}
	/* コマンドバーを追加する */
	height += CreateCommandBar() ;
	m_dwTopPos = height ;
	/* コントロールの配置を計算する */
	if ( m_bNarrow ) {
		w1 = w2 = tw - 2 ;
		x1 = x2 = 0 ;
		y1 = height ;
		h1 = h2 = (th - height - 4) / 2 ;
		y2 = y1 + h1 + 2 ;
	} else {
		w1 = 240 ;
		w2 = tw - 4 - w1 ;
		x1 = 0, x2 = x1 + w1 + 2 ;
		y1 = y2 = height ;
		h1 = h2 = th - height ;
	}
	x3 = 0, y3 = height ;
	w3 = tw - 2, h3 = th - height ;

	m_hwndFile = CreateWindow( CTRL_BIGLIST,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP|WS_VSCROLL,
						x1, y1, w1, h1,
						hWnd,
						(HMENU) IDC_FILE,
						hInst,
						0 ) ;

	m_hwndContent = CreateWindow( CTRL_BIGLIST,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP|WS_VSCROLL,
						x2, y2, w2, h2,
						hWnd,
						(HMENU) IDC_CONTENT,
						hInst,
						0 ) ;

	m_hwndView = CreateWindow( CTRL_FILEVIEW,
						TEXT(""),
						WS_CHILD|WS_BORDER|WS_TABSTOP|WS_VSCROLL,
						x3, y3, w3, h3,
						hWnd,
						(HMENU) IDC_VIEW,
						hInst,
						0 ) ;

	/* View画面の情報を設定する */
	SendMessage( m_hwndView, FVM_SETTAB, (WPARAM) g_dwTabSize, (LPARAM) FALSE ) ;
	SendMessage( m_hwndView, FVM_SETHMARGIN, (WPARAM) g_dwHMargin, (LPARAM) TRUE ) ;
	if ( m_bNarrow ) {
		SendMessage( m_hwndView, FVM_SETKEYMAP, 0, (LPARAM) g_NarrowKeyMapInfo ) ;
	}

	/* 初期ディレクトリ内容を表示する */
	GetFilenames( g_szBaseDir ) ;

	/* 一覧領域に表示できる文字数を求める */
	GetClientRect( m_hwndFile, &rect ) ;
	m_dwMaxFileCol = (rect.right - 4) / GetFontHW() ;
	/* ダブルクリックでEnterするように設定する */
	SendMessage( m_hwndFile, BLM_SETDBLCLK, (WPARAM) TRUE, 0 ) ;
	/* 一覧用のプロシージャを設定する */
	SendMessage( m_hwndFile, BLM_SETPROC, 0, (LPARAM) file_proc ) ;

	/* 内容領域に表示できる文字数を求める */
	GetClientRect( m_hwndContent, &rect ) ;
	m_dwMaxContentCol = (rect.right - 4) / GetFontHW() ;
	m_dwMaxContentLine = SendMessage( m_hwndContent, BLM_GETMAXLINE, 0, 0 ) ;
	/* 内容表示用のプロシージャを設定する */
	SendMessage( m_hwndContent, BLM_SETPROC, 0, (LPARAM) NULL ) ;

	/* 初期フォーカスを設定する */
	SetFocus( m_hwndFile ) ;

	if ( g_szArgs && *g_szArgs ) {
		_tcscpy( g_szFilePath, g_szArgs ) ;
		OpenFileView( 0 ) ;
	}
}

void
MainWindow::WMDestroy()
{
	PostQuitMessage( 0 ) ;
}

LRESULT
MainWindow::WMCommand( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	DWORD		index, attr ;
	WORD		idCtrl = LOWORD(wParam) ;
	WORD		notifyCode = HIWORD(wParam) ;

	switch ( idCtrl ) {
	case IDC_FILE:
		switch ( notifyCode ) {
		case BLN_ENTER:
			switch ( m_dwMode ) {
			case MODE_FILE:
				/* ファイル内容を表示する */
				if ( find_bookmark( g_szFilePath, &index ) ) {
					if ( MessageBox( m_hwnd,
									 TEXT("This file has already BookMarked.\r\nUse marked position?"),
									 TEXT("Already marked"),
									 MB_YESNO|MB_ICONQUESTION ) != IDYES ) {
						index = 0 ;
					}
				} else {
					index = 0 ;
				}
				OpenFileView( index ) ;
				break ;
			case MODE_BOOKMARK:
				index = SendMessage( m_hwndFile, BLM_GETCURSEL, 0, 0 ) ;
				if ( !index ) {
					/* フォルダーモードに移る */
					_tcscpy( m_szCurDir, g_szBaseDir ) ;
					SendMessage( m_hwnd, WM_COMMAND, IDM_FOLDER, 0 ) ;
					break ;
				}
				attr = GetFileAttributes( g_szFilePath ) ;
				if ( attr == 0xFFFFFFFF ) {
					/* フォルダーモードに移る */
					_tcscpy( m_szCurDir, TEXT("\\") ) ;
					SendMessage( m_hwnd, WM_COMMAND, IDM_FOLDER, 0 ) ;
				} else if ( attr & FILE_ATTRIBUTE_DIRECTORY ) {
					/* ファイルモードに移る */
					_tcscpy( g_szBaseDir, g_szFilePath ) ;
					SendMessage( m_hwnd, WM_COMMAND, IDM_FILE, 0 ) ;
				} else {
					/* ファイル内容を表示する */
					OpenFileView( g_dwMarkPos[ index - 1 ] ) ;
				}
				break ;
			case MODE_FOLDER:
				/* フォルダーモードに移る */
				_tcscpy( m_szCurDir, g_szFilePath ) ;
				SendMessage( m_hwnd, WM_COMMAND, IDM_FOLDER, 0 ) ;
				break ;
			}
			break ;
		case BLN_ESC:
			switch ( m_dwMode ) {
			case MODE_FILE:
				/* しおりモードに移る */
				SendMessage( m_hwnd, WM_COMMAND, IDM_BOOKMARK, 0 ) ;
				break ;
			case MODE_FOLDER:
				_tcscpy( g_szBaseDir, m_szCurDir ) ;
			case MODE_BOOKMARK:
				/* ファイルモードに移る */
				SendMessage( m_hwnd, WM_COMMAND, IDM_FILE, 0 ) ;
				break ;
			}
			break ;
		case BLN_CHANGE:
			index = SendMessage( m_hwndFile, BLM_GETCURSEL, 0, 0 ) ;
			switch ( m_dwMode ) {
			case MODE_FILE:
				_tcscpy( g_szFilePath, g_szBaseDir ) ;
				catdir( g_szFilePath, g_szFilename[ index ], NULL ) ;
				break ;
			case MODE_BOOKMARK:
				_tcscpy( g_szFilePath, g_szFilename[ index ] ) ;
				break ;
			case MODE_FOLDER:
				_tcscpy( g_szFilePath, m_szCurDir ) ;
				catdir( g_szFilePath, g_szFilename[ index ], NULL ) ;
				break ;
			}
			PostMessage( hWnd, WM_USER_VIEW, 0, 0 ) ;
			break ;
		}
		break ;
	case IDC_VIEW:
		switch ( notifyCode ) {
		case BLN_ENTER:
			/* エディターを起動する */
			SendMessage( m_hwnd, WM_COMMAND, IDM_EDIT, 0 ) ;
			break ;
		case BLN_ESC:
			/* ファイル内容表示から戻る */
			CloseFileView() ;
			break ;
		}
		break ;
	case IDM_EDIT:
		/* エディターを起動する */
		if ( m_dwMode == MODE_FOLDER ) {
			MessageBeep( 0xFFFFFFFF ) ;
			break ;
		}
		if ( !IsWindowVisible( m_hwndView ) ) {
			index = SendMessage( m_hwndFile, BLM_GETCURSEL, 0, 0 ) ;
			_tcscpy( g_szFilePath, g_szBaseDir ) ;
			catdir( g_szFilePath, g_szFilename[ index ], NULL ) ;
		}
		ExecProgram( g_szFilePath ) ;
		break ;
	case IDM_ADD_FOLDER:
		/* しおりにフォルダーを追加する */
		switch ( m_dwMode ) {
		case MODE_FILE:
			add_bookmark( g_szBaseDir, 0 ) ;
			break ;
		case MODE_FOLDER:
			add_bookmark( m_szCurDir, 0 ) ;
			break ;
		}
		break ;
	case IDM_ADD_FILE:
		/* しおりにファイルを追加する */
		if ( !IsWindowVisible( m_hwndView ) ) {
			MessageBeep( 0xFFFFFFFF ) ;
			break ;
		}
		index = SendMessage( m_hwndView, FVM_GETTOPPOS, 0, 0 ) ;
		add_bookmark( g_szFilePath, index ) ;
		break ;
	case IDM_DELETE_MARK:
		/* しおりを削除する */
		if ( m_dwMode == MODE_FOLDER ) {
			MessageBeep( 0xFFFFFFFF ) ;
			break ;
		}
		if ( !delete_bookmark( g_szFilePath ) ) {
			MessageBeep( 0xFFFFFFFF ) ;
			break ;
		}
		if ( !IsWindowVisible( m_hwndView ) && m_dwMode == MODE_BOOKMARK ) {
			/* しおりモードの場合はリストを作成する */
			GetBookMarks() ;
			SendMessage( m_hwndFile, BLM_SETPROC, 0, (LPARAM) file_proc ) ;
		}
		break ;
	case IDM_FILE:
		/* ファイル表示モードに移る */
		if ( IsWindowVisible( m_hwndView ) ) {
			CloseFileView() ;
		}
		GetFilenames( g_szBaseDir ) ;
		SendMessage( m_hwndFile, BLM_SETPROC, 0, (LPARAM) file_proc ) ;
		m_dwMode = MODE_FILE ;
		break ;
	case IDM_FOLDER:
		/* フォルダ表示モードに移る */
		if ( IsWindowVisible( m_hwndView ) ) {
			CloseFileView() ;
		}
		GetFolders( m_szCurDir ) ;
		SendMessage( m_hwndFile, BLM_SETPROC, 0, (LPARAM) file_proc ) ;
		m_dwMode = MODE_FOLDER ;
		break ;
	case IDM_BOOKMARK:
		/* しおり表示モードに移る */
		if ( IsWindowVisible( m_hwndView ) ) {
			CloseFileView() ;
		}
		GetBookMarks() ;
		SendMessage( m_hwndFile, BLM_SETPROC, 0, (LPARAM) file_proc ) ;
		m_dwMode = MODE_BOOKMARK ;
		break ;
	case IDM_COPY:
		/* 表示内容をクリップボードにコピーする */
		if ( !IsWindowVisible( m_hwndView ) ) {
			MessageBeep( 0xFFFFFFFF ) ;
			break ;
		}
		SendMessage( m_hwndView, WM_COPY, 0, 0 ) ;
		break ;
	case IDM_SETUP:
		if ( !SetupDialogExec( m_pApp->get_inst(), hWnd, &index ) ) {
			break ;
		}
		if ( index & SETUP_RET_CHANGE ) {
			SendMessage( m_hwndView, FVM_SETTAB, (WPARAM) g_dwTabSize, (LPARAM) FALSE ) ;
			SendMessage( m_hwndView, FVM_SETHMARGIN, (WPARAM) g_dwHMargin, (LPARAM) TRUE ) ;
		}
		break ;
	case IDM_ABOUT:
		DialogBox( m_pApp->get_inst(), MAKEINTRESOURCE(IDD_DLG_ABOUT), hWnd, AboutDlgFunc ) ;
		if ( !g_bDeleteReg ) {
			break ;
		}
		//
	case IDM_EXIT:
		if ( IsWindowVisible( m_hwndView ) ) {
			CloseFileView() ;
		}
		SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
		break ;
	}
	return 0 ;
}

BOOL
MainWindow::WMClose()
{
	if ( IsWindowVisible( m_hwndView ) ) {
		CloseFileView() ;
		return TRUE ;
	}
	if ( g_bDeleteReg ) {
		m_pApp->DeleteReg() ;
	} else {
		m_pApp->SetReg() ;
	}
	return FALSE ;
}

void
MainWindow::WMSetFocus()
{
	if ( IsWindowVisible( m_hwndView ) ) {
		SetFocus( m_hwndView ) ;
	} else {
		SetFocus( m_hwndFile ) ;
	}
}

LRESULT
MainWindow::WMWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL *bDefault )
{
	MSG		msg1 ;
	DWORD	index ;

	*bDefault = FALSE ;
	switch ( msg ) {
	case WM_USER_VIEW:
		if ( PeekMessage( &msg1, hWnd, WM_USER_VIEW, WM_USER_VIEW, PM_NOREMOVE ) ) {
			break ;
		}
		*g_szContent = 0 ;
		if ( m_dwMode == MODE_FOLDER ) {
			index = SendMessage( m_hwndFile, BLM_GETCURSEL, 0, 0 ) ;
			if ( !_tcscmp( g_szFilename[ index ], TEXT("..") ) ) {
				GetFolderContent( m_szCurDir, m_dwMaxContentLine ) ;
			} else {
				GetFolderContent( g_szFilePath, m_dwMaxContentLine ) ;
			}
		} else {
			GetFileContent( g_szFilePath ) ;
		}
		if ( PeekMessage( &msg1, hWnd, WM_USER_VIEW, WM_USER_VIEW, PM_NOREMOVE ) ) {
			break ;
		}
		/* 内容表示用のプロシージャを設定する */
		SendMessage( m_hwndContent, BLM_SETPROC, 0, (LPARAM) content_proc ) ;
		break ;
	case WM_INITMENUPOPUP:
		WMInitMenuPopup( (HMENU) wParam, (UINT) LOWORD(lParam), (BOOL) HIWORD(lParam) ) ;
		break ;
	default:
		*bDefault = TRUE ;
		break ;
	}
	return 0 ;
}

void
MainWindow::WMInitMenuPopup( HMENU hmenuPopup, UINT uPos, BOOL fSystemMenu )
{
	UINT	uEnable ;

	switch ( uPos ) {
	case 0:
		uEnable = MF_BYCOMMAND ;
		uEnable |= m_dwMode == MODE_FOLDER ? MF_GRAYED : 0 ;
		EnableMenuItem( hmenuPopup, IDM_EDIT, uEnable ) ;
		break ;
	case 1:
		uEnable = MF_BYCOMMAND ;
		uEnable |= IsWindowVisible( m_hwndView ) ? 0 : MF_GRAYED ;
		EnableMenuItem( hmenuPopup, IDM_COPY, uEnable ) ;
		break ;
	}
}

BOOL
MainWindow::OpenFileView( DWORD pos )
{
	SetCursor( LoadCursor( NULL, IDC_WAIT ) ) ;
	if ( !SendMessage( m_hwndView, FVM_LOAD, 0, (LPARAM) g_szFilePath ) ) {
		SetCursor( NULL ) ;
		MessageBeep( MB_ICONASTERISK ) ;
		return FALSE ;
	}
	SetCursor( NULL ) ;
	if ( pos ) {
		SendMessage( m_hwndView, FVM_SETTOPPOS, (WPARAM) pos, 0 ) ;
	}
	ShowWindow( m_hwndView, SW_SHOW ) ;
	ShowWindow( m_hwndFile, SW_HIDE ) ;
	ShowWindow( m_hwndContent, SW_HIDE ) ;
	SetFocus( m_hwndView ) ;
	return TRUE ;
}

void
MainWindow::CloseFileView()
{
	DWORD	oldpos, newpos ;

	if ( find_bookmark( g_szFilePath, &oldpos ) ) {
		newpos = SendMessage( m_hwndView, FVM_GETTOPPOS, 0, 0 ) ;
		if ( oldpos != newpos && MessageBox( m_hwnd, TEXT("Update the old BookMark?"), TEXT("Bookmark"), MB_YESNO|MB_ICONQUESTION ) == IDYES ) {
			add_bookmark( g_szFilePath, newpos ) ;
		}
	}
	if ( m_dwMode == MODE_BOOKMARK ) {
		oldpos = SendMessage( m_hwndFile, BLM_GETCURSEL, 0, 0 ) ;
		GetBookMarks() ;
		SendMessage( m_hwndFile, BLM_SETPROC, 0, (LPARAM) file_proc ) ;
		SendMessage( m_hwndFile, BLM_SETCURSEL, (WPARAM) oldpos, 0 ) ;
	}
	SendMessage( m_hwndView, FVM_CLOSE, 0, 0 ) ;
	ShowWindow( m_hwndFile, SW_SHOW ) ;
	ShowWindow( m_hwndContent, SW_SHOW ) ;
	ShowWindow( m_hwndView, SW_HIDE ) ;
	SetFocus( m_hwndFile ) ;
}

int
MainWindow::file_proc( int index, const BYTE **ptr, int *len )
{
	LPTSTR			dst ;
	BOOL			bMarked ;
	DWORD			len1, count ;
	TCHAR			unicode[ MAX_PATH ], buf[ MAX_PATH ] ;
	static	BYTE	sjis[ MAX_PATH ] ;

	if ( index < 0 ) {
		return (int) g_dwNumFilename ;
	} else if ( index >= (int) g_dwNumFilename ) {
		return -1 ;
	}
	_tcscpy( unicode, g_szFilename[ index ] ) ;
	bMarked = g_bMarked[ index ] ;
	wsprintf( buf, TEXT("%s%d"), bMarked ? "*" : "", g_dwFilesize[ index ] ) ;
	len1 = CalcStrCols( unicode ) + CalcStrCols( buf ) ;
	if ( m_dwMaxFileCol > len1 ) {
		dst = unicode ;
		dst += _tcslen( unicode ) ;
		count = m_dwMaxFileCol - len1 ;
		do {
			*dst++ = TEXT(' ') ;
		} while ( -- count ) ;
		_tcscpy( dst, buf ) ;
		dst += _tcslen( dst ) ;
		*dst = 0 ;
	}
	/* Unicode→SJIS変換を行う */
	unicode2sjis( unicode, sjis, sizeof sjis ) ;

	*ptr = sjis ;
	*len = strlen( (LPSTR) *ptr ) ;
	return 0 ;
}

int
MainWindow::content_proc( int index, const BYTE **ptr, int *len )
{
	BOOL	bEof ;
	LPSTR	line ;
	static	BYTE	sjis[ 256 ] = "" ;

	if ( index < 0 ) {
		return (int) m_dwMaxContentLine ;
	} else if ( index >= (int) m_dwMaxContentLine ) {
		return -1 ;
	}
	line = (LPSTR) g_szContent ;
	while ( 1 ) {
		bEof = !copy_line( line, (LPSTR) sjis, m_dwMaxContentCol, (LPCSTR*) &line ) ;
		if ( !index -- ) {
			break ;
		} else if ( bEof ) {
			*sjis = 0 ;
			break ;
		}
	}
	*ptr = sjis ;
	*len = strlen( (LPSTR) *ptr ) ;
	return 0 ;
}

BOOL
MainWindow::Create()
{
	HWND	hWnd = CreateWindowEx( 0,
						GetClassName(),
						szTitleName,
						WS_VISIBLE,
#ifdef	_WIN32_WCE
						0, 0, CW_USEDEFAULT, CW_USEDEFAULT,
#else	/* _WIN32_WCE */
						0, 0, 480, 240,
#endif	/* _WIN32_WCE */
						NULL,
						NULL,
						m_pApp->get_inst(),
						this ) ;
	if ( hWnd == 0 ) {
		return FALSE ;
	}
    ShowWindow( hWnd, SW_SHOW ) ;
    UpdateWindow( hWnd ) ;
    return TRUE ;
}

DWORD
MainWindow::CreateCommandBar()
{
	HINSTANCE	hInst = m_pApp->get_inst() ;

#ifdef	_WIN32_WCE
	TBBUTTON	g_tbWideButton[] = {
		{ 0,            0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{ 4,     IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 0,            0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{ 5,     IDM_FILE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 6,   IDM_FOLDER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 3, IDM_BOOKMARK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 0,            0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{ 1, IDM_ADD_FILE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 2,     IDM_EDIT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
	} ;
	TBBUTTON	g_tbNarrowButton[] = {
		{ 0,            0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{ 4,     IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 0,            0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{ 3, IDM_BOOKMARK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 0,            0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{ 1, IDM_ADD_FILE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{ 2,     IDM_EDIT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
	} ;

	m_hwndCB = CommandBar_Create( hInst, m_hwnd, 0 ) ;
	CommandBar_InsertMenubar( m_hwndCB, hInst, IDR_MAIN_MENU, 0 ) ;
	CommandBar_AddBitmap( m_hwndCB, hInst, IDR_TOOLBAR1, 8, 0, 0 ) ;
	if ( m_bNarrow ) {
		CommandBar_AddButtons( m_hwndCB, sizeof(g_tbNarrowButton) / sizeof(*g_tbNarrowButton), g_tbNarrowButton ) ;
	} else {
		CommandBar_AddButtons( m_hwndCB, sizeof(g_tbWideButton) / sizeof(*g_tbWideButton), g_tbWideButton ) ;
	}
	CommandBar_AddAdornments( m_hwndCB, 0, 0 ) ;
	return CommandBar_Height( m_hwndCB ) ;
#else	/* _WIN32_WCE */
	return 0 ;
#endif	/* _WIN32_WCE */
}

BOOL
MainWindow::RegisterClass( HINSTANCE hInst )
{
	WNDCLASS	wc ;

	wc.style         = NULL ;
	wc.lpfnWndProc   = (WNDPROC) WndProc ;
	wc.cbClsExtra    = 0 ;
	wc.cbWndExtra    = 4 ;
	wc.hInstance     = hInst ;
	wc.hIcon         = NULL ;
	wc.hCursor       = NULL ;
	wc.hbrBackground = (HBRUSH) GetStockObject( WHITE_BRUSH ) ;
#ifdef	_WIN32_WCE
	wc.lpszMenuName  = 0 ;
#else	/* _WIN32_WCE */
	wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAIN_MENU) ;
#endif	/* _WIN32_WCE */
	wc.lpszClassName = 	GetClassName() ;
	return ::RegisterClass( &wc ) ;
}

BOOL CALLBACK
AboutDlgFunc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
	TCHAR	buf[ 128 ], *ptr ;

	switch ( message ) {
	case WM_INITDIALOG:
		/* ダイアログタイトル */
		_tcscpy( buf, TEXT("About ") ) ;
		_tcscat( buf, szTitleName ) ;
		SetWindowText( hDlg, buf ) ;
		/* アプリケーションバージョン */
		_tcscpy( buf, szTitleName ) ;
		_tcscat( buf, TEXT(" for WinCE V") ) ;
		ptr = &buf[ _tcslen( buf ) ] ;
		*ptr++ = TEXT('0') + (TCHAR) (g_dwAppVersion / 100) ;
		*ptr++ = TEXT('.') ;
		*ptr++ = TEXT('0') + (TCHAR) ((g_dwAppVersion / 10) % 10) ;
		*ptr++ = TEXT('0') + (TCHAR) (g_dwAppVersion % 10) ;
		*ptr = 0 ;
		SetDlgItemText( hDlg, IDC_VERSION, buf ) ;
		/* DLLバージョン */
		_tcscpy( buf, TEXT("KCTRL Ver ") ) ;
		ptr = &buf[ _tcslen( buf ) ] ;
		*ptr++ = TEXT('0') + (TCHAR) (g_dwDllVersion / 100) ;
		*ptr++ = TEXT('.') ;
		*ptr++ = TEXT('0') + (TCHAR) ((g_dwDllVersion / 10) % 10) ;
		*ptr++ = TEXT('0') + (TCHAR) (g_dwDllVersion % 10) ;
		*ptr = 0 ;
		SetDlgItemText( hDlg, IDC_DLLVERSION, buf ) ;
		/* Copyright */
		_tcscpy( buf, TEXT("Copyright (C) 1997-1998\r\n") ) ;
		_tcscat( buf, TEXT("by Eiichiro ITO\r\n") ) ;
		_tcscat( buf, TEXT("All Rights Reserved") ) ;
		SetDlgItemText( hDlg, IDC_COPYRIGHT, buf ) ;
		return TRUE ;
	case WM_COMMAND:
		switch ( GET_WM_COMMAND_ID( wParam, lParam ) ) {
		case IDOK:
		case IDCANCEL:
			EndDialog( hDlg, TRUE ) ;
			return TRUE ;
		case IDC_UNINSTALL:
			if ( MessageBox( hDlg, TEXT("Uninstall Application?"), TEXT("Uninstal"), MB_YESNO|MB_ICONQUESTION ) == IDYES ) {
				g_bDeleteReg = TRUE ;
				EndDialog( hDlg, FALSE ) ;
			}
			break ;
		}
		break ;
	}
	return FALSE ;
}
