/*-----------------------------------------------------------------------------
[名称]	CharPaletteCanvasDlg.cpp
[概要]	文字パレットタブ内ページクラスの実装
[備考]	なし
[履歴]	2003-04-22	NC		コメント付加(moralog)
-----------------------------------------------------------------------------*/

//-----------------------------------------------------------------------------
// インクルード・不完全定義
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "shitarabian.h"
#include "ExeStruct.h"
#include "GeneralSetting.h"
#include "CharPaletteCanvasDlg.h"
#include "CharPaletteDlg.h"
#include "CharPalette.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/*-----------------------------------------------------------------------------
[名称]	コンストラクタ
[機能]	インスタンスの生成
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
CCharPaletteCanvasDlg::CCharPaletteCanvasDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CCharPaletteCanvasDlg::IDD, pParent)
	, m_sizeButton( 40, 40 )
	, m_nColumn( 1 )
	, m_nRow( 1 )
	, m_eScrollBarAlign( ScrollBarAlignBottom )
	, m_idxCellSelect( 0 )
	, m_idxTab( 0 )
	, m_bEdit( FALSE )
{
	//{{AFX_DATA_INIT(CCharPaletteCanvasDlg)
		// メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。
	//}}AFX_DATA_INIT
}


/*-----------------------------------------------------------------------------
[名称]	データ変換
[機能]	CDialog::DoDataExchange() のヘルプを参照。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCharPaletteCanvasDlg)
	DDX_Control(pDX, IDC_CHARPALETTEEDIT, m_editChar);
	DDX_Control(pDX, IDC_CHARPALETTE_CANVAS, m_Canvas);
	DDX_Control(pDX, IDC_CHARPALETTECANVAS_VSCROLL, m_VScroll);
	DDX_Control(pDX, IDC_CHARPALETTECANVAS_HSCROLL, m_HScroll);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CCharPaletteCanvasDlg, CDialog)
	//{{AFX_MSG_MAP(CCharPaletteCanvasDlg)
	ON_WM_SIZE()
	ON_WM_DRAWITEM()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_COMMAND(IDM_CHARPALETTE_INSERTCELL, OnCharpaletteInsertcell)
	ON_COMMAND(IDM_CHARPALETTE_EDITCELL, OnCharpaletteEditcell)
	ON_COMMAND(IDM_CHARPALETTE_DELETECELL, OnCharpaletteDeletecell)
	ON_EN_KILLFOCUS(IDC_CHARPALETTEEDIT, OnKillfocusCharpaletteedit)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/*-----------------------------------------------------------------------------
[名称]	初期化ハンドラ
[機能]	初期化処理。
[戻値]	CDialog::OnInitDialog()のヘルプを参照。
[備考]	なし
-----------------------------------------------------------------------------*/
BOOL CCharPaletteCanvasDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

	// 編集用エディットボックスをとりあえず隠す
	m_editChar.ShowWindow( SW_HIDE );
/*
	m_Canvas.SetWindowPos(
		0,10,10,
		10,10,
		SWP_NOZORDER|SWP_NOMOVE
	);
*/
	// コントロールの配置
	RePositionControl();

	return TRUE;  // コントロールにフォーカスを設定しないとき、戻り値は TRUE となります
	              // 例外: OCX プロパティ ページの戻り値は FALSE となります
}

