#define	STRICT
#include	<windows.h>
#include	<windowsx.h>
#include	<commctrl.h>
#include	<tchar.h>
#include	<math.h>
#include	"kctrl.h"
#include	"basewin.h"
#include	"controls.h"
#include	"resource.h"
#include	"fepbox.h"
#include	"appmain.h"
#include	"search.h"

TCHAR		MessageBuf[ 512 ] ;

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

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 ) ;
	}
}

/*
 * メインウィンドウ
 */
class MainWindow : public Window {
private:
	MainApp			*m_pApp ;		/* アプリケーションへのポインタ */
	HWND			m_hwndCB ;		/* CommandBarのハンドル */
	HICON			m_hIcon ;		/* アプリアイコンのハンドル */
	BOOL			m_bDeleteReg ;	/* レジストリを削除する場合*真* */
	HWND			m_hwndEdit1 ;	/* 電話番号1領域のハンドル */
	HWND			m_hwndEdit2 ;	/* 電話番号2領域のハンドル */
	HWND			m_hwndList ;	/* 一覧領域のハンドル */
	HWND			m_hwndTime ;	/* 秒数領域のハンドル */
	DWORD			m_dwTopPos ;	/* Y座標 */

	DWORD			m_dwIdxFrom ;
	DWORD			m_dwIdxTo ;
	DWORD			m_dwInputMode ;

	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() ;

	void	GoNextFocus( DWORD current, BOOL fShift ) const ;
	BOOL	CopyToClipboard() const ;

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

	static	int		list_proc( int index, const BYTE **ptr, int *len ) ;
	static	int		result_proc( int index, const BYTE **ptr, int *len ) ;
} ;

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

MainApp::~MainApp()
{
}

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 ( !LabelRegisterClass( m_hInst ) ) {
		return FALSE ;
	}
	if ( !InitFep() ) {
		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 ;
}

/*
 * レジストリからの情報取得
 */
BOOL
MainApp::GetReg()
{
	return TRUE ;
}

/*
 * レジストリへの情報設定
 */
BOOL
MainApp::SetReg() const
{
	return TRUE ;
}

/*
 * レジストリ情報削除
 */
void
MainApp::DeleteReg() const
{
}

/*-------------------------------------------------------------------------*
 * MainWindow
 *-------------------------------------------------------------------------*/
enum {
	MODE_EDIT1 = 0, MODE_EDIT2, MODE_RESULT,
	NUM_MODE
} ;

enum {
	CONTROL_EDIT1, CONTROL_EDIT2, CONTROL_LIST, CONTROL_TIME,
	NUM_CONTROL
} ;

DWORD		g_dwFocusList[ NUM_MODE ][ NUM_CONTROL ] = {
	{ CONTROL_EDIT1, CONTROL_LIST, CONTROL_EDIT2, CONTROL_TIME },
	{ CONTROL_EDIT1, CONTROL_EDIT2, CONTROL_LIST, CONTROL_TIME },
	{ CONTROL_EDIT1, CONTROL_EDIT2, CONTROL_TIME, CONTROL_LIST },
} ;

MainWindow::MainWindow( MainApp *pApp )
{
	m_pApp = pApp ;
	m_hIcon = 0 ;
	m_bDeleteReg = FALSE ;

	m_dwIdxFrom = -1 ;
	m_dwIdxTo   = -1 ;
	m_dwInputMode = MODE_EDIT1 ;
}

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

