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

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

TCHAR		MessageBuf[ 512 ] ;
DWORD		g_dwMaxCol = 40 ;
PEGPROPID	g_PropID = 0 ;
AddressCard	g_AddrCard ;

DWORD		g_PropTag[ 256 ] ;
TCHAR		g_PropName[ 256 ][ 32 ] ;
TCHAR		g_PropValue[ 256 ][ 128 ] ;
DWORD		g_dwPropNum = 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 ;
}

PEGPROPID
GetSortPropID()
{
	PEGOID		pegOID ;
	PEGPROPID	propID ;
	HANDLE		hOpenDB ;
	PEGOIDINFO	pegInfo ;

	pegOID = 0 ;
	hOpenDB = PegOpenDatabase( &pegOID, TEXT("Contacts Database"), 0, 0, NULL ) ;
	if ( hOpenDB == INVALID_HANDLE_VALUE ) {
		return 0 ;
	}
	if ( !PegOidGetInfo( pegOID, &pegInfo ) ) {
		CloseHandle( hOpenDB ) ;
		return 0 ;
	}
	propID = pegInfo.infDatabase.rgSortSpecs[0].propid ;
	CloseHandle( hOpenDB ) ;
	return propID ;
}

void
EnterPropValue( DWORD dwPropTag, LPCTSTR szPropName, LPCTSTR szPropValue )
{
	TCHAR		c ;
	DWORD		count, col, w ;
	BOOL		bFirst = TRUE ;
	LPCTSTR		start = szPropValue ;

	if ( !szPropValue ) {
		return ;
	}
	col = count = 0 ;
	while ( c = *szPropValue++ ) {
		w = is_hankaku( c ) ? 1 : 2 ;
		if ( col + w > g_dwMaxCol - 10 ) {
			g_PropTag[ g_dwPropNum ] = dwPropTag ;
			_tcscpy( g_PropName[ g_dwPropNum ], bFirst ? szPropName : TEXT("") ) ;
			memcpy( g_PropValue[ g_dwPropNum ], start, count * sizeof (TCHAR) ) ;
			g_PropValue[ g_dwPropNum ][ count ] = 0 ;
			g_dwPropNum ++ ;
			bFirst = FALSE ;
			start = szPropValue - 1 ;
			col = count = 0 ;
		}
		col += w ;
		count ++ ;
	}
	g_PropTag[ g_dwPropNum ] = dwPropTag ;
	_tcscpy( g_PropName[ g_dwPropNum ], bFirst ? szPropName : TEXT("") ) ;
	memcpy( g_PropValue[ g_dwPropNum ], start, count * sizeof (TCHAR) ) ;
	g_PropValue[ g_dwPropNum ][ count ] = 0 ;
	g_dwPropNum ++ ;
}