/*-----------------------------------------------------------------------------
[名称]	サイズ変更ハンドラ
[機能]	コントロールの再配置処理。
[戻値]	なし
[備考]	CDislog::OnSize()のヘルプを参照。
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnSize(UINT nType, int cx, int cy) 
{
	if ( ::IsWindow( m_Canvas.m_hWnd ) )
	{
		ReflectSize( cx, cy );
	}

	CDialog::OnSize(nType, cx, cy);
}

/*-----------------------------------------------------------------------------
[名称]	サイズ変更処理
[機能]	コントロールの再配置。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::ReflectSize(
	int cx,		// ダイアログページの幅 [pixel] (-) :-
	int cy		// ダイアログページの高さ [pixel] (-) :-
)
{
	m_sizeButton.cx = max( 1, m_sizeButton.cx );
	m_sizeButton.cy = max( 1, m_sizeButton.cy );

	if ( ::IsWindow( m_Canvas.m_hWnd ) )
	{
		CStringArray*	pastrCharz = GetCharz();

		CRect	rcVScroll;
		CRect	rcHScroll;
		m_VScroll.GetWindowRect( &rcVScroll );
		m_HScroll.GetWindowRect( &rcHScroll );

		CRect	rcClient;
		GetClientRect( & rcClient );

		// コントロール位置の計算
		CRect	rcCanvas( rcClient );
		CPoint	ptVScroll( 0, 0 );
		CPoint	ptHScroll( 0, 0 );
		switch ( m_eScrollBarAlign )
		{
		case ScrollBarAlignTop:
			rcCanvas.top = rcHScroll.Height();
			ptHScroll.x = 0;
			ptHScroll.y = 0;
			m_HScroll.ShowWindow( SW_SHOW );
			m_VScroll.ShowWindow( SW_HIDE );
			break;

		case ScrollBarAlignBottom:
			rcCanvas.bottom = rcCanvas.Height() - rcHScroll.Height();
			ptHScroll.x = 0;
			ptHScroll.y = rcCanvas.bottom;
			m_HScroll.ShowWindow( SW_SHOW );
			m_VScroll.ShowWindow( SW_HIDE );
			break;

		case ScrollBarAlignLeft:
			rcCanvas.left = rcVScroll.Width();
			ptVScroll.x = 0;
			ptVScroll.y = 0;
			m_HScroll.ShowWindow( SW_HIDE );
			m_VScroll.ShowWindow( SW_SHOW );
			break;

		case ScrollBarAlignRight:
			rcCanvas.right =  rcCanvas.Width() - rcVScroll.Width();
			ptVScroll.x = rcCanvas.right;
			ptVScroll.y = 0;
			m_HScroll.ShowWindow( SW_HIDE );
			m_VScroll.ShowWindow( SW_SHOW );
			break;

		default:
			break;
		}

		// キャンバスの配置
		m_Canvas.SetWindowPos(
			NULL,
			rcCanvas.left,
			rcCanvas.top,
			rcCanvas.Width(),//rcClient.Width(),
			rcCanvas.Height(),//rcClient.Height(),
			SWP_NOZORDER
		);

		// 垂直スクロールバーの配置
		m_VScroll.SetWindowPos(
			NULL,
			ptVScroll.x,
			ptVScroll.y,
			rcVScroll.Width(),
			cy,
			SWP_NOZORDER
		);

		// 水平スクロールバーの配置
		m_HScroll.SetWindowPos(
			NULL,
			ptHScroll.x,
			ptHScroll.y,
			cx,
			rcHScroll.Height(),
			SWP_NOZORDER
		);

		// 基本的にスクロールしない辺に沿って配置。
		// スクロールする辺にはみだすかんじ
		switch ( m_eScrollBarAlign )
		{
		case ScrollBarAlignTop:
		case ScrollBarAlignBottom:
			// 横スクロールなので基本的に縦に配置する
			m_nRow = ( cy - rcHScroll.Height() ) / m_sizeButton.cy;
			m_nRow = max( m_nRow, 1 );
			m_nColumn = ( pastrCharz->GetSize() + m_nRow -1 ) / m_nRow;
			break;

		case ScrollBarAlignLeft:
		case ScrollBarAlignRight:
			// 縦スクロールなので基本的に横に配置する
			m_nColumn = ( cx - rcVScroll.Width() ) / m_sizeButton.cx;
			m_nColumn = max( m_nColumn, 1 );
			m_nRow = ( pastrCharz->GetSize() + m_nColumn -1 ) / m_nColumn;
			break;

		default:
			break;
		}

		SCROLLINFO	tHInfo;
		tHInfo.cbSize = sizeof( tHInfo ); 
		tHInfo.fMask = SIF_ALL; 
		tHInfo.nMin = 0;
		tHInfo.nMax = (m_nColumn-(cx/m_sizeButton.cx)) * m_sizeButton.cx; 
		tHInfo.nPage = 1;
		tHInfo.nPos = 0;
		tHInfo.nTrackPos = 1; 
		m_HScroll.SetScrollInfo( &tHInfo );

		SCROLLINFO	tVInfo;
		tVInfo.cbSize = sizeof( tVInfo ); 
		tVInfo.fMask = SIF_ALL; 
		tVInfo.nMin = 0;
		tVInfo.nMax = (m_nRow-(cy/m_sizeButton.cy)) * m_sizeButton.cy; 
		tVInfo.nPage = 1;
		tVInfo.nPos = 0;
		tVInfo.nTrackPos = 1; 
		m_VScroll.SetScrollInfo( &tVInfo );
	}
}

/*-----------------------------------------------------------------------------
[名称]	描画ハンドラ
[機能]	セル群の描画処理。
[戻値]	なし
[備考]	CDialog::OnDrawItem()のヘルプを参照。
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
// ▼ (ワーニング回避) BGN 2003.12.29 (moralog) warning C4100
	// warning C4100 回避
	nIDCtl;
	lpDrawItemStruct;
// ▲ (ワーニング回避) END

	Redraw();
}

/*-----------------------------------------------------------------------------
[名称]	描画処理
[機能]	セル群の描画処理。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::Redraw()
{
	for( long idxRow=0 ; idxRow<=m_nRow ; idxRow++ )
	{
		for( long idxColumn=0 ; idxColumn<=m_nColumn ; idxColumn++ )
		{
			if ( !DrawCell( idxRow, idxColumn ) )
			{
				;//break;
			}
		}
	}
}

/*-----------------------------------------------------------------------------
[名称]	行･カラム→セル番号
[機能]	行とカラムから該当するセル番号を取得する。
[戻値]	long		セル番号 [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
long CCharPaletteCanvasDlg::RowColumnToCellIndex(
	long	idxRow,		// I  : 行 [-] (-) :-
	long	idxColumn	// I  : カラム [-] (-) :-
)
{
	long idxChar = 0;
	switch ( m_eScrollBarAlign )
	{
	case ScrollBarAlignTop:
	case ScrollBarAlignBottom:
		// 横スクロールのとき、縦の高さは固定
		idxChar = m_nRow*idxColumn+idxRow;
		break;

	case ScrollBarAlignLeft:
	case ScrollBarAlignRight:
		idxChar = idxRow*m_nColumn+idxColumn;
		break;

	default:
		break;
	}
	return( idxChar );
}

/*-----------------------------------------------------------------------------
[名称]	セル番号→行･カラム
[機能]	セル番号から該当する行とカラムを取得する。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::CellIndexToRowColumn(
	long	idxChar,			// I  : セル番号 [-] (-) :-
	long*	pidxRow,			//   O: 行 [-] (-) :-
	long*	pidxColumn			//   O: カラム [-] (-) :-
)
{
	switch ( m_eScrollBarAlign )
	{
	case ScrollBarAlignTop:
	case ScrollBarAlignBottom:
		// 横スクロールのとき、縦の高さは固定
		*pidxColumn = idxChar/m_nRow;
		*pidxRow = idxChar - (*pidxColumn*m_nRow);
		break;

	case ScrollBarAlignLeft:
	case ScrollBarAlignRight:
		*pidxRow = idxChar/m_nColumn;
		*pidxColumn = idxChar - (*pidxRow*m_nColumn);
		break;

	default:
		ASSERT( FALSE );
		break;
	}
}

/*-----------------------------------------------------------------------------
[名称]	セル番号→行･カラム
[機能]	セル番号から該当する行とカラムを取得する。
[戻値]	BOOL		TRUE
[備考]	なし
-----------------------------------------------------------------------------*/
BOOL CCharPaletteCanvasDlg::DrawCell(
	long	idxRow,		// I  : 行 [-] (-) :-
	long	idxColumn	// I  : カラム [-] (-) :-
)
{
	CStringArray*	pastrCharz = GetCharz();
	CClientDC dc( &m_Canvas );

	CRect	rcClient;
	m_Canvas.GetClientRect( &rcClient );

	// リージョンの設定
	CRgn		rgn;
	rgn.CreateRectRgn( 0, 0, rcClient.Width(), rcClient.Height() );
	dc.SelectObject( rgn );
	CPen*	pOldPen = (CPen*)dc.SelectStockObject( BLACK_PEN );


	// スクロール位置に対応したマッピングに変更する
	{
		int	iXOffset = 0;
		int	iYOffset = 0;
		switch ( m_eScrollBarAlign )
		{
		case ScrollBarAlignTop:
		case ScrollBarAlignBottom:
			// 横スクロール
			iXOffset = m_HScroll.GetScrollPos();
			break;

		case ScrollBarAlignLeft:
		case ScrollBarAlignRight:
			iYOffset = m_VScroll.GetScrollPos();
			break;

		default:
			ASSERT( FALSE );
			break;
		}
		dc.SetViewportOrg(
			-iXOffset,
			-iYOffset
		);
	}

	// セル描画
	{
		COLORREF	colBack = RGB( 255, 255, 255 );
		COLORREF	colSelect = RGB( 200, 200, 255 );

		// セル割り出し
		long idxChar = RowColumnToCellIndex( idxRow, idxColumn );
		if ( idxChar == m_idxCellSelect )
		{
			colBack = colSelect;
		}

		// セル位置の計算
		CRect	rcCell(
			idxColumn * m_sizeButton.cx,
			idxRow * m_sizeButton.cy,
			idxColumn * m_sizeButton.cx + m_sizeButton.cx -1,
			idxRow * m_sizeButton.cy + m_sizeButton.cy -1
		);

		// キャラクタのないセルを描画
		{
			BOOL	bValid = TRUE;
			bValid &= ( idxChar < pastrCharz->GetSize() );
			bValid &= ( idxRow < m_nRow );
			bValid &= ( idxColumn < m_nColumn );
			if( !bValid )
			{
				dc.FillSolidRect(
					rcCell.left,
					rcCell.top,
					rcCell.Width()+1,
					rcCell.Height()+1,
					GetSysColor( COLOR_3DFACE )
				);
				// 帰る
				return( FALSE );
			}
		}

		// 通常セルの描画
		{
			dc.FillSolidRect(
				rcCell.left+1,
				rcCell.top+1,
				rcCell.Width()-1,
				rcCell.Height()-1,
				colBack
			);

			// キャラクタの描画
			{
				CLogFont	Font;
				CFont*	pfonOld = dc.SelectObject( Font.GetFont(&dc) );
				dc.DrawText(
					pastrCharz->GetAt( idxChar ),
					rcCell,
					DT_CENTER|DT_VCENTER|DT_NOPREFIX|DT_SINGLELINE
				);
				dc.SelectObject( pfonOld );
			}

			dc.MoveTo(
				rcCell.left,
				rcCell.top
			);
			dc.LineTo(
				rcCell.left,
				rcCell.bottom
			);
			dc.LineTo(
				rcCell.right,
				rcCell.bottom
			);
			dc.LineTo(
				rcCell.right,
				rcCell.top
			);
			dc.LineTo(
				rcCell.left,
				rcCell.top
			);
		}
	}

	dc.SelectObject( pOldPen );

	dc.SetViewportOrg( 0, 0 );
	return( TRUE );
}