void
MainWindow::WMCreate( HWND hWnd )
{
	RECT		rect ;
	TCHAR		unicode[ 20 ] ;
	DWORD		height = 2, tw, th, lw ;
	HINSTANCE	hInst = m_pApp->get_inst() ;
	DWORD		x1, x2, x3, x4, y1, y2, y3, y4 ;
	DWORD		w1, w2, w3, w4, h1, h2, h3, h4 ;

	m_hwnd = hWnd ;
	/* 表示領域を求める */
	GetClientRect( m_hwnd, &rect ) ;
	tw = rect.right ;
	th = rect.bottom ;
	/* アイコンを作成しタスクバーに登録する */
	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 ( rect.right > 400 ) {
		w3 = GetFontHW() * 5 + 4 + 2 * GetFontZW() + 4 ;
		w1 = w2 = (tw - w3 - 4) / 2 - 2 ;
		x1 = 0, x2 = x1 + w1 + 2, x3 = x2 + w2 + 2 ;
		y1 = y2 = y3 = height ;
		h1 = h2 = h3 = GetFontH() + 4 ;
		height += GetFontH() + 6 ;
		x4 = 0,      y4 = height, w4 = tw, h4 = th - height ;

		lw = 3 * GetFontZW() + 2 ;
		sjis2unicode( (LPBYTE) "発信地", unicode, sizeof unicode ) ;
		CreateWindow( CTRL_LABEL, unicode, WS_CHILD|WS_VISIBLE,
					x1, y1, lw, h1,
					hWnd, 0, hInst, 0 ) ;
		x1 += lw + 2 ;
		w1 -= lw + 2 ;

		lw = 3 * GetFontZW() + 2 ;
		sjis2unicode( (LPBYTE) "着信地", unicode, sizeof unicode ) ;
		CreateWindow( CTRL_LABEL, unicode, WS_CHILD|WS_VISIBLE,
					x2, y2, lw, h2,
					hWnd, 0, hInst, 0 ) ;
		x2 += lw + 2 ;
		w2 -= lw + 2 ;

		lw = 2 * GetFontZW() + 2 ;
		sjis2unicode( (LPBYTE) "秒数", unicode, sizeof unicode ) ;
		CreateWindow( CTRL_LABEL, unicode, WS_CHILD|WS_VISIBLE,
					x3, y3, lw, h3,
					hWnd, 0, hInst, 0 ) ;
		x3 += lw + 2 ;
		w3 -= lw + 2 ;

		set_view_mode( FALSE ) ;
	} else {
		w3 = GetFontHW() * 5 + 4 ;
		w1 = w2 = (tw - w3 - 4) / 2 - 2 ;
		x1 = 0, x2 = x1 + w1 + 2, x3 = x2 + w2 + 2 ;
		y1 = y2 = y3 = height ;
		h1 = h2 = h3 = GetFontH() + 4 ;
		height += GetFontH() + 6 ;
		x4 = 0,      y4 = height, w4 = tw, h4 = th - height ;

		set_view_mode( TRUE ) ;
	}

	m_hwndEdit1 = CreateWindowEx( 0,
						CTRL_LINEEDIT,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP,
						x1, y1, w1, h1,
						hWnd,
						(HMENU) IDC_EDIT1,
						hInst,
						0 ) ;

	m_hwndEdit2 = CreateWindowEx( 0,
						CTRL_LINEEDIT,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP,
						x2, y2, w2, h2,
						hWnd,
						(HMENU) IDC_EDIT2,
						hInst,
						0 ) ;

	m_hwndTime = CreateWindowEx( 0,
						CTRL_LINEEDIT,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP,
						x3, y3, w3, h3,
						hWnd,
						(HMENU) IDC_TIME,
						hInst,
						0 ) ;

	m_hwndList = CreateWindowEx( 0,
						CTRL_BIGLIST,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP|WS_VSCROLL,
						x4, y4, w4, h4,
						hWnd,
						(HMENU) IDC_LIST,
						hInst,
						0 ) ;

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

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

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

	switch ( idCtrl ) {
	case IDC_LIST:
		if ( notifyCode == BLN_ENTER ) {
			if ( m_dwInputMode == MODE_RESULT ) {
			} else if ( g_dwNumList ) {
				index = SendMessage( m_hwndList, BLM_GETCURSEL, 0, 0 ) ;
				index = g_dwList[ index ] ;
				sjis2unicode( (LPBYTE) getname( index ), MessageBuf, sizeof MessageBuf ) ;
				switch ( m_dwInputMode ) {
				case MODE_EDIT1:
					m_dwIdxFrom = index ;
					SetWindowText( m_hwndEdit1, MessageBuf ) ;
					SetFocus( m_hwndEdit2 ) ;
					break ;
				case MODE_EDIT2:
					m_dwIdxTo   = index ;
					SetWindowText( m_hwndEdit2, MessageBuf ) ;
					PostMessage( hWnd, WM_COMMAND, IDM_CALC, 0 ) ;
					break ;
				}
			}
		} else if ( notifyCode == BLN_ESC ) {
			switch ( m_dwInputMode ) {
			case MODE_EDIT1:
			case MODE_RESULT:
				SetFocus( m_hwndEdit1 ) ;
				break ;
			case MODE_EDIT2:
				SetFocus( m_hwndEdit2 ) ;
				break ;
			}
		} else if ( notifyCode == BLN_TAB ) {
			GoNextFocus( CONTROL_LIST, FALSE ) ;
		} else if ( notifyCode == BLN_STAB ) {
			GoNextFocus( CONTROL_LIST, TRUE ) ;
		}
		break ;
	case IDC_EDIT1:
		if ( notifyCode == LEN_GOTFOCUS ) {
			/* SIPをオンにする */
			ShowSIP( TRUE ) ;
		} else if ( notifyCode == LEN_CHANGE ) {
			m_dwInputMode = MODE_EDIT1 ;
			GetWindowText( m_hwndEdit1, MessageBuf, sizeof MessageBuf / sizeof *MessageBuf ) ;
			if ( _tcscmp( MessageBuf, TEXT("0") ) ) {
				/* 一覧用のプロシージャを設定する */
				index = getma( MessageBuf ) ;
				SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) list_proc ) ;
				SendMessage( m_hwndList, BLM_SETCURSEL, index, 0 ) ;
				m_dwIdxFrom = g_dwNumList ? g_dwList[ index ] : -1 ;
			}
		} else if ( notifyCode == LEN_ENTER ) {
			if ( m_dwIdxFrom != -1 ) {
				SetFocus( m_hwndEdit2 ) ;
			}
		} else if ( notifyCode == LEN_KEYDOWN ) {
			SetFocus( m_hwndList ) ;
		} else if ( notifyCode == BLN_TAB ) {
			GoNextFocus( CONTROL_EDIT1, FALSE ) ;
		} else if ( notifyCode == BLN_STAB ) {
			GoNextFocus( CONTROL_EDIT1, TRUE ) ;
		}
		break ;
	case IDC_EDIT2:
		if ( notifyCode == LEN_GOTFOCUS ) {
			/* SIPをオンにする */
			ShowSIP( TRUE ) ;
		} else if ( notifyCode == LEN_CHANGE ) {
			m_dwInputMode = MODE_EDIT2 ;
			GetWindowText( m_hwndEdit2, MessageBuf, sizeof MessageBuf / sizeof *MessageBuf ) ;
			if ( *MessageBuf == TEXT('+') ) {
				/* 隣接地域を調べる */
				if ( areaplus( m_dwIdxFrom ) ) {
					SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) result_proc ) ;
					m_dwInputMode = MODE_RESULT ;
					SetFocus( m_hwndList ) ;
					m_dwIdxTo = -1 ;
				} else {
					break ;
				}
			} else if ( _tcscmp( MessageBuf, TEXT("0") ) ) {
				/* 一覧用のプロシージャを設定する */
				index = getma( MessageBuf ) ;
				SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) list_proc ) ;
				SendMessage( m_hwndList, BLM_SETCURSEL, index, 0 ) ;
				m_dwIdxTo = g_dwNumList ? g_dwList[ index ] : -1 ;
			}
		} else if ( notifyCode == LEN_ENTER ) {
			PostMessage( hWnd, WM_COMMAND, IDM_CALC, 0 ) ;
		} else if ( notifyCode == LEN_KEYDOWN ) {
			SetFocus( m_hwndList ) ;
		} else if ( notifyCode == BLN_TAB ) {
			GoNextFocus( CONTROL_EDIT2, FALSE ) ;
		} else if ( notifyCode == BLN_STAB ) {
			GoNextFocus( CONTROL_EDIT2, TRUE ) ;
		}
		break ;
	case IDC_TIME:
		if ( notifyCode == LEN_GOTFOCUS ) {
			/* SIPをオンにする */
			ShowSIP( TRUE ) ;
		} else if ( notifyCode == LEN_ENTER ) {
			PostMessage( hWnd, WM_COMMAND, IDM_CALC, 0 ) ;
		} else if ( notifyCode == BLN_TAB ) {
			GoNextFocus( CONTROL_TIME, FALSE ) ;
		} else if ( notifyCode == BLN_STAB ) {
			GoNextFocus( CONTROL_TIME, TRUE ) ;
		}
		break ;
	case IDM_CALC:
		if ( m_dwIdxFrom == -1 ) {
			/* 発信地が確定していない場合 */
			SetFocus( m_hwndEdit1 ) ;
			break ;
		}
		GetWindowText( m_hwndEdit2, MessageBuf, sizeof MessageBuf / sizeof *MessageBuf ) ;
		if ( *MessageBuf == TEXT('+') ) {
			/* 隣接地域を調べる */
			if ( areaplus( m_dwIdxFrom ) ) {
				SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) result_proc ) ;
				m_dwInputMode = MODE_RESULT ;
				SetFocus( m_hwndList ) ;
				m_dwIdxTo = -1 ;
			} else {
				break ;
			}
		}
		if ( m_dwIdxTo == -1 ) {
			/* 着信地が確定していない場合 */
			SetFocus( m_hwndEdit2 ) ;
			break ;
		}
		/* 秒数を取得する */
		time = 0 ;
		GetWindowText( m_hwndTime, MessageBuf, sizeof MessageBuf / sizeof *MessageBuf ) ;
		if ( *MessageBuf ) {
			time = _ttol( MessageBuf ) ;
			if ( time < 0 || time > 60 * 60 * 24 ) {
				time = 0 ;
			}
		}
		/* 検索を行う */
		calc_main( time, m_dwIdxFrom, m_dwIdxTo ) ;
		/* SIPをオフにする */
		ShowSIP( FALSE ) ;
		/* 結果を表示する */
		SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) result_proc ) ;
		m_dwInputMode = MODE_RESULT ;
		SetFocus( m_hwndList ) ;
		break ;
	case IDM_EXACT:
		switch ( m_dwInputMode ) {
		case MODE_EDIT1:
			GetWindowText( m_hwndEdit1, MessageBuf, sizeof MessageBuf / sizeof *MessageBuf ) ;
			index = getma_ss( MessageBuf ) ;
			m_dwIdxFrom = g_dwNumList ? g_dwList[ index ] : -1 ;
			break ;
		case MODE_EDIT2:
			GetWindowText( m_hwndEdit2, MessageBuf, sizeof MessageBuf / sizeof *MessageBuf ) ;
			index = getma_ss( MessageBuf ) ;
			m_dwIdxTo   = g_dwNumList ? g_dwList[ index ] : -1 ;
			break ;
		default:
			return 0 ;
		}
		SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) list_proc ) ;
		SendMessage( m_hwndList, BLM_SETCURSEL, index, 0 ) ;
		break ;
	case IDM_COPY:
		CopyToClipboard() ;
		break ;
	case IDM_ABOUT:
		DialogBox( m_pApp->get_inst(), MAKEINTRESOURCE(IDD_DLG_ABOUT), hWnd, AboutDlgFunc ) ;
		break ;
	case IDM_EXIT:
		SendMessage( hWnd, WM_CLOSE, 0, 0 ) ;
		break ;
	}
	return 0 ;
}