BOOL
GetAllProps( PEGOID oid )
{
	g_dwPropNum = 0 ;
	memset( &g_AddrCard, 0, sizeof g_AddrCard ) ;
	if ( !OpenAddressCard( oid, &g_AddrCard, 0 ) ) {
		wsprintf( MessageBuf, TEXT("OpenAddressCard = %d"), GetLastError() ) ;
		MessageBox( NULL, MessageBuf, TEXT(""), MB_OK ) ;
		FreeAddressCard( &g_AddrCard ) ;
		return FALSE ;
	}

	/* 姓を取り出す */
	EnterPropValue( HHPR_SURNAME, TEXT("姓"), g_AddrCard.pszSurname ) ;
	/* 名を取り出す */
	EnterPropValue( HHPR_GIVEN_NAME, TEXT("名"), g_AddrCard.pszGivenName ) ;
	/* WorkPhoneを取り出す */
	EnterPropValue( HHPR_OFFICE_TELEPHONE_NUMBER, TEXT("会社(TEL)"), g_AddrCard.pszWorkPhone ) ;
	/* BusinessFaxを取り出す */
	EnterPropValue( HHPR_BUSINESS_FAX_NUMBER, TEXT("会社(FAX)"), g_AddrCard.pszBusinessFax ) ;
	/* HomePhoneを取り出す */
	EnterPropValue( HHPR_HOME_TELEPHONE_NUMBER, TEXT("自宅(TEL)"), g_AddrCard.pszHomePhone ) ;
	/* HomeFaxを取り出す */
	EnterPropValue( HHPR_HOME_FAX_NUMBER, TEXT("自宅(FAX)"), g_AddrCard.pszHomeFax ) ;
	/* MobilePhoneを取り出す */
	EnterPropValue( HHPR_MOBILE_TELEPHONE_NUMBER, TEXT("移動(TEL)"), g_AddrCard.pszMobilePhone ) ;
	/* Pagerを取り出す */
	EnterPropValue( HHPR_MOBILE_TELEPHONE_NUMBER, TEXT("ポケベル"), g_AddrCard.pszPager ) ;
	/* E-Mailを取り出す */
	EnterPropValue( HHPR_EMAIL1_EMAIL_ADDRESS, TEXT("Email"), g_AddrCard.pszEmail ) ;
	/* Companyを取り出す */
	EnterPropValue( HHPR_COMPANY_NAME, TEXT("会社名"), g_AddrCard.pszCompany ) ;
	/* Departmentを取り出す */
	EnterPropValue( HHPR_DEPARTMENT_NAME, TEXT("部署"), g_AddrCard.pszDepartment ) ;
	/* Titleを取り出す */
	EnterPropValue( HHPR_TITLE, TEXT("肩書"), g_AddrCard.pszTitle ) ;
	/* OfficeAddrCountryを取り出す */
	EnterPropValue( HHPR_OFFICE_ADDRESS_COUNTRY, TEXT("会社(国)"), g_AddrCard.pszOfficeAddrCountry ) ;
	/* OfficeAddrPostalCodeを取り出す */
	EnterPropValue( HHPR_OFFICE_ADDRESS_POSTAL_CODE, TEXT("会社(〒)"), g_AddrCard.pszOfficeAddrPostalCode ) ;
	/* OfficeAddrStateを取り出す */
	EnterPropValue( HHPR_OFFICE_ADDRESS_STATE, TEXT("会社(県)"), g_AddrCard.pszOfficeAddrState ) ;
	/* OfficeAddrCityを取り出す */
	EnterPropValue( HHPR_OFFICE_ADDRESS_CITY, TEXT("会社(市)"), g_AddrCard.pszOfficeAddrCity ) ;
	/* OfficeAddrStreetを取り出す */
	EnterPropValue( HHPR_OFFICE_ADDRESS_STREET, TEXT("会社(町)"), g_AddrCard.pszOfficeAddrStreet ) ;
	/* HomeAddrCountryを取り出す */
	EnterPropValue( HHPR_HOME_ADDRESS_COUNTRY, TEXT("自宅(国)"), g_AddrCard.pszHomeAddrCountry ) ;
	/* HomeAddrPostalCodeを取り出す */
	EnterPropValue( HHPR_HOME_ADDRESS_POSTAL_CODE, TEXT("自宅(〒)"), g_AddrCard.pszHomeAddrPostalCode ) ;
	/* HomeAddrStateを取り出す */
	EnterPropValue( HHPR_HOME_ADDRESS_STATE, TEXT("自宅(県)"), g_AddrCard.pszHomeAddrState ) ;
	/* HomeAddrCityを取り出す */
	EnterPropValue( HHPR_HOME_ADDRESS_CITY, TEXT("自宅(市)"), g_AddrCard.pszHomeAddrCity ) ;
	/* HomeAddrStreetを取り出す */
	EnterPropValue( HHPR_HOME_ADDRESS_STREET, TEXT("自宅(町)"), g_AddrCard.pszHomeAddrStreet ) ;

	FreeAddressCard( &g_AddrCard ) ;
	return TRUE ;
}

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_hwndList ;	/* 一覧領域のハンドル */
	HWND			m_hwndFind ;	/* 検索領域のハンドル */
	HWND			m_hwndDetail ;	/* 詳細領域のハンドル */
	DWORD			m_dwTopPos ;

	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() ;
	void	WMSize( DWORD fwSize, WORD nWidth, WORD nHeight ) ;
	void	WMWinIniChange( DWORD wFlag, LPCTSTR pszSection ) ;
	BOOL	WMClose() ;
	LRESULT	WMWndProc( HWND hWnd,  UINT msg, WPARAM wParam, LPARAM lParam, BOOL *bDefault ) ;

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

	static	int		list_proc( int index, const BYTE **ptr, int *len ) ;
	static	int		detail_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 ( !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 ;
}

