//********************************************************************************************
/**
 * @file		checkExcel.cpp
 * @brief		エクセルシートを誤植検索
 *
 *	このファイルの詳細説明
 *
 * @date		2011/10/11	touya	新規作成.
 */
//********************************************************************************************

#define	SW_MODULE_CHECKEXCEL						///< この機能を切り離したい時はコメントアウト.
#ifdef	SW_MODULE_CHECKEXCEL

#ifndef _STOOLS_H
#include <system\win32\dde.h>
#endif

//********************************************************************************************
/**
 * @class		CHECKEXCEL
 * @brief		エクセルシートを誤植検索スクリプトコマンドクラス.
 */
//********************************************************************************************
class CHECKEXCEL : public CHECKTXT
{
	StDDEState	m_stDDEState;
	
	HINSTANCE	m_hInst;
	
	Bool		m_bPrinted;
	
public:
	int			Func( LPCTSTR _sParamString );
	
	static HWND				s_hFindWhd;
	static BOOL CALLBACK	EnumWindowsProc( HWND _hWnd , LPARAM _lp );
	
	CHECKEXCEL();
	~CHECKEXCEL();
	
};

//********************************************************************************************
/**
 * @brief		エクセルシートを誤植検索コンストラクタ.
 */
//********************************************************************************************
CHECKEXCEL::CHECKEXCEL()
 : m_hInst( 0 )
 , m_bPrinted( FALSE )
{
	
}

//********************************************************************************************
/**
 * @brief		エクセルシートを誤植検索デストラクタ.
 */
//********************************************************************************************
CHECKEXCEL::~CHECKEXCEL()
{
	
}


//==============================================================================================================================================
/**
	初期化と開放.
		1ファイルに1つの処理でコンプリートするような場合は修正する必要ありません
		注釈となっている Message_printf を有効にして sample.swb を実行すると動きがよく分かると思います。
*/
//==============================================================================================================================================

HWND	CHECKEXCEL::s_hFindWhd = NULL;

//********************************************************************************************
/**
 * @brief		エクセルのウィンドウハンドルを得る.
 * @author		N.Takeda
 * @date		2011/11/28(月) 17:00:26
 *
 * @param[in]		HWND	_hWnd	.
 * @param[in,out]	LPARAM	_lp		.
 *
 * @return		BOOL CALLBACK	TRUE:成 / FALSE:否
 */
//********************************************************************************************
BOOL CALLBACK CHECKEXCEL::EnumWindowsProc( HWND _hWnd , LPARAM _lp )
{
	TCHAR	strWindowText[1024];
	
	if( (HINSTANCE)_lp != (HINSTANCE)GetWindowLong( _hWnd, GWL_HINSTANCE) )
	{
		GetWindowText(_hWnd , strWindowText , 1024);
		if (strWindowText[0] == 0) return TRUE;
		
		if( NULL != STRING_str( strWindowText, TEXT("Microsoft"), 1024, NULL ) )
			if( NULL != STRING_str( strWindowText, TEXT("Excel"), 1024, NULL ) )
			{
				s_hFindWhd = _hWnd;
				return FALSE;
			}
/*		
		TCHAR	cTemp[1024];
		STRING_printf( cTemp, 1024, TEXT("%s %d != %d"), strWindowText, (HINSTANCE)_lp, (HINSTANCE)GetWindowLong( _hWnd, GWL_HINSTANCE) );
		Message_printf( cTemp );
*/
	}
	return TRUE;
/*	
	GetWindowText(_hWnd , strWindowText , 1024);
	if (strWindowText[0] == 0) return TRUE;

	Message_printf( strWindowText );
*/
//	s_hFindWhd = _hWnd;
//	return FALSE;
}



//==============================================================================================================================================
//	変換処理部分
//==============================================================================================================================================

#define	CHECKEXCEL_OUTAREA		2	///< 変換後の容量は仮に元の倍取っている　内容によって変更して下さい.
#define	CHECKEXCEL_RANGE				///< このdefineを有効にすると範囲限定機能が有効になる.

//********************************************************************************************
/**
 * @brief	エクセルシートを誤植検索変換フィルターサンプル　機能:無変換
 *			テキストデータを取り扱うサンプル.
 *			関数内は patol.lib を使用したサンプルになっているが、中身は完全に別物に変えても問題ありません.
 *
 *			
 *
 * @param[in]	LPCTSTR	_sParamString	引数文字列  ターゲットファイル名 + スクリプトで指定する引数.
 *
 * @return		int	TRUE:成 / FALSE:否(デフォルト)
 */