void
MainWindow::WMSetFocus()
{
	HWND	hwnd = GetFocus() ;

	if ( hwnd == m_hwndEdit1 || hwnd == m_hwndEdit2 || hwnd == m_hwndList || hwnd == m_hwndTime ) {
		return ;
	}
	switch ( m_dwInputMode ) {
	case MODE_EDIT1:	SetFocus( m_hwndEdit1 ) ;	break ;
	case MODE_EDIT2:	SetFocus( m_hwndEdit2 ) ;	break ;
	case MODE_RESULT:	SetFocus( m_hwndList ) ;	break ;
	}
}

BOOL
MainWindow::WMClose()
{
	if ( m_bDeleteReg ) {
		m_pApp->DeleteReg() ;
	} else {
		m_pApp->SetReg() ;
	}
	return FALSE ;
}

void
MainWindow::GoNextFocus( DWORD current, BOOL fShift ) const
{
	DWORD	i, next ;
	LPDWORD	list = g_dwFocusList[ m_dwInputMode ] ;

	if ( !fShift ) {
		next = 0 ;
		for ( i = 0 ; i < NUM_CONTROL ; i ++ ) {
			if ( list[ i ] == current ) {
				next = (i + 1) % NUM_CONTROL ;
				break ;
			}
		}
	} else {
		next = 0 ;
		for ( i = 0 ; i < NUM_CONTROL ; i ++ ) {
			if ( list[ i ] == current ) {
				next = (i + NUM_CONTROL - 1) % NUM_CONTROL ;
				break ;
			}
		}
	}
	next = list[ next ] ;
	switch ( next ) {
	case CONTROL_EDIT1:		SetFocus( m_hwndEdit1 ) ;	break ;
	case CONTROL_EDIT2:		SetFocus( m_hwndEdit2 ) ;	break ;
	case CONTROL_LIST:		SetFocus( m_hwndList ) ;	break ;
	case CONTROL_TIME:		SetFocus( m_hwndTime ) ;	break ;
	}
}