#define		REG_BASEKEY		TEXT("Software\\Gawaro\\")
#define		VAR_SRCDIR		TEXT("SrcDir")

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

	wsprintf( subkey, TEXT("%s%s"), REG_BASEKEY, szTitleName ) ;
	/* レジストリキーをオープンする */
	lret = RegOpenKeyEx( HKEY_CURRENT_USER, subkey, 0, KEY_QUERY_VALUE, &hk ) ;
	if ( lret != ERROR_SUCCESS ) {
		return FALSE ;
	}
	/* 同期ディレクトリ名 */
	name = VAR_SRCDIR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_szSrcDir ;
	cbData = sizeof m_szSrcDir ;
	lret = RegQueryValueEx( hk, name, NULL, &dwType, lpData, &cbData ) ;
	/* レジストリをクローズする */
	RegCloseKey( hk ) ;
#endif
	return TRUE ;
}

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

	wsprintf( subkey, TEXT("%s%s"), REG_BASEKEY, 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_SRCDIR ;
	dwType = REG_SZ ;
	lpData = (LPBYTE) m_szSrcDir ;
	cbData = (_tcslen(m_szSrcDir) + 1) * sizeof (*m_szSrcDir) ;
	lret = RegSetValueEx( hk, name, 0, dwType, lpData, cbData ) ;
	/* レジストリをクローズする */
	RegCloseKey( hk ) ;
#endif
	return TRUE ;
}

/*
 * レジストリ情報削除
 */
void
MainApp::DeleteReg() const
{
#if 0
	TCHAR	subkey[ MAX_PATH ] ;
	wsprintf( subkey, TEXT("%s%s"), REG_BASEKEY, szTitleName ) ;
	RegDeleteKey( HKEY_CURRENT_USER, subkey ) ;
#endif
}

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

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