/*-----------------------------------------------------------------------------
[名称]	スクロールバー配置設定
[機能]	スクロールバーの配置情報を変更する。
[戻値]	なし
[備考]	RePositionControl() しないと反映されない。
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::SetScrollBarAlign(
	EScrollBarAlign eAlign		// I  : 配置情報 [-] (-) :-
)
{
	m_eScrollBarAlign = eAlign;
}

/*-----------------------------------------------------------------------------
[名称]	座標→セル取得
[機能]	クライアント座標からセル位置を取得する
[戻値]	long		セル番号 [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
long CCharPaletteCanvasDlg::PointToCell(
	CPoint		ptCursor,		// I  : カーソル位置 [クライアント座標] (-) :-
	long*		pRow,			//   O: 行 [-] (-) :-
	long*		pColumn			//   O: カラム [-] (-) :-
)
{
	// スクロール位置に対応したマッピングを意識する
	int	iXOffset = 0;
	int	iYOffset = 0;
	{
		switch ( m_eScrollBarAlign )
		{
		case ScrollBarAlignTop:
		case ScrollBarAlignBottom:
			// 横スクロール
			iXOffset = m_HScroll.GetScrollPos();
			break;

		case ScrollBarAlignLeft:
		case ScrollBarAlignRight:
			iYOffset = m_VScroll.GetScrollPos();
			break;

		default:
			ASSERT( FALSE );
			break;
		}
	}

	// 押されたセル判別
	m_Canvas.ScreenToClient( &ptCursor );
	*pColumn = (ptCursor.x+iXOffset) / m_sizeButton.cx;
	*pRow = (ptCursor.y+iYOffset) / m_sizeButton.cy;
	long	idxChar = RowColumnToCellIndex( *pRow, *pColumn );
	return( idxChar );
}

/*-----------------------------------------------------------------------------
[名称]	セル番号→座標取得
[機能]	セル番号に該当する座標を得る。
[戻値]	long		セル番号 [-] (-)
[備考]	なし
-----------------------------------------------------------------------------*/
CRect CCharPaletteCanvasDlg::CellToRect(
	long		idxCell		// I  : セル番号 [-] (-) :-
)
{
	CRect	rc;

	// スクロール位置に対応したマッピングを意識する
	int	iXOffset = 0;
	int	iYOffset = 0;
	{
		switch ( m_eScrollBarAlign )
		{
		case ScrollBarAlignTop:
		case ScrollBarAlignBottom:
			// 横スクロール
			iXOffset = m_HScroll.GetScrollPos();
			rc.left = (idxCell/m_nRow);
			rc.top = idxCell-(rc.left*m_nRow);
			break;

		case ScrollBarAlignLeft:
		case ScrollBarAlignRight:
			iYOffset = m_VScroll.GetScrollPos();
			rc.top = (idxCell/m_nColumn);
			rc.left = idxCell - (rc.top*m_nColumn);
			break;

		default:
			ASSERT( FALSE );
			break;
		}
	}

	// キャンバス位置に応じて座標を調整
	rc.top *= m_sizeButton.cy;
	rc.left *= m_sizeButton.cx;

	CRect	rcClient;
	m_Canvas.GetWindowRect( &rcClient );
	ScreenToClient( &rcClient );
	rc.top += rcClient.top;
	rc.left += rcClient.left;

	rc.bottom = rc.top + m_sizeButton.cy;
	rc.right = rc.left + m_sizeButton.cx;
	return( rc );
}