BOOL
MainWindow::CopyToClipboard() const
{
	DWORD	i, len, size = 0 ;
	TCHAR	unicode[ 128 ], *ptr ;

	for ( i = 0 ; i < g_dwNumResult ; i ++ ) {
		sjis2unicode( (LPBYTE) g_szResult[ i ], unicode, sizeof unicode ) ;
		size += (_tcslen( unicode ) + 2) * sizeof (TCHAR) ;
	}
	/* クリップボードオープン */
	if ( !OpenClipboard( m_hwnd ) ) {
		return FALSE ;
	} else if ( !EmptyClipboard() ) {
		CloseClipboard() ;
		return FALSE ;
	}
	/* 必要な分だけメモリ確保を行う */
#ifdef  _WIN32_WCE
	HLOCAL  hGMem = LocalAlloc( LMEM_FIXED, size ) ;
	ptr = (LPTSTR) hGMem ;
#else   /* _WIN32_WCE */
	HGLOBAL hGMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_DDESHARE, size ) ;
	ptr = (LPTSTR) GlobalLock( hGMem ) ;
#endif  /* _WIN32_WCE */
	/* SJIS->UNICODE変換し結果をメモリに書き込む */
	for ( i = 0 ; i < g_dwNumResult ; i ++ ) {
		sjis2unicode( (LPBYTE) g_szResult[ i ], ptr, size ) ;
		len = _tcslen( ptr ) ;
		ptr += len ;
		*ptr++ = TEXT('\r') ;
		*ptr++ = TEXT('\n') ;
		size -= (len + 2) * sizeof (TCHAR) ;
	}
	*ptr = 0 ;
	/* クリップボードに結果をセットする */
	SetClipboardData( CF_UNICODETEXT, hGMem ) ;