void
MainWindow::WMCreate( HWND hWnd )
{
	RECT		rect ;
	DWORD		height = 2, tw, th ;
	HINSTANCE	hInst = m_pApp->get_inst() ;

	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 ) ;
	}
	/* アドレスデータベースをオープンする */
	g_PropID = GetSortPropID() ;
	if ( !OpenAddressBook( m_hwnd, g_PropID ) ) {
		wsprintf( MessageBuf, TEXT("%d"), GetLastError() ) ;
		MessageBox( NULL, MessageBuf, TEXT("OpenAddressBook"), MB_OK|MB_ICONASTERISK ) ;
	}
	/* コマンドバーを追加する */
	height += CreateCommandBar() ;
	m_dwTopPos = height ;

	m_hwndDetail = CreateWindowEx( 0,
						CTRL_BIGLIST,
						TEXT(""),
						WS_CHILD|WS_BORDER|WS_TABSTOP|WS_VSCROLL,
						0, height, tw, th - height,
						hWnd,
						(HMENU) IDC_DETAIL,
						hInst,
						0 ) ;

	m_hwndFind = CreateWindowEx( 0,
						CTRL_LINEEDIT,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP,
						0, height, tw, GetFontH() + 4,
						hWnd,
						(HMENU) IDC_FIND,
						hInst,
						0 ) ;
	height += GetFontH() + 6 ;
	m_hwndList = CreateWindowEx( 0,
						CTRL_BIGLIST,
						TEXT(""),
						WS_CHILD|WS_VISIBLE|WS_BORDER|WS_TABSTOP|WS_VSCROLL,
						0, height, tw, th - height,
						hWnd,
						(HMENU) IDC_LIST,
						hInst,
						0 ) ;

	/* 画面に表示できる文字数を求める */
	GetClientRect( m_hwndList, &rect ) ;
	g_dwMaxCol = (rect.right - 4) / GetFontHW() ;
	/* 一覧用のプロシージャを設定する */
	SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) list_proc ) ;
	/* 初期フォーカスを設定する */
	SetFocus( m_hwndList ) ;
}

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

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

	switch ( idCtrl ) {
	case IDC_LIST:
		if ( notifyCode == BLN_ENTER ) {
			index = SendMessage( m_hwndList, BLM_GETCURSEL, 0, 0 ) ;
			oid = GetAddressCardOid( index ) ;
			if ( !oid || !GetAllProps( oid ) ) {
				break ;
			}
			/* SIPをオフにする */
			ShowSIP( FALSE ) ;
			/* 詳細画面の表示に切り替える */
			SendMessage( m_hwndDetail, BLM_SETPROC, 0, (LPARAM) detail_proc ) ;
			ShowWindow( m_hwndDetail, SW_SHOW ) ;
			ShowWindow( m_hwndList, SW_HIDE ) ;
			ShowWindow( m_hwndFind, SW_HIDE ) ;
			SetFocus( m_hwndDetail ) ;
		} else if ( notifyCode == BLN_ESC ) {
			SetFocus( m_hwndFind ) ;
		} else if ( notifyCode == BLN_CHAR && lParam > TEXT(' ') ) {
			SendMessage( m_hwndFind, WM_CHAR, (WPARAM) lParam, 0 ) ;
			SetFocus( m_hwndFind ) ;
		}
		break ;
	case IDC_DETAIL:
		if ( notifyCode == BLN_ESC ) {
			SendMessage( m_hwndDetail, BLM_SETPROC, 0, 0 ) ;
			ShowWindow( m_hwndList, SW_SHOW ) ;
			ShowWindow( m_hwndFind, SW_SHOW ) ;
			ShowWindow( m_hwndDetail, SW_HIDE ) ;
			SetFocus( m_hwndList ) ;
		}
		break ;
	case IDM_PROP:
		if ( IsWindowVisible( m_hwndList ) ) {
			SendMessage( hWnd, WM_COMMAND, MAKEWPARAM(IDC_LIST,BLN_ENTER), 0 ) ;
		} else {
			SendMessage( hWnd, WM_COMMAND, MAKEWPARAM(IDC_DETAIL,BLN_ESC), 0 ) ;
		}
		break ;
	case IDC_FIND:
		if ( notifyCode == LEN_CHANGE ) {
			GetWindowText( m_hwndFind, MessageBuf, sizeof MessageBuf / sizeof *MessageBuf ) ;
			while ( *MessageBuf ) {
				index = SendMessage( m_hwndList, BLM_FINDSTRING, 0, (LPARAM) MessageBuf ) ;
				if ( index != -1 ) {
					SendMessage( m_hwndList, BLM_SETCURSEL, (WPARAM) index, 0 ) ;
					break ;
				}
				MessageBuf[ _tcslen( MessageBuf ) - 1 ] = 0 ;
			}
			SetWindowText( m_hwndFind, MessageBuf ) ;
		} else if ( notifyCode == LEN_ENTER ) {
			SendMessage( hWnd, WM_COMMAND, MAKEWPARAM(IDC_LIST,BLN_ENTER), 0 ) ;
		} else if ( notifyCode == LEN_KEYDOWN ) {
			SendMessage( m_hwndList, WM_KEYDOWN, (WPARAM) lParam, 0 ) ;
		}
		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 ;
}

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

void
MainWindow::WMSetFocus()
{
	if ( IsWindowVisible( m_hwndList ) ) {
		SetFocus( m_hwndList ) ;
	} else if ( IsWindowVisible( m_hwndDetail ) ) {
		SetFocus( m_hwndDetail ) ;
	}
}