/*-----------------------------------------------------------------------------
[名称]	メッセージハンドラ
[機能]	キー入力処理。
[戻値]	BOOL
[備考]	CDialog::PreTranslateMessage()のヘルプを参照。
-----------------------------------------------------------------------------*/
BOOL CCharPaletteCanvasDlg::PreTranslateMessage(MSG* pMsg) 
{
	CStringArray*	pastrCharz = GetCharz();

	// キー入力のイベント処理
	if ( m_bEdit )
	if ( GetFocus() == &m_editChar )
	{
	// 編集モード
		switch( pMsg->message )
		{
		case WM_KEYDOWN:
			switch( pMsg->wParam )
			{
			case VK_RETURN:
				OnKillfocusCharpaletteedit();
				return( TRUE );
				break;

			case VK_ESCAPE:
				m_editChar.SetWindowText( pastrCharz->GetAt(m_idxCellSelect) );
				OnKillfocusCharpaletteedit();
				return( TRUE );
				break;

			default:
				break;
			}
			break;

		default:
			break;
		}
	}

	if ( !m_bEdit )
	if ( pMsg->message == WM_RBUTTONDOWN )
	if ( pMsg->hwnd == m_Canvas.m_hWnd )
	{
		// クリック位置の選択
		long	iNewRow;
		long	iNewColumn;
		long	idxChar;
		idxChar = PointToCell(
			pMsg->pt,
			&iNewRow,
			&iNewColumn
		);
		if ( iNewColumn < m_nColumn )
		if ( iNewRow < m_nRow )
		if ( idxChar < pastrCharz->GetSize() )
		{
			long	iOldColumn;
			long	iOldRow;
			long	idxOldChar = m_idxCellSelect;
			m_idxCellSelect = idxChar;
			CellIndexToRowColumn( idxOldChar, &iOldRow, &iOldColumn );

			// セルの描画（選択状態の反映）
			DrawCell( iOldRow, iOldColumn );
			DrawCell( iNewRow, iNewColumn );
		}

		// ポップアップメニューの表示
		{
			// メニューのロード
			CMenu menu;
			VERIFY(menu.LoadMenu(IDR_CHARPALETTE));

			// ポップアップとして表示するサブメニューを取り出す
			CMenu* pPopup = menu.GetSubMenu( 1 );
			ASSERT(pPopup != NULL);

			// 編集・削除の有効無効
			BOOL	bExist = ( m_idxCellSelect < pastrCharz->GetSize() );
			pPopup->EnableMenuItem( IDM_CHARPALETTE_EDITCELL, MF_BYCOMMAND | bExist?MF_ENABLED:MF_GRAYED );
			pPopup->EnableMenuItem( IDM_CHARPALETTE_DELETECELL, MF_BYCOMMAND | bExist?MF_ENABLED:MF_GRAYED );

			// ポップアップメニューの表示
			CPoint	ptCursor;
			::GetCursorPos( &ptCursor );
			pPopup->TrackPopupMenu(
				TPM_LEFTALIGN | TPM_RIGHTBUTTON,
				ptCursor.x, ptCursor.y,
				this
			);
		}
		return( TRUE );
	}

	if ( !m_bEdit )
	if ( pMsg->message == WM_LBUTTONDOWN )
	if ( pMsg->hwnd == m_Canvas.m_hWnd )
	{
		long	iNewRow;
		long	iNewColumn;
		long	idxChar;
		idxChar = PointToCell(
			pMsg->pt,
			&iNewRow,
			&iNewColumn
		);

		// セル押下処理
		if ( iNewColumn < m_nColumn )
		if ( iNewRow < m_nRow )
		if ( idxChar < pastrCharz->GetSize() )
		{
			long	iOldColumn;
			long	iOldRow;
			long	idxOldChar = m_idxCellSelect;
			m_idxCellSelect = idxChar;
			CellIndexToRowColumn( idxOldChar, &iOldRow, &iOldColumn );

			// セルの描画（選択状態の反映）
			DrawCell( iOldRow, iOldColumn );
			DrawCell( iNewRow, iNewColumn );

			// メインウィンドウへ文字列を挿入
			CString		str = pastrCharz->GetAt(idxChar);
			m_pParent->ConfirmChar( str );
			return( TRUE );
		}
	}

	if ( pMsg->message == WM_KEYDOWN )
	if ( pMsg->hwnd == m_Canvas.m_hWnd )
	{
		long	iOldColumn;
		long	iOldRow;
		long	idxOldChar = m_idxCellSelect;
		CellIndexToRowColumn( idxOldChar, &iOldRow, &iOldColumn );
		long	iColumn = iOldColumn;
		long	iRow = iOldRow;

		// マトリクスからはみ出した場合は反対端から出てくる
		switch( pMsg->wParam )
		{
		case VK_TAB:
			// タブコントロールにフォーカスを当てる
			m_pParent->SetTabFocus();
			m_pParent->PostMessage( WM_KEYDOWN, VK_TAB, 0 );
			break;

		case VK_ESCAPE:
			{
				// メインウィンドウへ戻る
				m_pParent->ToMainWindow();
			}
			break;

		case VK_RETURN:
		case VK_SPACE:
			{
				// メインウィンドウへ文字列を挿入
				CString		str = pastrCharz->GetAt(idxOldChar);
				m_pParent->ConfirmChar( str );
			}
			break;

		case VK_UP:
			iRow--;
			if ( iRow < 0 )
			{
				iRow = m_nRow-1;
				while( RowColumnToCellIndex( iRow, iColumn ) >= pastrCharz->GetSize() )
				{
					iRow--;
				}
			}
			break;

		case VK_DOWN:
			iRow++;
			if( RowColumnToCellIndex( iRow, iColumn ) >= pastrCharz->GetSize() )
			{
				iRow = 0;
			}
			if( iRow >= m_nRow )
			{
				iRow = 0;
			}
			break;

		case VK_LEFT:
			iColumn--;
			if ( iColumn < 0 )
			{
				iColumn = m_nColumn-1;
				while( RowColumnToCellIndex( iRow, iColumn ) >= pastrCharz->GetSize() )
				{
					iColumn--;
				}
			}
			break;

		case VK_RIGHT:
			iColumn++;
			if( RowColumnToCellIndex( iRow, iColumn ) >= pastrCharz->GetSize() )
			{
				iColumn = 0;
			}
			if( iColumn >= m_nColumn )
			{
				iColumn = 0;
			}
			break;

		default:
			break;
		}

		long	idxChar = RowColumnToCellIndex( iRow, iColumn );
		if ( idxChar < pastrCharz->GetSize() )
		{
			m_idxCellSelect = idxChar;
			DrawCell( iOldRow, iOldColumn );
			DrawCell( iRow, iColumn );
		}
		return( TRUE );
	}


	return CDialog::PreTranslateMessage(pMsg);
}