#ifndef _WIN32_WCE
	GlobalUnlock( hGMem ) ;
#endif  /* _WIN32_WCE */
	/* クリップボードクローズ */
	CloseClipboard() ;
	return TRUE ;
}

int
MainWindow::list_proc( int index, const BYTE **ptr, int *len )
{
	static	BYTE	sjis[ 256 ] ;

	if ( index < 0 ) {
		return g_dwNumList ? g_dwNumList : 1 ;
	} else if ( (DWORD) index >= (g_dwNumList ? g_dwNumList : 1 ) ) {
		return -1 ;
	}
	if ( !g_dwNumList ) {
		strcpy( (LPSTR) sjis, "該当ありません" ) ;
	} else {
		strcpy( (LPSTR) sjis, getname( g_dwList[ index ] ) ) ;
	}
	*ptr = sjis ;
	*len = strlen( (LPSTR) *ptr ) ;
	return 0 ;
}

int
MainWindow::result_proc( int index, const BYTE **ptr, int *len )
{
	LPBYTE	sjis ;

	if ( index < 0 ) {
		return g_dwNumResult ? g_dwNumResult : 1 ;
	} else if ( (DWORD) index >= (g_dwNumResult ? g_dwNumResult : 1 ) ) {
		return -1 ;
	}
	if ( !g_dwNumResult ) {
		sjis = (LPBYTE) "該当ありません" ;
	} else {
		sjis = (LPBYTE) g_szResult[ index ] ;
	}
	*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_tbButton[] = {
		{       0,         0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{STD_COPY,  IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1},
		{       0,         0, TBSTATE_ENABLED, TBSTYLE_SEP,    0, 0, 0, -1},
		{STD_FIND,  IDM_CALC, 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_COMMCTRL, IDB_STD_SMALL_COLOR, 15, 0, 0 ) ;
	CommandBar_AddButtons( m_hwndCB, sizeof(g_tbButton) / sizeof(*g_tbButton), g_tbButton ) ;
	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 ], buf2[ 10 ] ;

	switch ( message ) {
	case WM_INITDIALOG:
		/* ダイアログタイトル */
		_tcscpy( buf, TEXT("About ") ) ;
		_tcscat( buf, szTitleName ) ;
		SetWindowText( hDlg, buf ) ;
		/* アプリケーションバージョン */
		buf2[0] = '0' + (TCHAR) ((g_dwAppVersion / 100) % 10) ;
		buf2[1] = '.' ;
		buf2[2] = '0' + (TCHAR) ((g_dwAppVersion / 10) % 10) ;
		buf2[3] = '0' + (TCHAR) (g_dwAppVersion % 10) ;
		buf2[4] = 0 ;
		_tcscpy( buf, szTitleName ) ;
		_tcscat( buf, TEXT(" for WinCE V") ) ;
		_tcscat( buf, buf2 ) ;
		SetDlgItemText( hDlg, IDC_VERSION, buf ) ;
		/* DLLバージョン */
		buf2[0] = '0' + (TCHAR) ((g_dwDllVersion / 100) % 10) ;
		buf2[1] = '.' ;
		buf2[2] = '0' + (TCHAR) ((g_dwDllVersion / 10) % 10) ;
		buf2[3] = '0' + (TCHAR) (g_dwDllVersion % 10) ;
		buf2[4] = 0 ;
		_tcscpy( buf, TEXT("KCTRL Ver ") ) ;
		_tcscat( buf, buf2 ) ;
		SetDlgItemText( hDlg, IDC_DLLVERSION, buf ) ;
		/* Copyright */
		_tcscpy( buf, TEXT("Copyright (C) 1997-1998\r\n") ) ;
		_tcscat( buf, TEXT("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 ;
		}
		break ;
	}
	return FALSE ;
}