void
MainWindow::WMSize( DWORD fwSize, WORD nWidth, WORD nHeight )
{
	DWORD		h ;

	h = m_dwTopPos ;
	MoveWindow( m_hwndDetail,
				0, h, nWidth, nHeight - h,
				TRUE ) ;
	h += GetFontH() + 6 ;
	MoveWindow( m_hwndList,
				0, h, nWidth, nHeight - h,
				TRUE ) ;
}

void
MainWindow::WMWinIniChange( DWORD wFlag, LPCTSTR pszSection )
{
	SIPINFO		si ;
	static RECT	rect = { 0, 0, 0, 0 }, *pRect ;

	memset( &si, 0, sizeof si ) ;
	si.cbSize = sizeof si ;
	if ( SHSipInfo && SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 ) ) {
		pRect = &si.rcVisibleDesktop ;
		if ( rect.left == pRect->left && rect.right == pRect->right
		  && rect.top == pRect->top && rect.bottom == pRect->bottom ) {
			return ;
		}
		memcpy( &rect, pRect, sizeof (RECT) ) ;
		MoveWindow( m_hwnd,
					si.rcVisibleDesktop.left,
					si.rcVisibleDesktop.top,
					si.rcVisibleDesktop.right - si.rcVisibleDesktop.left,
					si.rcVisibleDesktop.bottom - si.rcVisibleDesktop.top,
					TRUE ) ;
	}
}

LRESULT
MainWindow::WMWndProc( HWND hWnd,  UINT msg, WPARAM wParam, LPARAM lParam, BOOL *bDefault )
{
	*bDefault = FALSE ;
	switch ( msg ) {
	case DB_CEOID_CHANGED:
	case DB_CEOID_CREATED:
	case DB_CEOID_RECORD_DELETED:
		/* データベースに変更があった場合 */
		if ( IsWindowVisible( m_hwndDetail ) ) {
			/* 一覧画面を表にする */
			SendMessage( m_hwndDetail, BLM_SETPROC, 0, 0 ) ;
			ShowWindow( m_hwndList, SW_SHOW ) ;
			ShowWindow( m_hwndFind, SW_SHOW ) ;
			ShowWindow( m_hwndDetail, SW_HIDE ) ;
		}
		/* 一覧用のプロシージャを設定する */
		SendMessage( m_hwndList, BLM_SETPROC, 0, (LPARAM) list_proc ) ;
		/* 初期フォーカスを設定する */
		SetFocus( m_hwndList ) ;
		break ;
	default:
		*bDefault = TRUE ;
		break ;
	}
	return 0 ;
}