/*-----------------------------------------------------------------------------
[名称]	水平スクロールバーハンドラ
[機能]	スクロール処理。
[戻値]	なし
[備考]	CDialog::OnHScroll()のヘルプを参照。
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	int	min = 0;
	int max = 0;
	int	iNowPos = 0;
	if( pScrollBar != NULL )
	{
		pScrollBar->GetScrollRange( &min, &max );
		iNowPos = pScrollBar->GetScrollPos();
	}

	if( pScrollBar ==  &m_HScroll )
	{
		switch( nSBCode )
		{
		case SB_LEFT://   左端へスクロール。
			pScrollBar->SetScrollPos( max );
			break;
		case SB_ENDSCROLL://   スクロール終了。
			break;
		case SB_LINELEFT://   左へスクロール。
			pScrollBar->SetScrollPos( max(min,iNowPos-m_sizeButton.cx/2) );
			break;
		case SB_PAGELEFT://   1 ページ左へスクロール。
			pScrollBar->SetScrollPos( max(min,iNowPos-m_sizeButton.cx) );
			break;
		case SB_LINERIGHT://   右へスクロール。
			pScrollBar->SetScrollPos( min(max,iNowPos+m_sizeButton.cx/2) );
			break;
		case SB_PAGERIGHT://   1 ページ右へスクロール。
			pScrollBar->SetScrollPos( min(max,iNowPos+m_sizeButton.cx) );
			break;
		case SB_RIGHT://   右端へスクロール。
			pScrollBar->SetScrollPos( min );
			break;
		case SB_THUMBPOSITION://   絶対位置へスクロール。現在位置は引数 nPos で指定されます。
		case SB_THUMBTRACK://スクロール ボックスを指定位置へドラッグします。現在位置は引数 nPos で指定されます。 
			pScrollBar->SetScrollPos( nPos );
			break;
		default:
			break;
		}
		Redraw();
	}

	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

/*-----------------------------------------------------------------------------
[名称]	垂直スクロールバーハンドラ
[機能]	スクロール処理。
[戻値]	なし
[備考]	CDialog::OnVScroll()のヘルプを参照。
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	int	min = 0;
	int max = 0;
	int	iNowPos = 0;
	if( pScrollBar != NULL )
	{
		pScrollBar->GetScrollRange( &min, &max );
		iNowPos = pScrollBar->GetScrollPos();
	}

	if( pScrollBar ==  &m_VScroll )
	{
		switch( nSBCode )
		{
		case SB_LEFT://   左端へスクロール。
			pScrollBar->SetScrollPos( max );
			break;
		case SB_ENDSCROLL://   スクロール終了。
			break;
		case SB_LINELEFT://   左へスクロール。
			pScrollBar->SetScrollPos( max(min,iNowPos-m_sizeButton.cy/2) );
			break;
		case SB_PAGELEFT://   1 ページ左へスクロール。
			pScrollBar->SetScrollPos( max(min,iNowPos-m_sizeButton.cy) );
			break;
		case SB_LINERIGHT://   右へスクロール。
			pScrollBar->SetScrollPos( min(max,iNowPos+m_sizeButton.cy/2) );
			break;
		case SB_PAGERIGHT://   1 ページ右へスクロール。
			pScrollBar->SetScrollPos( min(max,iNowPos+m_sizeButton.cy) );
			break;
		case SB_RIGHT://   右端へスクロール。
			pScrollBar->SetScrollPos( min );
			break;
		case SB_THUMBPOSITION://   絶対位置へスクロール。現在位置は引数 nPos で指定されます。
		case SB_THUMBTRACK://スクロール ボックスを指定位置へドラッグします。現在位置は引数 nPos で指定されます。 
			pScrollBar->SetScrollPos( nPos );
			break;
		default:
			break;
		}
		Redraw();
	}
	
	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}

/*-----------------------------------------------------------------------------
[名称]	ボタンサイズ変更
[機能]	ボタンのサイズを変更する。
[戻値]	なし
[備考]	RePositionControl()しないと反映されない。
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::SetButtonSize( CSize sizeButton )
{
	m_sizeButton = sizeButton;
}

/*-----------------------------------------------------------------------------
[名称]	挿入ボタンハンドラ
[機能]	選択位置にセルを挿入し、編集モードに入る。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnCharpaletteInsertcell() 
{
	CStringArray*	pastrCharz = GetCharz();
	pastrCharz->InsertAt( m_idxCellSelect, _T("") );
	RePositionControl();
	RedrawWindow();

	OnCharpaletteEditcell();
}

/*-----------------------------------------------------------------------------
[名称]	編集ボタンハンドラ
[機能]	選択位置のセルに対し、編集モードに入る。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnCharpaletteEditcell() 
{
	CRect	rc( CellToRect( m_idxCellSelect ) );

	// エディットボックスを配置し、内容をセットする
	m_editChar.SetWindowPos( &wndTop, rc.left,rc.top, rc.Width(),rc.Height(), SWP_NOREPOSITION|SWP_NOZORDER);
	CStringArray*	pastrCharz = GetCharz();
	m_editChar.SetWindowText( pastrCharz->GetAt(m_idxCellSelect) );

	// 入力モード開始
	m_editChar.ShowWindow( SW_SHOW );
	m_editChar.SetFocus();

	m_bEdit = TRUE;
}

/*-----------------------------------------------------------------------------
[名称]	削除ボタンハンドラ
[機能]	選択位置のセルを削除する。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnCharpaletteDeletecell() 
{
	CStringArray*	pastrCharz = GetCharz();
	CString		strMes;
	strMes.Format( "\"%s\" を削除しますか？", pastrCharz->GetAt(m_idxCellSelect) );
	if ( MessageBox( strMes, "セルの削除確認", MB_ICONWARNING|MB_OKCANCEL ) == IDOK )
	{
		pastrCharz->RemoveAt( m_idxCellSelect );
		RePositionControl();
		RedrawWindow();
	}
}

/*-----------------------------------------------------------------------------
[名称]	文字編集終了（エディットボックスのフォーカス喪失ハンドラ）
[機能]	文字編集の終了と登録パレット登録処理。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void CCharPaletteCanvasDlg::OnKillfocusCharpaletteedit() 
{
	CString		strChar;
	m_editChar.GetWindowText( strChar );

	CStringArray*	pastrCharz = GetCharz();
	if ( m_idxCellSelect < pastrCharz->GetSize() )
	{
		// テキストをさしなおす
		pastrCharz->SetAt( m_idxCellSelect, strChar );

		// セルの描画
		long	iColumn;
		long	iRow;
		CellIndexToRowColumn( m_idxCellSelect, &iRow, &iColumn );
		DrawCell( iRow, iColumn );
	}

	// エディットコントロールを消去
	m_editChar.ShowWindow( SW_HIDE );
	m_Canvas.SetFocus();
	m_bEdit = FALSE;
}

/*-----------------------------------------------------------------------------
[名称]	パレット文字列群取得
[機能]	パレットで使用する文字列群の取得。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
CStringArray*	CCharPaletteCanvasDlg::GetCharz() 
{
	CArray<CCharPalette, CCharPalette&>* paPalettez = CGeneralSetting::GetInstance()->GetCharPaletteManager()->GetDefine()->GetItemz();
	if ( m_idxTab < paPalettez->GetSize() )
	{
		CCharPalette&	Palette = (*paPalettez)[ m_idxTab ];
		return( Palette.GetCharz() );
	}
	return( NULL );
}

/*-----------------------------------------------------------------------------
[名称]	コントロール再配置処理
[機能]	描画属性の変更を受けてコントロールを配置しなおす。
[戻値]	なし
[備考]	なし
-----------------------------------------------------------------------------*/
void	CCharPaletteCanvasDlg::RePositionControl() 
{
	// コントロールの配置
	CRect	rcClient;
	GetClientRect( &rcClient );
	ReflectSize( rcClient.Width(), rcClient.Height() );
}