//********************************************************************************************
int		CHECKEXCEL::Func( LPCTSTR _sParamString )
{
	CSwbParam	cParam( _sParamString );							///< パラメータ処理.
	
	int		ii, jj, iSx, iSy, iEx, iEy;
	LPCTSTR	szFileName, sInifile, sParam, sRange;
	LPTSTR	pPtr;
	TCHAR	cTemp[ 256 ];
	
	#define	REBUFF_SIZE	(4*1024)
	TCHAR	sReBuf[ REBUFF_SIZE ];
	
	
	/// 引数の取り出し.
	/**
	 * ターゲットファイル (GetString(0)としても同じ).
	 * swb ファイルでは指定しない、システムで付加される引数.
	 */
	szFileName = cParam.GetPath();
	sInifile = cParam.GetString( 1 );			///< 第1引数をファイルパスとして取得(%0等が変換されて得られる).★ezParamに入れ替える際も GetStringで
	sParam   = cParam.GetStringIndex( 2 );
	sRange   = cParam.GetStringOption( 'r' );	///< -pSTRING のようなパラメータから "STRING" を得る.
	
	
	iSx = iSy = iEx = iEy = -1;
	
	/// 機能の初期化.
	Initialize( sInifile, sParam );
	
	
	if( sRange )
	{
		pPtr = (LPTSTR)(sRange);
		
		if( *pPtr >= 'A' && *pPtr <= 'Z' )
		{
			jj = 0;
			while( 1 )
			{
				if( 0>iSx )
				{
					if( *pPtr >= 'A' && *pPtr <= 'Z' )
					{
						jj *= ('Z'-'A');
						jj += (*pPtr) - 'A' + 1;
						pPtr++;
					}else{
						iSx = jj;
						jj = 0;
					}
				}
				else if( 0>iSy )
				{
					if( *pPtr >= '0' && *pPtr <= '9' )
					{
						jj *= 10;
						jj += (*pPtr) - '0';
						pPtr++;
					}else{
						iSy = jj;
						jj = 0;
					}
				}
				else if( 0>iEx )
				{
					if( *pPtr >= 'A' && *pPtr <= 'Z' )
					{
						jj *= ('Z'-'A');
						jj += (*pPtr) - 'A' + 1;
						pPtr++;
					}else{
						iEx = jj;
						jj = 0;
					}
				}
				else if( 0>iEy )
				{
					if( *pPtr >= '0' && *pPtr <= '9' )
					{
						jj *= 10;
						jj += (*pPtr) - '0';
						pPtr++;
					}
					else{
						iEy = jj;
						break;
					}
				}
			}
			
		}else{
			Message_printf( TEXT("未対応") );
		}
	}else{
		iSx = iSy = 1;
		iEx = 256;
		iEy = 4096;
	}
	
	if( 0>=iSx || 0>=iSy || 0>=iEx || 0>=iEy )	return TRUE;
	
	/// Excelファイルを開く.
	m_hInst = ShellExecute( NULL, TEXT("open"), szFileName, NULL, NULL, SW_MINIMIZE );
	
	_stZero( StDDEState, &m_stDDEState );
	
	
	TCHAR	cSheetNames[ 256 ];
	Int32	iSheetEntry = DDEXL_GetSheets( szFileName, cSheetNames, 256 );
	pPtr = cSheetNames;
	
	
	if( !m_bPrinted )
	{
		Message_printf( TEXT("Cell(%d,%d)-(%d,%d)"), iSx, iSy, iEx, iEy );
		m_bPrinted = TRUE;
	}
	
	for( Int32 iTab=0 ; iTab<iSheetEntry ; iTab++ )
	{
		DDEXL_Start( &m_stDDEState, szFileName, pPtr );
		
		/// セル走査.
		for( jj=iSx ; jj<=iEx ; jj++ )
		{
			for( ii=iSy ; ii<=iEy ; ii++ )
			{
				if( 0 > DDEXL_GetData( &m_stDDEState, ii, jj, sReBuf, REBUFF_SIZE ) )
				{
					Message_printf( TEXT("(%s)DDEが開始されていません"), szFileName );
					break;
				}
				if( 2 < STRING_len(sReBuf) )	///< 改行のみの場合も弾くため２文字以上.
				{
					SetLine( ii );
					STRING_printf( cTemp, 256, TEXT("[%s]%s"), szFileName, pPtr );
					/// 前後の " 、末端の制御記号を除いてチェック.
					while( sReBuf[STRING_len(sReBuf)-1] == '\"' || sReBuf[STRING_len(sReBuf)-1] <= ' ' )
					{
						sReBuf[STRING_len(sReBuf)-1] = '\0';
					}
					check_string( cTemp, sReBuf + (sReBuf[0]=='\"'), STRING_len(sReBuf) - (sReBuf[0]=='\"') );
				}
			}
		}
		DDEXL_End( &m_stDDEState );
		
		pPtr += STRING_len( pPtr ) + 1;
	}
	
	s_hFindWhd = NULL;
	EnumWindows( EnumWindowsProc , (LPARAM)m_hInst );
	if( s_hFindWhd )	PostMessage( s_hFindWhd, WM_CLOSE, 0, 0 );
	
	return TRUE;
}
#undef	REBUFF_SIZE


CHECKEXCEL	*pC_checkExcel = NULL;

#endif	// SW_MODULE_CHECKEXCEL