int
MainWindow::list_proc( int index, const BYTE **ptr, int *len )
{
	LPTSTR			dst ;
	PEGOID			oid ;
	DWORD			len1, count ;
	static	BYTE	sjis[ 256 ] ;
	TCHAR			buf[ 256 ], unicode[ 256 ] ;

	if ( index < 0 ) {
		return (int) GetNumberOfAddressCards() ;
	} else if ( index >= (int) GetNumberOfAddressCards() ) {
		return -1 ;
	}
	strcpy( (LPSTR) sjis, "(Unknown)" ) ;
	oid = GetAddressCardOid( index ) ;
	if ( !oid ) {
		goto error ;
	}
	/* アドレスカードを取得する */
	memset( &g_AddrCard, 0, sizeof g_AddrCard ) ;
	if ( !OpenAddressCard( oid, &g_AddrCard, 0 ) ) {
		FreeAddressCard( &g_AddrCard ) ;
		goto error ;
	}
	/* 名字を取り出す */
	dst = unicode ;
	if ( g_AddrCard.pszSurname ) {
		_tcscpy( dst, g_AddrCard.pszSurname ) ;
		dst += _tcslen( dst ) ;
	}
	/* 名前を取り出す */
	if ( g_AddrCard.pszGivenName ) {
		*dst++ = TEXT(',') ;
		_tcscpy( dst, g_AddrCard.pszGivenName ) ;
		dst += _tcslen( dst ) ;
	}
	*dst = 0 ;
	*buf = 0 ;
	if ( g_AddrCard.pszWorkPhone ) {
		/* WorkPhoneを取り出す */
		_tcscpy( buf, g_AddrCard.pszWorkPhone ) ;
		_tcscat( buf, TEXT("W") ) ;
	} else if ( g_AddrCard.pszHomePhone ) {
		/* HomePhoneを取り出す */
		_tcscpy( buf, g_AddrCard.pszHomePhone ) ;
		_tcscat( buf, TEXT("H") ) ;
	} else if ( g_AddrCard.pszMobilePhone ) {
		/* MobilePhoneを取り出す */
		_tcscpy( buf, g_AddrCard.pszMobilePhone ) ;
		_tcscat( buf, TEXT("M") ) ;
	} else if ( g_AddrCard.pszPager ) {
		/* Pagerを取り出す */
		_tcscpy( buf, g_AddrCard.pszPager ) ;
		_tcscat( buf, TEXT("P") ) ;
	} else if ( g_AddrCard.pszEmail ) {
		/* E-Mailを取り出す */
		_tcscpy( buf, g_AddrCard.pszEmail ) ;
	}
	len1 = CalcStrCols( unicode ) + CalcStrCols( buf ) ;
	if ( g_dwMaxCol > len1 ) {
		count = g_dwMaxCol - len1 ;
		do {
			*dst++ = TEXT(' ') ;
		} while ( -- count ) ;
		_tcscpy( dst, buf ) ;
		dst += _tcslen( dst ) ;
	}
	*dst = 0 ;
	/* アドレスカードを解放する */
	FreeAddressCard( &g_AddrCard ) ;
	/* Unicode→SJIS変換を行う */
	unicode2sjis( unicode, sjis, sizeof sjis ) ;

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

int
MainWindow::detail_proc( int index, const BYTE **ptr, int *len )
{
	LPTSTR			dst ;
	DWORD			len1, count ;
	static	BYTE	sjis[ 256 ] ;
	TCHAR			unicode[ 256 ] ;

	if ( index < 0 ) {
		return (int) g_dwPropNum ;
	} else if ( index >= (int) g_dwPropNum ) {
		return -1 ;
	}

	len1 = CalcStrCols( g_PropValue[ index ] ) ;
	if ( len1 >= g_dwMaxCol ) {
		_tcscpy( unicode, g_PropValue[ index ] ) ;
	} else {
		dst = unicode ;
		_tcscpy( dst, g_PropName[ index ] ) ;
		dst += _tcslen( g_PropName[ index ] ) ;
		len1 = CalcStrCols( unicode ) ;
		count = 10 - len1 ;
		do {
			*dst++ = TEXT(' ') ;
		} while ( -- count ) ;
		_tcscpy( dst, g_PropValue[ index ] ) ;
	}
	/* Unicode→SJIS変換を行う */
	unicode2sjis( unicode, sjis, sizeof sjis ) ;

	*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_PROPERTIES, IDM_PROP, 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 ] ;

	switch ( message ) {
	case WM_INITDIALOG:
		/* ダイアログタイトル */
		wsprintf( buf, TEXT("About %s"), szTitleName ) ;
		SetWindowText( hDlg, buf ) ;
		/* アプリケーションバージョン */
		wsprintf( buf, TEXT("%s for WinCE V%d.%02d"),
				  szTitleName, g_dwAppVersion / 100, g_dwAppVersion % 100 ) ;
		SetDlgItemText( hDlg, IDC_VERSION, buf ) ;
		/* DLLバージョン */
		wsprintf( buf, TEXT("KCTRL Ver %d.%02d"),
				  g_dwDllVersion / 100, g_dwDllVersion % 100 ) ;
		SetDlgItemText( hDlg, IDC_DLLVERSION, buf ) ;
		/* Copyright */
		wsprintf( buf, TEXT("Copyright %c 1997-1998\r\n%s\r\n%s"),
				  0xA9,
				  TEXT("Eiichiro Ito"),
				  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 ;
}
