//********************************************************************************************
/**
 * @file		main.cpp
 * @brief		要約説明
 *
 *	このファイルの詳細説明
 *
 * @author		N.Takeda
 * @date		2010/03/24(水) 19:41:55
 */
//********************************************************************************************
#include "main.h"
#include "params.h"

#include <commctrl.h>
#include <mbstring.h>

#include <assert.h>
#ifndef _STOOLS_H
#include <system/win32/env.h>
#endif
#include "resource.h"

#include "string/csv.h"



#ifdef _DEBUG
//# define	DEBUG_OUT_BATCMD						///< 有効にするとバッチファイルから取得したコマンドをbatcmd.txtに出力.
//# define BATCH_TEST								///< 有効にすると指定したバッチファイルを起動時に固定読み込み.
#endif


#ifdef BATCH_TEST
// 固定バッチ.
//char	*s_lpszCmdLine = "\"D:\\work\\program\\tool\\swComponent\\_update.swb\"";	///< フルパスで指定する.
//char	*s_lpszCmdLine = "\"C:\\work\\tool\\swriter\\sample\\checkExcel\\checkExcel.swb\"";	///< フルパスで指定する.
char	*s_lpszCmdLine = "-s\\\"C:\\tool\\cpp2htm\\cpp2htm %1 /mode:\"section\" /dlg:0\\\" -f*.txt -oOUTINFONAME=C:\\work\\tool\\swriter\\swriter\\OutputcheckTxt.txt";
#endif

/**
	定義
 */
#define	MESSAGEINFO_SIZE	(1024*1024)	///< メッセージウィンドウバッファサイズ(オーバーするとこのサイズ分更に加算).
#define	MESSAGE_1MAX		(256*1024)	///< 一度にメッセージ表示できる長さ.

#define	DROP_BATCHLINE		(60)

static	const	TCHAR	c_sButton[]			= TEXT("BUTTON");
static	const	TCHAR	c_sStatic[]			= TEXT("STATIC");
static	const	TCHAR	c_sEdit[]			= TEXT("EDIT");
static	const	TCHAR	c_sListBox[]		= TEXT("LISTBOX");


static	const	TCHAR	c_sSettingSectionMain[]	= TEXT("SETTING");
static	const	TCHAR	c_sIniSectionMain[]	= TEXT("MAIN");

static	const	TCHAR	c_sDefaultOutFile[]	= TEXT("MSG.TXT");	///< デフォルトのメッセージ出力ファイル名.


static	const	TCHAR	c_sTempSwbName[]	= TEXT("temp.swb");	///< 
TCHAR	c_sTempSwbPath[ T_MAXPATH ] = TEXT("");


/// アプリケーションローカルの変数
WINDOW_INFO		s_cWin;
STRUCT_GLOBAL	s_stGl;


static	Int32	s_iMIsize;
static	Int32	WINDOW_W;							///< ウィンドウ横幅.
static	Int32	WINDOW_H;							///< ウィンドウ縦幅.


void	swriter_cmd( SCRIPT_STAT SStat, LPCTSTR pPath );
void	swriter_exit( Bool bExit );


Bool	Read_SWriterBatch( LPCTSTR _pFName );

static	Bool	OpenGetFileName( HWND hWnd );
static	void	default_function();
static	void	set_messagepath( LPTSTR path );


//------------------------------------------------------
//		Windows基礎関数
//------------------------------------------------------
static Bool Init_Window( HINSTANCE _hInstance, HINSTANCE _hPrevInstance, LPSTR _lpszCmdLine, Int32 _cmdShow );
static void Init_MainWnd();
static void Init_ChildWnd_zero();
static void Init_ChildWnd();
static void Init_SystemMenu();
static long FAR PASCAL MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam );

//------------------------------------------------------
//		WindowsMessage
//------------------------------------------------------
static void MyWmCreate( HWND hWnd );
static void MyWmClose( HWND hWnd );
static void MyWmPaint( HWND hWnd );
static void MyWmDropFiles( HWND hWnd, HDROP hDrop );
static void MyWmCommand( HWND hWnd, WPARAM wParam, LPARAM lParam );

//------------------------------------------------------
//		Timer関連
//------------------------------------------------------
static void TimerStart_conv( HWND hWnd );
static void CALLBACK TimerFunc_conv( UINT wID, UINT wUser, DWORD dwUser, DWORD dw1, DWORD dw2 );

//static void CALLBACK TimerFunc_wave( UINT wID, UINT wUser, DWORD dwUser, DWORD dw1, DWORD dw2 );

static void TimerStop( HWND hWnd, UINT &id);



//------------------------------------------------------
//		関数
//------------------------------------------------------
void	List_show();
void 	line_list( Int32 idx );
static void List_del();
static void List_delext1();
static void List_delext2();
static void Data_Initialize();
static void CmdLine_Parameter( LPTSTR cmdLien, LPTSTR data );

static void read_profile();
void	write_profile();

static	void	GetCommandParam( SCRIPT_STAT *pSStat, xstring sString );

static	void	Push_start( Bool bEffStop );

static	Bool	TimerConv( HWND hWnd );
static	void	out_infomessage( LPTSTR name );

static	Bool	MakeTempScript( LPCTSTR _pCmdLine );


//------------------------------------------------------
//		外部関数
//------------------------------------------------------
Bool 	Dlg_msgbox1();
Bool 	Dlg_msgbox3();
Bool 	Dlg_msgbox6();



////////////////////////////////////////////////////////////////
//      これがメインプログラムです                            //
////////////////////////////////////////////////////////////////
Int32 PASCAL WinMain( HINSTANCE _hInstance, HINSTANCE _hPrevInstance, LPSTR lpszCmdLine, Int32 _cmdShow )
{
	MSG	  msg;
	
	
#if 0
	TCHAR		sStr[ 256 ] = TEXT("D:\\work\\program\\tool\\swriter\\swriter\\checktxt\\readme.txt \"\\123456\\\"  ABCDWEEF	\"kakko no naka\" ");
	CSwbParam	cObj( sStr );
	
	cObj.Trace();
	TRACE( TEXT("*1:%s\n"), cObj.GetFilePath( 1 ) );
#endif
	
	
	if( Init_Window( _hInstance, _hPrevInstance, lpszCmdLine, _cmdShow ) )
	{
		while( GetMessage( &msg, NULL, 0, 0 ) )
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		
		return msg.wParam;
	}
	
	WINDOW_Destroy( s_cWin );
#ifdef _DEBUG
#else	// _DEBUG
	FILE_delete( c_sTempSwbPath );
#endif	// not _DEBUG
	
	return 0;
}


//////////////////////////////////////////////////////////
//		ウィンドウイニシャライズ						//
//////////////////////////////////////////////////////////
static Bool Init_Window( HINSTANCE _hInstance, HINSTANCE _hPrevInstance, LPSTR _lpszCmdLine, Int32 _cmdShow )
{
	TCHAR	sTemp[_MAX_PATH], drive[_MAX_DRIVE], cDir[_MAX_DIR];
	
	
	s_stGl.ScriptPath[0] = 0;
	s_stGl.MessagePath[0] = 0;
	
#ifdef BATCH_TEST
	_lpszCmdLine = reinterpret_cast<LPSTR>(s_lpszCmdLine);
#endif
	
	if( !_hPrevInstance )
	{
		s_stGl.hInst = _hInstance;
		
		/// 作業ディレクトリを確保.
		GetModuleFileName( s_stGl.hInst, sTemp, sizeof(sTemp) );
		FILE_split( sTemp, drive, cDir, NULL, NULL );
		FILE_merge( s_stGl.MainPath, drive, cDir, NULL, NULL );
		
		read_profile();
		Data_Initialize();	///< データの初期化.
		
		{
#ifdef	_UNICODE
			CTOUTF16	cUtf;
			CmdLine_Parameter( cUtf.From(_lpszCmdLine), sTemp );	///< コマンドラインの引数を取得.
#else
			CmdLine_Parameter( _lpszCmdLine, sTemp );				///< コマンドラインの引数を取得.
#endif
		}
		
		Bool	bNormalExec = FALSE;
		if( MakeTempScript( sTemp ) == FALSE )						///< 引数に直スクリプト指定してないかチェック.
		{
			if( sTemp[ 1 ] == ':' )
			{
				/// フルパスはそのまま.
				STRING_cpy( s_stGl.ScriptPath, sTemp );
			}
			else{
				/// フルパスでないならカレントを付加する.
				FILE_GetCurrentDirectory( s_stGl.ScriptPath );
				catyen( s_stGl.ScriptPath );
				STRING_cat( s_stGl.ScriptPath, sTemp );
			}
			bNormalExec = TRUE;
		}
		
		Init_MainWnd();
		
		if( s_stGl.ScriptPath[0] != 0 )		///< 引数が指定されているのはバッチ起動.
		{
			if( FALSE == Read_SWriterBatch( s_stGl.ScriptPath ) )
			{
				/// 引数に指定しているファイルが見つからない.
				Message_error( TEXT("not found. %s"), s_stGl.ScriptPath );
			}
			set_messagepath( s_stGl.ScriptPath );
			if( s_stGl.m_pOption->m_bAuto && s_stGl.m_cXcopy.GetEntry() > 0 ){	///< 自動起動がonでファイルが指定されているなら.
				s_stGl.autoexec = 1;											///< 起動させる(再描画で受け取り実行している).
			}else
				s_stGl.autoexec = 0;
			
		}
		
		if( bNormalExec && !s_stGl.m_pOption->m_bDefaultCurrent )	///< オプションはバッチリード後でないと入っていないのでここで行う.
		{
			/// スクリプトを格納しているフォルダをカレントに.
			FILE_split( s_stGl.ScriptPath, drive, cDir, NULL, NULL );
			FILE_merge( sTemp, drive, cDir, NULL, NULL );
			FILE_SetCurrentDirectory( sTemp );								///< カレント移動(バッチドロップアウト起動の時はカレントがC:\のため).
		}
		
		default_function();
		
		Init_ChildWnd();
		
		return TRUE;
	}
	return FALSE;
}


////////////////////////////////////////////////////////
//      メインウィンドウ作成                          //
////////////////////////////////////////////////////////
static void Init_MainWnd()
{
	s_cWin = WINDOW_SetStdInfo( TEXT("PROC"), WINDOW_TITLE, enWindowTypeStandard, MainWndProc, s_stGl.hInst, WINDOW_W, WINDOW_H );
	
	WINDOW_SetMenu( s_cWin, (TCHAR*)IDR_MENU1 );
	WINDOW_Create( s_cWin );
	
	WINDOW_Update( s_cWin, SW_SHOW );
	
	// ファイルドロップ可/不可
	DragAcceptFiles( s_cWin.m_hWnd, TRUE );
	
	// タイトルバーのアイコン
	SetClassLong( s_cWin.m_hWnd, GCL_HICON, (long)LoadIcon( s_stGl.hInst, (LPTSTR)IDI_ICON1 ) );
	
	Init_ChildWnd_zero();
	Init_SystemMenu();
	
	s_stGl.TimerID = 0;
}


////////////////////////////////////////////////////////
//      子ウィンドウの作成                            //
////////////////////////////////////////////////////////
static void Init_ChildWnd()
{
	HWND			hTmp;
	TCHAR			cStr[ 32 ];
	
	
	s_stGl.hStart = CreateWindow( c_sButton, TEXT("開始"),
		WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
		WINDOW_W-90, 5, 80, 20,
		s_cWin.m_hWnd, (HMENU)BTN_START, s_stGl.hInst, NULL );
	SendMessage( s_stGl.hStart, WM_SETFONT, (WPARAM)s_stGl.hFont, MAKELPARAM(FALSE,0) );
	
	
	hTmp = CreateWindow( c_sStatic, TEXT("SWriteBatch"),
		WS_CHILD | WS_VISIBLE,
		10,8,75,15,
		s_cWin.m_hWnd, NULL, s_stGl.hInst, NULL );
	SendMessage( hTmp, WM_SETFONT, (WPARAM)s_stGl.hFont, MAKELPARAM(FALSE,0) );
	
	s_stGl.hScriptPath = CreateWindowEx( WS_EX_CLIENTEDGE, c_sEdit, s_stGl.ScriptPath,
		WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
		90, 5, WINDOW_W-190, 18,
		s_cWin.m_hWnd, NULL, s_stGl. hInst, NULL );
	SendMessage( s_stGl.hScriptPath,WM_SETFONT,(WPARAM)s_stGl.hFont,MAKELPARAM(FALSE,0) );
	
	
	//	ファイルリスト
	hTmp = CreateWindow( c_sStatic, TEXT("File list"),
		WS_CHILD | WS_VISIBLE,
		10, 32, 60, 12,
		s_cWin.m_hWnd, NULL, s_stGl.hInst, NULL );
	SendMessage( hTmp, WM_SETFONT, (WPARAM)s_stGl.hFont, MAKELPARAM(FALSE,0) );
	
	s_stGl.hFlist = CreateWindowEx( WS_EX_CLIENTEDGE, c_sListBox, TEXT(""),
		WS_CHILD | WS_VSCROLL | WS_VISIBLE | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | LBS_NOTIFY,
		10, 46, 160, WINDOW_H-46-17,
		s_cWin.m_hWnd, NULL, s_stGl.hInst, NULL );
	SendMessage( s_stGl.hFlist, WM_SETFONT, (WPARAM)s_stGl.hFont, MAKELPARAM(FALSE,0) );
	
	List_show();	// 確保されたデータをリストボックスに表示
	
	if(s_stGl.bFuntion_lock)
		EnableWindow( s_stGl.hScriptPath, FALSE );
	
	wsprintf( cStr, TEXT("Entry : %3d"), s_stGl.m_cXcopy.GetEntry() );
	s_stGl.hEntry = CreateWindow( c_sStatic, cStr,
		WS_CHILD | WS_VISIBLE,
		10, WINDOW_H-17, 80, 12,
		s_cWin.m_hWnd, NULL, s_stGl.hInst, NULL );
	SendMessage( s_stGl.hEntry, WM_SETFONT, (WPARAM)s_stGl.hFont, MAKELPARAM(FALSE,0) );
	
}


////////////////////////////////////////////////////////
//      子ウィンドウの作成                            //
//		起動時のエラーを受け取るため先に初期化		  //
////////////////////////////////////////////////////////
static void Init_ChildWnd_zero()
{
	HWND		hTmp;
	
	s_stGl.hFont = CreateFont( 12, 0, 0, 0, FW_EXTRALIGHT, FALSE, FALSE, 0, SHIFTJIS_CHARSET,
		OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, TEXT("ＭＳ ゴシック") );
	
	
	//	インフォメーション
	hTmp = CreateWindow( c_sStatic, TEXT("Message"), WS_CHILD | WS_VISIBLE,
		175,32,76,12,s_cWin.m_hWnd,NULL,s_stGl.hInst,NULL );
	SendMessage( hTmp, WM_SETFONT, (WPARAM)s_stGl.hFont, MAKELPARAM(FALSE,0) );
	
	s_stGl.hInfo = CreateWindowEx( WS_EX_CLIENTEDGE, c_sEdit, TEXT(""),
		WS_CHILD | WS_VSCROLL | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL,
		175, 46, WINDOW_W-180, WINDOW_H-56, s_cWin.m_hWnd, NULL, s_stGl.hInst, NULL );
	SendMessage( s_stGl.hInfo, WM_SETFONT, (WPARAM)s_stGl.hFont, MAKELPARAM(FALSE,0) );
	SendMessage( s_stGl.hInfo, EM_SETREADONLY, (WPARAM)(Bool)TRUE, 0 );
	
	s_iMIsize = MESSAGEINFO_SIZE;
	mem_alloc( TCHAR, s_stGl.m_memMsg, s_iMIsize );
	
}


////////////////////////////////////////////////////////
//      システムメニュー設定                          //
////////////////////////////////////////////////////////
static void Init_SystemMenu()
{
	HMENU	hMenu;
	
	hMenu = GetSystemMenu( s_cWin.m_hWnd, FALSE );
	
}


////////////////////////////////////////////////////////////////
//      メインルーチンにしようぜっ！                          //
////////////////////////////////////////////////////////////////
static long FAR PASCAL MainWndProc( HWND hWnd,UINT message,UINT wParam,LONG lParam )
{
	switch( message )
	{
		/// タイマーでポストされる(オリジナル)
		case TIMER_LOOP_CONV:
			if( TimerConv( hWnd ) == FALSE ){
				TimerStop( hWnd,s_stGl.TimerID );
				
				if(s_stGl.autoexec == 2 && s_stGl.m_pOption->m_bAtExit && s_stGl.iErrors==0)	///< 自動起動していて、自動終了がonでエラーがないなら終了する
					PostMessage( hWnd, WM_CLOSE, 0, 0 );
			}
			s_stGl.TimerFlag = FALSE;
			break;
		
		/// ウィンドウ作成時(表示前)
		case WM_CREATE:
			MyWmCreate( hWnd );
			break;
		
		/// ウィンドウ再描画時
		case WM_PAINT:
			MyWmPaint( hWnd );
			break;
		
		/// Windowsが終了する
		case WM_QUERYENDSESSION:
			MyWmClose( hWnd );
			return 1L;
		
		/// アプリケーションが終了する
		case WM_CLOSE:
			DestroyWindow( hWnd );
#ifdef _DEBUG
#else	// _DEBUG
			FILE_delete( c_sTempSwbPath );
#endif	// not _DEBUG
			break;
		
		/// ウィンドウの破棄される
		case WM_DESTROY:
			MyWmClose( hWnd );
			PostQuitMessage( 0 );
			break;
		
		/// ファイルがドロップされた
		case WM_DROPFILES:
			MyWmDropFiles( hWnd, (HDROP)wParam );
			break;
		
		case WM_SIZE:
			switch(wParam){			///< サイズ変更の種類を示すフラグ.
				case SIZE_MAXIMIZED:	///< ウィンドウが最大化されました
				case SIZE_MINIMIZED:	///< ウィンドウがアイコン化されました
				case SIZE_MAXHIDE:		///< ほかのウィンドウが最大化されたときに、メッセージがすべてのポップアップ ウィンドウに送られました
				case SIZE_MAXSHOW:		///< ほかのウィンドウが復元されたときに、メッセージがすべてのポップアップ ウィンドウに送られました
					break;
				case SIZE_RESTORED:		///< ウィンドウのサイズが (最大化またはアイコン化以外のサイズに) 変更されました
					
					/// ボタン類の再配置
					MoveWindow( s_stGl.hInfo, 175, 46, LOWORD(lParam)-180, HIWORD(lParam)-56, TRUE );
					MoveWindow( s_stGl.hFlist, 10, 46, 160, HIWORD(lParam)-46-17, TRUE );
					MoveWindow( s_stGl.hEntry, 10, HIWORD(lParam)-17, 80, 12, TRUE );
					
					MoveWindow( s_stGl.hStart, LOWORD(lParam)-90, 5, 80, 20, TRUE );
					MoveWindow( s_stGl.hScriptPath, 90, 5, LOWORD(lParam)-190, 18, TRUE );
					
					/// サイズ更新
					WINDOW_W = LOWORD(lParam);
					WINDOW_H = HIWORD(lParam);
			}
			break;
		
		/// ---- キーが押された
		case WM_KEYDOWN:
			switch(wParam){
				case VK_RETURN:
					if( s_stGl.m_pOption->m_bRetexec )	Push_start( TRUE );
					break;
			}
			break;
		
		/// コマンドが入力された
		case WM_COMMAND:
			MyWmCommand( hWnd, wParam, lParam );
			break;
		
		default:
			return DefWindowProc( hWnd, message, wParam, lParam );
	}
	
	return 0L;
}


//======================================================
//		ウィンドウ作成時
//======================================================
static void MyWmCreate( HWND hWnd )
{
	
}


//======================================================
//		ウィンドウを閉じる
//======================================================
static void MyWmClose( HWND hWnd )
{
	mem_del(s_stGl.m_memMsg);
	
	DeleteObject( s_stGl.hFont );
	
	write_profile();
	
}


//======================================================
//		ウィンドウ再描画時
//======================================================
static void MyWmPaint( HWND hWnd )
{
	PAINTSTRUCT		ps;
	
	if(s_stGl.autoexec == 1){		///< 描画後、自動起動が設定されていたら実行
		Push_start( TRUE );
		s_stGl.autoexec = 2;		///< 自動起動した
	}
	
	/// 空処理でも置いておかないと子ウィンドウ描画がされない
	BeginPaint( hWnd, ( LPPAINTSTRUCT )&ps );
	
	EndPaint( hWnd, ( LPPAINTSTRUCT )&ps );
	
//	ValidateRect( hWnd, NULL );
	
}


//======================================================
//		ファイルがドラッグされた
//======================================================
static void MyWmDropFiles( HWND _hWnd, HDROP _hDrop )
{
	TCHAR		cDrive[_MAX_DRIVE], cDir[_MAX_DIR];
	TCHAR		szName[_MAX_PATH], cWork[_MAX_PATH];
	POINT		pt;
	Int32			iEntry, ii;
	
	
	/// ファイルがドロップされた位置を取得
	if( DragQueryPoint( _hDrop, &pt ) == FALSE )	return;
	
	if( pt.y < DROP_BATCHLINE )
	{
		/// バッチファイル領域にドロップ
		DragQueryFile( _hDrop, 0, s_stGl.ScriptPath, sizeof(s_stGl.ScriptPath) );
		
		/// カレントディレクトリをドロップファイルのパス移動
		FILE_split( s_stGl.ScriptPath, cDrive, cDir, NULL, NULL );
		FILE_merge( cWork, cDrive, cDir, NULL, NULL );
		FILE_SetCurrentDirectory( cWork );
		
		if( !s_stGl.bFuntion_lock )
			SetWindowText( s_stGl.hScriptPath, s_stGl.ScriptPath );
		
		Data_Initialize();
		
		Read_SWriterBatch( s_stGl.ScriptPath );
		List_show();
		return;
	}
	
	/// ドロップされたファイル数
	iEntry = DragQueryFile( _hDrop, 0xFFFFFFFF, NULL, 0 );
	
	s_stGl.m_cXcopy.SetSearchSubDir( s_stGl.m_pOption->m_bSearchSubDir );	///< バッチ優先. システムにした方がよいか検討中.
	
	for( ii=0 ; ii<iEntry ; ii++ )
	{
		DragQueryFile( _hDrop, ii, szName, sizeof(szName) );
		s_stGl.m_cXcopy.AddXcopy( szName );
	}
	
	List_show();	///< リストを表示.
	
	DragFinish( _hDrop );
	
}


//======================================================
//		コマンド
//======================================================
static void MyWmCommand( HWND hWnd, WPARAM wParam, LPARAM lParam )
{
	SCRIPT_STAT		SStat;
	TCHAR			cTemp[ 256 ];
	
	
	#define	COM_ONETOUCH(id,Command,Param)	case id:if(s_stGl.bLock)break;\
											if(s_stGl.bFuntion_lock){	_message(TEXT("ワンタッチ機能は利用できません"));return;}\
											SStat.sCommand = Command;SStat.sParam = Param;STRING_cpy(s_stGl.ScriptPath,Command);\
											goto	skip
	
	//									STRING_cpy(temp,string);STRING_cpy(s_stGl.ScriptPath,temp);
	
	switch( LOWORD(wParam) ){
	/// -----メニュー-----.
	/// ファイル.
		//
		case ID_MENU_BATLOAD:
			if(s_stGl.bLock)break;
			OpenGetFileName( hWnd );
			List_show();
			break;
		//Infomation出力
		case ID_MENU_OUTINFO:
			if(s_stGl.bLock)break;
			out_infomessage( s_stGl.m_cSysOption.m_sOutInfoName );
			break;
		//プロパティ
		case ID_MENU_PROPERTY:
			if(s_stGl.bLock)break;
			Dlg_msgbox1();
			break;
		//終了
		case ID_MENU_EXIT:
			if(s_stGl.bLock)break;
			PostMessage( hWnd,WM_CLOSE,0,0 );
			break;
		
	/// 編集.
		/// 全クリア.
		case ID_MENU_CLEAR:
			if(s_stGl.bLock)break;
			List_clear();
			Message_clear();
			break;
		case ID_MENU_LISTDEL:
			if(s_stGl.bLock)break;
			List_del();
			break;
		case ID_MENU_NOTEXTDEL:
			List_delext1();
			break;
		case ID_MENU_EXTDEL:
			List_delext2();
			break;
	/*	case ID_MENU_LISTUP:
			List_up();
			break;
		case ID_MENU_LISTDOWN:
			List_down();
			break;
	*/	
		
	/// ワンタッチ機能	MENUのID				コマンド			パラメータ.
		COM_ONETOUCH( ID_MENU_OP_DELREM,		TEXT("DELREM"),		TEXT(""));		///< 注釈削除.
		COM_ONETOUCH( ID_MENU_OP_KANJICHK,		TEXT("KANJI_CHECK"),TEXT("1"));		///< 漢字チェック.
		COM_ONETOUCH( ID_MENU_OP_ZEN2HAN,		TEXT("ZEN2HAN"),	TEXT(""));		///< 半角変換.
		COM_ONETOUCH( ID_MENU_OP_LISTSORT,		TEXT("LISTSORT"),	TEXT("-op"));	///< ソート.
		COM_ONETOUCH( ID_MENU_OP_FILECHECK,		TEXT("FILECHECK"),	TEXT(""));		///< ファイルチェック.
		COM_ONETOUCH( ID_MENU_OP_BINARYDUMP,	TEXT("DUMP"),		TEXT(""));		///< ダンブ.
		COM_ONETOUCH( ID_MENU_OP_SAMESIZE,		TEXT("SAMESIZE"),	TEXT(""));		///< サイズ統一.
		
		skip://全共通部分
			s_stGl.m_stScrStat.clear();
			s_stGl.m_stScrStat.push_back( SStat );
			
			wsprintf( cTemp, TEXT("%s %s"), SStat.sCommand.c_str(), SStat.sParam.c_str() );
			SetWindowText( s_stGl.hScriptPath, cTemp );
			STRING_cpy( s_stGl.ScriptPath, cTemp );
			
			if(s_stGl.m_cXcopy.GetEntry() != 0 ){
				Push_start( TRUE );
			}
			break;
		
	/// ヘルプ.
		//About
		case ID_MENU_ABOUT:
			if( s_stGl.bLock )	break;
			Dlg_msgbox6();
			break;
		
	/// -----ボタン-----.
		/// 開始ボタンが押された.
		case BTN_START:
			
			GetWindowText( s_stGl.hScriptPath, s_stGl.ScriptPath , sizeof(s_stGl.ScriptPath) );
			
			Push_start( TRUE );
			break;
		
	}
	
}




////////////////////////////////////////////////////////////////////////////////
//		関数
////////////////////////////////////////////////////////////////////////////////



// -----関連付け
//======================================================
//		コマンドラインのパラメータを取得
//======================================================
static void CmdLine_Parameter( LPTSTR cmdLien, LPTSTR data )
{
	Int32		ii;
	
	if( cmdLien[0] == '"' ){
		for( ii = 0 ; cmdLien[ii+1] != '"' ; ii++ ){
			if( cmdLien[ii+1] == '\0' )	break;
			data[ii] = cmdLien[ii+1];
		}
		data[ii] = '\0';
	}
	else{
		STRING_cpy( data,cmdLien );
	}
}


// -----リストボックス
//======================================================
//		リストデータ表示
//======================================================
void	List_show()
{
	Int32		ii, iEntry;
	TCHAR	str[ 32 ];
	
	
	iEntry = s_stGl.m_cXcopy.GetEntry();
	
	if( iEntry == 0 )	return;
	
	for( ii = 0 ; ii < (Int32)iEntry ; ii++ )	line_list( ii );
	
	SendMessage( s_stGl.hFlist,LB_SETCURSEL,(WPARAM)0,0 );
	
	wsprintf( str, TEXT("Entry : %3d"), iEntry );
	SetWindowText( s_stGl.hEntry, str );
	
}




//======================================================
//		リスト全消去
//======================================================
void	List_clear()
{
	SendMessage( s_stGl.hFlist,LB_RESETCONTENT,0,0 );
	s_stGl.m_cXcopy.Clear();
	
	SetWindowText( s_stGl.hEntry, TEXT("Entry :   0") );
	
	s_stGl.ScriptPath[0] = 0;
	SetWindowText( s_stGl.hScriptPath, s_stGl.ScriptPath );
	
}


void 	line_list( Int32 idx )
{
	TCHAR	cBuff[256];
	
	
	wsprintf( cBuff, TEXT("%-13s"), s_stGl.m_cXcopy.GetStringFileName(idx).c_str() );
	
	SendMessage( s_stGl.hFlist, LB_DELETESTRING, (WPARAM)idx, 0 );
	SendMessage( s_stGl.hFlist, LB_INSERTSTRING, (WPARAM)idx, (LPARAM)cBuff );
	SendMessage( s_stGl.hFlist, LB_SETCURSEL, (WPARAM)idx, 0 );
	
}


//======================================================
//		リスト削除
//======================================================
static void List_del()
{
	Int32		iIdx;
	TCHAR	str[32];
	
	
	if( s_stGl.m_cXcopy.GetEntry() == 0 )	return;
	
	iIdx = SendMessage( s_stGl.hFlist,LB_GETCURSEL,0,0 );
	if( iIdx == -1 )	return;
	
	SendMessage( s_stGl.hFlist,LB_DELETESTRING,(WPARAM)iIdx,0 );
	
	if( iIdx == s_stGl.m_cXcopy.GetEntry()-1 )
		SendMessage( s_stGl.hFlist,LB_SETCURSEL,(WPARAM)(iIdx-1),0 );
	else
		SendMessage( s_stGl.hFlist,LB_SETCURSEL,(WPARAM)iIdx,0 );
	
	s_stGl.m_cXcopy.Delete( iIdx );
	
	wsprintf( str,TEXT("Entry : %3d"),s_stGl.m_cXcopy.GetEntry() );
	
	SetWindowText( s_stGl.hEntry, str );
}


//======================================================
//		リスト削除	指定拡張子以外を削除
//======================================================
static void List_delext1()
{
	Int32		iIdx;
	xstring		sExt;
	
	
	if( s_stGl.m_cXcopy.GetEntry() == 0 )	return;
	
	iIdx = SendMessage( s_stGl.hFlist,LB_GETCURSEL,0,0 );
	if( iIdx == -1 )	return;
	
	sExt = s_stGl.m_cXcopy.GetFileExt( iIdx );
	
	s_stGl.m_cXcopy.DeleteOnExt( sExt.c_str(), TRUE );
	
	SendMessage( s_stGl.hFlist,LB_RESETCONTENT,0,0 );
	List_show();
}


//======================================================
//		リスト削除	指定拡張子を削除
//======================================================
static void List_delext2()
{
	Int32		iIdx;
	xstring		sExt;
	
	
	if( s_stGl.m_cXcopy.GetEntry() == 0 )	return;
	
	iIdx = SendMessage( s_stGl.hFlist,LB_GETCURSEL,0,0 );
	if( iIdx == -1 )	return;
	
	sExt = s_stGl.m_cXcopy.GetFileExt( iIdx );
	
	s_stGl.m_cXcopy.DeleteOnExt( sExt.c_str(), FALSE );
	
	SendMessage( s_stGl.hFlist,LB_RESETCONTENT,0,0 );
	List_show();
}


//********************************************************************************************
/**
 * @brief		データの初期化
 *				スクリプト、ファイルリスト、メッセージをクリア
 * @author		N.Takeda
 *
 * @return		なし (none)
 */
//********************************************************************************************
static void Data_Initialize()
{
	s_stGl.m_cXcopy.Clear();
	
	s_stGl.m_stScrStat.clear();
	
	if( s_stGl.m_memMsg != NULL )	s_stGl.m_memMsg[ 0 ] = 0;
	
	s_stGl.iErrors = 0;
}


// -----開始
//======================================================
//		実行開始
//======================================================
static void Push_start( Bool _bEffStop )
{
	
	if( _bEffStop == TRUE && s_stGl.bLock == TRUE )		///< 実行中再度ボタンが押されたら「中止」
	{
		s_stGl.bFlagStop = TRUE;
		Message_win( TEXT("Stoped...") );
		
		SetWindowText( s_stGl.hStart, TEXT("開始") );
		s_stGl.bLock = FALSE;
		
		if( s_stGl.m_pOption->m_bOutInfo )	out_infomessage( s_stGl.m_pOption->m_sOutInfoName );
		
		return;
	}
	
	
	if(s_stGl.m_cXcopy.GetEntry() == 0 ){
		_message( TEXT("ファイルが選択されていません") );
		return;	//	ファイルなし
	}
	
	if( s_stGl.ScriptPath[0] == 0 )
	{
		GetWindowText( s_stGl.hScriptPath, s_stGl.ScriptPath , sizeof(s_stGl.ScriptPath) );
		
		if( s_stGl.ScriptPath[0] != 0 )
		{
			SCRIPT_STAT		SStat;
			xstring			sString = s_stGl.ScriptPath;
			
			GetCommandParam( &SStat, sString );
			s_stGl.m_stScrStat.push_back( SStat );
		}
		
	}
	
	if( s_stGl.ScriptPath[0] == 0 || s_stGl.m_stScrStat.empty() )
	{
		_message(TEXT("コマンドが指定されていません"));
		return;	//	スクリプトなし
	}
	
	Message_clear();
	
	s_stGl.bLock = TRUE;
	SetWindowText( s_stGl.hStart, TEXT("中止") );
	
	
	s_stGl.m_itStat = s_stGl.m_stScrStat.begin();
	
	s_stGl.m_iIdx = 0;
	s_stGl.bFlagStop = FALSE;
	s_stGl.err = 0;
	
/*	
	STRING_cpy(path,s_stGl.OutPath);
	if(path[0] != 0)
		if(path[STRING_len(path)-1] != '\\')	STRING_cat(path,"\\");
	STRING_cat(path,s_stGl.OutFile);
*/	
	s_stGl.m_cXcopy.SetSearchSubDir( s_stGl.m_pOption->m_bSearchSubDir );
	
	TimerStart_conv( s_cWin.m_hWnd );
	
}


//======================================================
//		タイマー内部
//======================================================
static Bool TimerConv( HWND hWnd )
{
	/// 「中止」による終了
	if( s_stGl.bFlagStop )	return FALSE;
	
	//	カーソル合わせ
	line_list( s_stGl.m_iIdx );
	
	swriter_cmd( *s_stGl.m_itStat , s_stGl.m_cXcopy.GetPathFileName( s_stGl.m_iIdx ) );
	
	line_list( s_stGl.m_iIdx );	//	リストウィンドウ内容更新
	
	s_stGl.m_iIdx++;
	if( s_stGl.m_iIdx >= (Int32)s_stGl.m_cXcopy.GetEntry() || s_stGl.err != 0 )
	{
		if(s_stGl.err == 0)
		{
			s_stGl.m_itStat++;
			
			if( s_stGl.m_itStat != s_stGl.m_stScrStat.end() )
			{
			//	次のスクリプトコマンドを設定して始めから
				s_stGl.m_iIdx = 0;
				
				//	終了処理	でもまだ次のスクリプトがある場合
				swriter_exit( FALSE );
				return TRUE;
			}
		}
		
		//	終了処理
		swriter_exit( TRUE );
		
		if(s_stGl.iErrors == 0)	Message_win( TEXT("Completed..."));
		else					Message_printf( TEXT("error(s).%d"), s_stGl.iErrors );
		
		if(s_stGl.m_pOption->m_bOutInfo)	out_infomessage( s_stGl.m_pOption->m_sOutInfoName );
		
		SetWindowText( s_stGl.hStart, TEXT("開始") );
		s_stGl.bLock = FALSE;
		
		return FALSE;	//	終了
	}
	
	return TRUE;
}


//********************************************************************************************
/**
 * @brief		デフォルトの機能
 *				機能限定してある場合、スクリプトコマンドを .ini から読み込む
 * @author		N.Takeda
 *
 * @return		なし (none)
 */
//********************************************************************************************
static	void	default_function()
{
	TCHAR	defFile[ _MAX_PATH ], drive[ _MAX_DRIVE ], cDir[ _MAX_DIR ];
	
	
	if( s_stGl.bFuntion_lock == FALSE )
		if(s_stGl.ScriptPath[0] != 0)	return;		//Batch により起動した場合はBatch優先(ただし、Function_Lockしてない場合)
	
	FILE_split( s_stGl.MainPath, drive, cDir, NULL, NULL );
	FILE_merge( defFile, drive, cDir, TEXT("swriter"), TEXT(".ini") );
	
	
	GetPrivateProfileString( TEXT("EXTRA"), TEXT("NAME"), TEXT(""), s_stGl.ScriptPath, _MAX_FNAME, defFile );
	
	if( s_stGl.ScriptPath[0] != 0 )
	{
		SCRIPT_STAT	SStat;
		TCHAR		temp[256];
		
		GetPrivateProfileString(TEXT("EXTRA"), TEXT("SCRIPT"), TEXT(""), temp, 256, defFile);
		SStat.sCommand = temp;
		SStat.sParam.clear();
		s_stGl.m_stScrStat.push_back( SStat );
	}
}


// -----設定ファイル
//********************************************************************************************
/**
 * @brief		デフォルト設定を読み込みます
 * @author		N.Takeda
 *
 * @return		なし (none)
 */
//********************************************************************************************
static void read_profile()
{
	
	s_stGl.m_cSysOption.m_bAuto				= PROFILE_GetInt( c_sIniSectionMain, TEXT("AUTOEXEC"),	0 );
	s_stGl.m_cSysOption.m_bAtExit			= PROFILE_GetInt( c_sIniSectionMain, TEXT("ATEXIT"),	0 );
	s_stGl.m_cSysOption.m_bOutInfo			= PROFILE_GetInt( c_sIniSectionMain, TEXT("OUTINFO"),	0 );
	s_stGl.m_cSysOption.m_bBackup			= PROFILE_GetInt( c_sIniSectionMain, TEXT("BACKUP"),	0 );
	s_stGl.m_cSysOption.m_bRetexec			= PROFILE_GetInt( c_sIniSectionMain, TEXT("RETEXEC"),	0 );
	s_stGl.m_cSysOption.m_iRange			= PROFILE_GetInt( c_sIniSectionMain, TEXT("RANGE"),		0 );
	s_stGl.m_cSysOption.m_bSearchSubDir		= PROFILE_GetInt( c_sIniSectionMain, TEXT("SEARCHSUB"),	0 );
	s_stGl.m_cSysOption.m_bDefaultCurrent	= PROFILE_GetInt( c_sIniSectionMain, TEXT("DEFAULTCURRENT"),	0 );
	
//	s_stGl.m_cXcopy.SetSearchSubDir( s_stGl.m_cSysOption.m_bSearchSubDir );
	
	
	PROFILE_GetString( c_sIniSectionMain, TEXT("OUTINFONAME"), s_stGl.m_cSysOption.m_sOutInfoName, _MAX_PATH, c_sDefaultOutFile );
	PROFILE_GetString( c_sIniSectionMain, TEXT("BACKUPPATH"), s_stGl.m_cSysOption.m_sBackupPath, _MAX_PATH, TEXT("") );
	
	WINDOW_W = PROFILE_GetInt( c_sIniSectionMain, TEXT("WINDOW_W"), 480 );
	WINDOW_H = PROFILE_GetInt( c_sIniSectionMain, TEXT("WINDOW_H"), 360 );
	
	s_stGl.bFuntion_lock = PROFILE_GetInt( TEXT("EXTRA"), TEXT("LOCK"), FALSE );
}


//********************************************************************************************
/**
 * @brief		デフォルト設定を書き込みます
 * @author		N.Takeda
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	write_profile(){
	
	PROFILE_SetInt( c_sIniSectionMain,TEXT("AUTOEXEC"),			s_stGl.m_cSysOption.m_bAuto );
	
	PROFILE_SetInt( c_sIniSectionMain,TEXT("ATEXIT"),			s_stGl.m_cSysOption.m_bAtExit );
	PROFILE_SetInt( c_sIniSectionMain,TEXT("OUTINFO"),			s_stGl.m_cSysOption.m_bOutInfo );
	PROFILE_SetInt( c_sIniSectionMain,TEXT("BACKUP"),			s_stGl.m_cSysOption.m_bBackup );
	PROFILE_SetInt( c_sIniSectionMain,TEXT("RETEXEC"),			s_stGl.m_cSysOption.m_bRetexec );
	PROFILE_SetInt( c_sIniSectionMain,TEXT("RANGE"),			s_stGl.m_cSysOption.m_iRange );
	PROFILE_SetInt( c_sIniSectionMain,TEXT("SEARCHSUB"),		s_stGl.m_cSysOption.m_bSearchSubDir );
	PROFILE_SetInt( c_sIniSectionMain,TEXT("DEFAULTCURRENT"),	s_stGl.m_cSysOption.m_bDefaultCurrent );
	
	PROFILE_SetInt( c_sIniSectionMain, TEXT("WINDOW_W"),		WINDOW_W );
	PROFILE_SetInt( c_sIniSectionMain, TEXT("WINDOW_H"),		WINDOW_H );
	
	PROFILE_SetString( c_sIniSectionMain,TEXT("OUTINFONAME"),	s_stGl.m_cSysOption.m_sOutInfoName );
	PROFILE_SetString( c_sIniSectionMain,TEXT("BACKUPPATH"),	s_stGl.m_cSysOption.m_sBackupPath );
}


//********************************************************************************************
/**
 * @brief		profilebatchの読み込み.
 * @author		N.Takeda
 * @date		2011/05/28(土) 19:34:01
 *
 * @param[in]	LPCTSTR	_pBuff	バッファ.
 * @param[in]	Int32	_iLen	長さ.
 *
 * @return		なし (none)
 */
//********************************************************************************************
static void read_profile_batch( LPCTSTR _pBuff, Int32 _iLen )
{
	s_stGl.m_cBatOption = s_stGl.m_cSysOption;
	
	if( FALSE == PROBUFF_IsSection( _pBuff, _iLen, c_sSettingSectionMain ) )	return;
	
	s_stGl.m_cBatOption.m_bAuto				= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("AUTOEXEC"),		s_stGl.m_cSysOption.m_bAuto );
	s_stGl.m_cBatOption.m_bAtExit			= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("ATEXIT"),			s_stGl.m_cSysOption.m_bAtExit );
	s_stGl.m_cBatOption.m_bOutInfo			= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("OUTINFO"),		s_stGl.m_cSysOption.m_bOutInfo );
	s_stGl.m_cBatOption.m_bBackup			= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("BACKUP"),			s_stGl.m_cSysOption.m_bBackup );
	s_stGl.m_cBatOption.m_bRetexec			= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("RETEXEC"),		s_stGl.m_cSysOption.m_bRetexec );
	s_stGl.m_cBatOption.m_iRange			= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("RANGE"),			s_stGl.m_cSysOption.m_iRange );
	s_stGl.m_cBatOption.m_bSearchSubDir		= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("SEARCHSUB"),		s_stGl.m_cSysOption.m_bSearchSubDir );
	s_stGl.m_cBatOption.m_bDefaultCurrent	= PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("DEFAULTCURRENT"),	s_stGl.m_cSysOption.m_bDefaultCurrent );
	
	PROBUFF_GetString( _pBuff, _iLen, c_sSettingSectionMain, TEXT("OUTINFONAME"), s_stGl.m_cBatOption.m_sOutInfoName,	_MAX_PATH, s_stGl.m_cSysOption.m_sOutInfoName );
	PROBUFF_GetString( _pBuff, _iLen, c_sSettingSectionMain, TEXT("BACKUPPATH"), s_stGl.m_cBatOption.m_sBackupPath,		_MAX_PATH, s_stGl.m_cSysOption.m_sBackupPath );
	
#if 0
	WINDOW_W = PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("WINDOW_W"), 480 );
	WINDOW_H = PROBUFF_GetInt( _pBuff, _iLen, c_sSettingSectionMain, TEXT("WINDOW_H"), 360 );
#endif
	
	s_stGl.m_cXcopy.SetSearchSubDir( s_stGl.m_cBatOption.m_bSearchSubDir );
	
	/// バッチの設定に切り替え.
	s_stGl.m_pOption = &s_stGl.m_cBatOption;
}


// -----タイマー
//======================================================
//		高精度タイマーを開始します
//======================================================
static void TimerStart_conv( HWND hWnd )
{
	TIMECAPS	caps;
	
	s_stGl.TimerFlag = FALSE;
	
	timeGetDevCaps( &caps,sizeof(caps) );
	timeBeginPeriod( caps.wPeriodMin );
	
	s_stGl.TimerID = timeSetEvent( 66,caps.wPeriodMin,TimerFunc_conv,(DWORD)hWnd,(UINT)TIME_PERIODIC );
	
}


//======================================================
//		タイマーコールバック関数
//======================================================
static void CALLBACK TimerFunc_conv( UINT wID, UINT wUser, DWORD dwUser, DWORD dw1, DWORD dw2 )
{
	HWND	hWnd = (HWND)dwUser;
	
	T_ASSERT( s_stGl.TimerID != 0 );
	if( s_stGl.TimerFlag == FALSE )
	{
		s_stGl.TimerFlag = TRUE;
		PostMessage( hWnd,TIMER_LOOP_CONV,0,0 );
	}
}


//======================================================
//		高精度タイマーを停止します
//======================================================
static void TimerStop( HWND hWnd, UINT &id)
{
	TIMECAPS	caps;
	
	if( id != 0 )
	{
		timeKillEvent( id );
		id = 0;
		timeGetDevCaps( &caps,sizeof(caps) );
		timeEndPeriod( caps.wPeriodMin );
		
	}
}


//==================================================
//		オープンファイルダイアログを呼び出す		
//==================================================
static	Bool	OpenGetFileName( HWND hWnd )
{
	TCHAR		buf[MAX_PATH], drive[_MAX_DRIVE], cDir[_MAX_DIR];
	TCHAR		Title[] = TEXT("参照");
	TCHAR		szFilter[] = TEXT("Macro Files(*.*)\0*.swb\0");
	FILESELECT	fs;
	
	
	fs.hWnd = hWnd;
	fs.szTitle = Title;
	fs.szFullPathName = buf;
	fs.szFilter = szFilter;
	fs.DefFilename = NULL;
	
	if( FILE_GetOpenFile(fs) == FALSE )	return	FALSE;
	
	STRING_cpy( s_stGl.ScriptPath, buf );
	
	// カレントディレクトリを移動
	FILE_split( s_stGl.ScriptPath, drive, cDir, NULL, NULL );
	FILE_merge( buf, drive, cDir, NULL, NULL );
	FILE_SetCurrentDirectory( buf );
	
	SetWindowText( s_stGl.hScriptPath, s_stGl.ScriptPath );
	Read_SWriterBatch( s_stGl.ScriptPath );
	
	return	TRUE;
}


//********************************************************************************************
/**
 * @brief		sectionの取得.
 * @author		N.Takeda
 * @date		2010/09/15(水) 01:01:12
 *
 * @param[in]	LPCTSTR	_pPtr	検証バッファポインタ.
 *
 * @return		Int32	0:なし 1:スクリプト 2:ファイル
 */
//********************************************************************************************
static	Int32	get_section( LPCTSTR _pPtr )
{
	const	Int32	STRING_MAX = 32;
	Int32		ii;
	TCHAR	sTemp[ STRING_MAX ];
	
	
	if(*_pPtr != '[')	return	0;
	_pPtr++;
	
	ii = 0;
	while(*(_pPtr+ii) != ']' && *(_pPtr+ii) != 0 && ii<STRING_MAX){
		sTemp[ii] = *(_pPtr+ii);
		ii++;
	}
	sTemp[ii] = 0;
	
	STRING_ToBig( sTemp );
	
	if( STRING_cmp( sTemp, TEXT("SCRIPT")) == 0 )	return	1;
	if( STRING_cmp( sTemp, TEXT("FILES")) == 0 )	return	2;
	
	
	return 0;
}


/// 文字列から　コマンドとパラメータに分ける (★ezParamに統一できるはず)
static	void	GetCommandParam( SCRIPT_STAT *pSStat, xstring sString ){
	xstring::iterator	it;
	
	
	it = sString.begin();
	
	pSStat->sCommand.clear();
	pSStat->sParam.clear();
	
	while( it != sString.end() && *it!=' ' && *it!='\t' && *it!='\r' && *it!='\n' )
	{
		TCHAR	cCh = *it;
		
		if( cCh >= 'a' && cCh <= 'z' )	cCh = cCh - ('a'-'A');
		
		pSStat->sCommand.append( 1, cCh );
		it++;
	}
	
	if( it != sString.end() )
	{
		while( it != sString.end() && (*it==' ' || *it=='\t') )	it++;
	}

	if( it != sString.end() )
	{
		while( it != sString.end() && *it!='\r' && *it!='\n' )
		{
			pSStat->sParam.append( 1, *it );
			it++;
		}
	}
	
}

/// バッチファイル内のスクリプトをセット
static	void	set_script( LPCTSTR _pPtr, Int32 _iLen )
{
	SCRIPT_STAT	SStat;
	xstring		sString;
	Int32			ii;
	
	
	if( s_stGl.bFuntion_lock )	return;
	
	ii = 0;
	while( ii < _iLen )
	{
		sString.clear();
		
		while( ii<_iLen && *(_pPtr + ii)!='\r' && *(_pPtr + ii)!='\n' )
		{
			sString.append( 1, *(_pPtr + ii++) );
		}
		GetCommandParam( &SStat, sString );
		
		while( ii<_iLen && (*(_pPtr + ii)=='\r' || *(_pPtr + ii)=='\n') )	ii++;
		
		s_stGl.m_stScrStat.push_back( SStat );
	}
	
#ifdef DEBUG_OUT_BATCMD
	DEBUG_printf(TEXT("batcmd.txt"),TEXT("Commands %s\r\n"), s_stGl.ScriptPath );
	for(LScriptStat::iterator it = s_stGl.m_stScrStat.begin() ; it != s_stGl.m_stScrStat.end() ; it++)
	{
		DEBUG_printf(TEXT("batcmd.txt"),TEXT("%s(%s)\r\n"), it->sCommand.c_str(), it->sParam.c_str() );
	}
#endif
	
}


Bool FileReadUpdate( void *_pParam )
{
	WINDOW_INFO	*pWin = (WINDOW_INFO*)_pParam;
	
/*	
{
	SendMessage( s_stGl.hFlist,LB_RESETCONTENT,0,0 );
}
	List_show();
*/
	Int32	iEntry = s_stGl.m_cXcopy.GetEntry();
	TCHAR	str[32];
	wsprintf( str, TEXT("Entry : %3d"), iEntry );
	SetWindowText( s_stGl.hEntry, str );
	
//	UpdateWindow( pWin->m_hWnd );
	WINDOW_Update( *pWin, SW_SHOW );
	
	return FALSE;
}

//**************************************************************
//		バッチファイルからファイルリストを得る
//**************************************************************
static	void	get_files( LPCTSTR _pPtr, Int32 len )
{
	Int32					ii, jj, idx, entry;
	TCHAR				temp[ _MAX_PATH ];
	
	
	/// 数を調べる
	ii = entry = 0;
	idx = -1;
	while( ii < len )
	{
		jj = 0;
		while( ii < len )
		{
			if( *(_pPtr+ii) == '\r' || *(_pPtr+ii) == '\n' )	break;
#ifndef	_UNICODE
			if( _ismbblead(*(_pPtr+ii)) != 0 )	temp[jj++] = *(_pPtr+ii++);
#endif
			temp[jj++] = *(_pPtr+ii++);
		}
		temp[jj] = 0;
		while( (*(_pPtr+ii) == '\r' || *(_pPtr+ii) == '\n' || *(_pPtr+ii) == '\t') && ii<len)	ii++;
		
		
		s_stGl.m_cXcopy.SetUpdateFunc( FileReadUpdate, &s_cWin, 60 );
		
		s_stGl.m_cXcopy.AddXcopy( temp );
	}
}


#if 0
//--------------------------------------------------------------
//		小文字に
//			-option を除外するバージョン
//--------------------------------------------------------------
void	filt_small2big( LPTSTR _pPtr, DWORD length, char strch )
{
	Int32			ii,ff;
	
	
	ff = 1;
	for(ii=0 ; ii<(Int32)length ; ii++){
		if(*(_pPtr+ii) == strch)	ff = 1 - ff;
		if(*(_pPtr+ii) == '-')		while(*(_pPtr+ii-1) != '\n' && ii<(Int32)length)	ii++;	//	-オプションは小文字化しない
		
		if(ff == 1){
#ifndef	_UNICODE
			if( _ismbblead(*(_pPtr+ii)) != 0)
				ii++;
			else
#endif
			if(*(_pPtr+ii) >= 'a' && *(_pPtr+ii) <= 'z')	*(_pPtr+ii) -= ('a' - 'A');
		}
	}
	
}
#endif


//********************************************************************************************
/**
 * @brief		SWriterバッチを読み込む
 * @author		N.Takeda
 *
 * @param[in]	LPCTSTR	_pFName	名.
 *
 * @return		Bool	TRUE:成 / FALSE:否
 */
//********************************************************************************************
Bool	Read_SWriterBatch( LPCTSTR _pFName )
{
	TCHAR		*pMem = NULL;
	Int32		ii, iScLen, iLen;
	
	
	/// バッチファイル読む
	iLen = MEM_TextRead( &pMem, _pFName );
	if(iLen == 0)
	{	/// バッチファイルが存在しない場合はコマンドと判断
	/*	
		SCRIPT_STAT	SStat;
		
		SStat.sCommand.clear();
		SStat.sParam.clear();
		
		SStat.sCommand = _pFName;
		
		s_stGl.m_stScrStat.push_back( SStat );
	*/	
		return FALSE;
	}
	
	/// 注釈削除
	iLen = FILT_deleteREM( pMem, iLen, TEXT("//"), TEXT("/*"), TEXT("*/"), '\"' );

//	/// 小文字->大文字(-option を除外する特殊)
//	filt_small2big( pMem,iLen,'\"');			///< 弊害しかないので廃止. N.Takeda 2010/09/15
	
	read_profile_batch( pMem, iLen );
	
	{
		//! 環境変数を展開.
		TCHAR	sEnv[ 256 ];
		Int32	jj = 0, iTempLen = 0;
		TCHAR	*pTemp = NULL;
		
		mem_alloc( TCHAR, pTemp, iLen * 3 );
		ii = 0;
		while( ii < iLen )
		{
			if( *(pMem+ii) == '%' )
			{
				ii++;
				while( ii < iLen && ('0' <= *(pMem+ii) && *(pMem+ii) <= '9' || 'A' <= *(pMem+ii) && *(pMem+ii) <= 'Z' || 'a' <= *(pMem+ii) && *(pMem+ii) <= 'z' || *(pMem+ii) == '_') && *(pMem+ii) != '%' )
				{
					sEnv[ jj++ ] = *(pMem+ii++);
				}
				sEnv[ jj ] = '\0';
				
				if( ENV_GetStr( pTemp + iTempLen, 256, sEnv, TRUE ) )
				{
					iTempLen += STRING_len(pTemp);
				}else{
					*(pTemp + iTempLen++) = '%';
					STRING_cpy( pTemp + iTempLen, sEnv );
					iTempLen += STRING_len(sEnv);
				}
			//	ii++;
				continue;
			}
			*(pTemp + iTempLen++) = *(pMem+ii++);
		}
		*(pTemp + iTempLen) = '\0';
		
		del_alloc( pMem );
		iLen = iTempLen;
		pMem = pTemp;
	}
	
	ii = 0;
	while( ii < iLen )
	{
		switch( get_section( pMem + ii ) )
		{
			case 1:	///< [SCRIPT]
				
				while( ii < iLen && *(pMem+ii) != ']' )
				{
#ifndef	_UNICODE
					if( _ismbblead(*(pMem+ii)) != 0 )	ii++;
#endif
					ii++;
				}
				if(*(pMem+ii) == ']')	ii++;
				while(*(pMem+ii) < ' ')	ii++;
				iScLen = 0;
				while( ii+iScLen < iLen && *(pMem+ii+iScLen) != '[' )
				{
#ifndef	_UNICODE
					if( _ismbblead(*(pMem+ii+iScLen)) != 0)	iScLen++;
#endif
					iScLen++;
				}
				while( iScLen>0 && (*(pMem+ii+iScLen-2)=='\r' || *(pMem+ii+iScLen-1)=='\n') )	iScLen -= 2;
				
				set_script( pMem+ii, iScLen );
				
				break;
			
			case 2:	///< [FILES]
				
				while( ii < iLen && *(pMem+ii) != ']' )
				{
#ifndef	_UNICODE
					if( _ismbblead(*(pMem+ii)) != 0 )	ii++;
#endif
					ii++;
				}
				if(*(pMem+ii) == ']')	ii++;
				while(*(pMem+ii) < ' ')	ii++;
				iScLen = 0;
				while( ii+iScLen < iLen && *(pMem+ii+iScLen) != '[' )
				{
#ifndef	_UNICODE
					if( _ismbblead(*(pMem+ii+iScLen)) != 0)	iScLen++;
#endif
					iScLen++;
				}
				
				get_files( pMem+ii, iScLen );
				
				break;
			default:
				ii++;
		}
	}
	
	del_alloc( pMem );
	
	Message_script();
	
	return TRUE;
}


//==================================================
//		エラーメッセージ表示						
//==================================================
void	Message_error( LPCTSTR format, ... )
{
	#define		MESSAGE_ERRORLENGTH	(1024)
	TCHAR	str[MESSAGE_ERRORLENGTH];
	va_list	args;
	
	va_start( args,format );
//	vsprintf_s( str, MESSAGE_ERRORLENGTH, format, args );
	_vsntprintf_s( str, MESSAGE_ERRORLENGTH, format, args );
	va_end( args );
	
	Message_win( str );
	s_stGl.iErrors++;
}


//==================================================
//		メッセージ表示								
//==================================================
void	Message_printf( LPCTSTR format, ... )
{
	TCHAR	str[MESSAGE_1MAX];
	va_list	args;
	
	va_start( args,format );
//	vsprintf_s( str,MESSAGE_1MAX,format,args );
	_vsntprintf_s( str, MESSAGE_1MAX, format, args );
	va_end( args );
	
	Message_win( str );
}


//********************************************************************************************
/**
 * @brief		メッセージ表示.
 * @author		N.Takeda
 * @date		2011/05/17(火) 10:49:16
 *
 * @param[in]	LPCTSTR	_pStr	文字列.
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	Message_win( LPCTSTR _pStr )
{
	const Int32	iTextBoxBuffSize = 30000;
	const TCHAR	sCrlf[] = TEXT("\r\n");
	
	Int32			iLen;
	Int32			iStrlen = STRING_len( _pStr ) * sizeof(TCHAR);
	
	if( iStrlen < 256 )	iStrlen = 256;
	
	T_ASSERT( s_stGl.m_memMsg );
	
	if( STRING_len(s_stGl.m_memMsg) > s_iMIsize - MESSAGE_1MAX )
	{
		/// 容量オーバー時.
		TCHAR	*pMem = NULL;
		
		mem_alloc( TCHAR, pMem, s_iMIsize + MESSAGEINFO_SIZE );
		BUF_copy( pMem, s_stGl.m_memMsg, s_iMIsize * sizeof(TCHAR) );
		mem_del(s_stGl.m_memMsg);
		
		s_stGl.m_memMsg = pMem;
		
		s_iMIsize += MESSAGEINFO_SIZE;
		TRACE( TEXT("バッファサイズを更新(%d)\n"), s_iMIsize );
	}
	
	/// バッファへ文字列の追加.
	STRING_cat( s_stGl.m_memMsg, _pStr );
	STRING_cat( s_stGl.m_memMsg, sCrlf );
	
	/// ボックスへ文字列の追加.
	iLen = SendMessage( s_stGl.hInfo, WM_GETTEXTLENGTH, 0, 0 );
	if( iTextBoxBuffSize - iStrlen < iLen )
	{
		/// テキストボックスのバッファをオーバーしそうな時、先頭を削る.
		TCHAR	sWork[ iTextBoxBuffSize ];
		GetWindowText( s_stGl.hInfo,  sWork, sizeof(sWork) );
		
		Int32	ii = 0;
		for( ii = iStrlen ; ii<iTextBoxBuffSize ; ii++ )
		{
			if( '\r' == sWork[ ii ] && '\n' == sWork[ ii+1 ] )	break;
		}
		if( ii < iTextBoxBuffSize )
		{
			ii += 2;													///< 改行の分.
		}else{
			sWork[ 0 ] = '\0';
			ii = 0;
		}
		SendMessage( s_stGl.hInfo, EM_SETSEL, 0, -1 );
		SendMessage( s_stGl.hInfo, EM_REPLACESEL, 0, (LPARAM)(&sWork[ ii ]) );
	}
	
	SendMessage( s_stGl.hInfo, EM_SETSEL, iLen, iLen );					///< 終端を選択して追加しないと動作中にスクロールバーを操作された時に末尾に付かない.
	SendMessage( s_stGl.hInfo, EM_REPLACESEL, 0, (LPARAM)_pStr );
	SendMessage( s_stGl.hInfo, EM_REPLACESEL, 0, (LPARAM)sCrlf );
	
//	SendMessage( s_stGl.hInfo, EM_SCROLL, SB_LINEDOWN,0 );
	
	UpdateWindow(s_stGl.hInfo);
}


//==================================================
//		メッセージクリア
//==================================================
void	Message_clear()
{
	T_ASSERT( s_stGl.m_memMsg );
	
	SendMessage( s_stGl.hInfo,WM_SETTEXT,0,(LPARAM)(LPCTSTR)"" );
	UpdateWindow(s_stGl.hInfo);
	
	s_stGl.m_memMsg[0] = 0;
	
}


//********************************************************************************************
/**
 * @brief		スクリプト名を表示.
 * @author		N.Takeda
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	Message_script()
{
	TCHAR	cTemp[ 1024 ];
	
	if( !s_stGl.m_stScrStat.empty() )
	{
		for(LScriptStat::iterator it = s_stGl.m_stScrStat.begin() ; it != s_stGl.m_stScrStat.end() ; it++)
		{
			wsprintf(cTemp, TEXT("%s %s"), it->sCommand.c_str(), it->sParam.c_str() );
			Message_win( cTemp );
		}
	}
	
}


/// パスからファイル名のみを取り出す
LPCTSTR	pickup_name( LPCTSTR _pp )
{
	TCHAR	cDrive[_MAX_DRIVE], cDir[_MAX_DIR];
	
	FILE_split( _pp, cDrive, cDir, NULL, NULL);
	
	return (_pp + STRING_len(cDrive) + STRING_len(cDir));
}


static	void	set_messagepath( LPTSTR path )
{
	TCHAR	cDrive[_MAX_DRIVE],cDir[_MAX_DIR];
	
	FILE_split( path,cDrive,cDir,NULL,NULL);
	FILE_merge( s_stGl.MessagePath,cDrive,cDir,NULL,NULL);
}


//********************************************************************************************
/**
* @brief		メッセージ内容出力
* @author		N.Takeda
*
* @param[in,out]	LPTSTR	_pOutName	名
*
* @return		なし (none)
*/
//********************************************************************************************
static	void	out_infomessage( LPTSTR _pOutName )
{
	TCHAR		cPath[ _MAX_PATH ], cDrive[ _MAX_DRIVE ], cDir[ _MAX_DIR ], cName[ _MAX_FNAME ], temp[ _MAX_FNAME ];
	T_ASSERT( s_stGl.m_memMsg );
	
	
	FILE_split( s_stGl.ScriptPath, NULL, NULL, cName, NULL );
	FILE_split( s_stGl.MessagePath, cDrive, cDir, NULL, NULL );
	
	if( _pOutName[ 0 ] != 0 )	///< 出力ファイル名を指定
	{
		if( *(_pOutName + 1) == ':' )	STRING_cpy( cPath, _pOutName );	///< フルパス.
		else							FILE_merge( cPath, cDrive, cDir, _pOutName, NULL );
		
		FILE_TextWrite( cPath, s_stGl.m_memMsg );
	}else{	//出力先指定なし
		STRING_cpy( temp, TEXT("res_") );
		STRING_cat( temp, cName );
		
		FILE_merge( cPath, cDrive, cDir, temp, TEXT(".txt") );
		FILE_TextWrite( cPath, s_stGl.m_memMsg );
	}
	
}




//==============================================================================================================================
//		その他
//==============================================================================================================================

//********************************************************************************************
/**
 * @brief		file_backup関数
 * @author		N.Takeda
 * @date		2009/08/14(金) 19:48:06
 *
 * @param[in]	LPCTSTR	_pFName	名
 *
 * @return		Bool	TRUE:成 / FALSE:否
 */
//********************************************************************************************
Bool	file_backup( LPCTSTR _pFName )
{
	TCHAR		cWork[_MAX_PATH], cDrive[_MAX_DRIVE], cDir[_MAX_DIR], cName[_MAX_FNAME], cExt[_MAX_EXT];
	
	
	if( FILE_GetFileSize(_pFName) > 0 )		///< ファイルが既に存在
	{
		if( s_stGl.m_pOption->m_bBackup == 1 )
		{
			/// バックアップ作成
			FILE_split( _pFName, cDrive, cDir, cName, cExt );
			if( s_stGl.m_pOption->m_sBackupPath[ 0 ] != 0 ){
				FILE_merge( cWork, NULL, s_stGl.m_pOption->m_sBackupPath, cName, cExt );
			}else
				FILE_merge( cWork, cDrive, cDir, cName, TEXT(".bak") );
			
			if( FILE_GetFileSize(cWork) > 0 )	FILE_delete(cWork);	///< 既に同名のバックアップファイルがある場合は消去
			if( FILE_rename( _pFName, cWork ) == -1 )				///< ファイルのリネーム
			{
				Message_printf( TEXT("%s\nバックアップファイルが作成できません"), _pFName );
				return TRUE;
			}
		}else{
			wsprintf( cWork, TEXT("%s\n既にファイルが存在します。上書きしますか？"), _pFName );
			switch( MessageBox( s_cWin.m_hWnd, cWork, TEXT("問い合わせ"), MB_YESNOCANCEL ) )
			{
				case IDYES:
					break;
				case IDNO:
					return TRUE;
				case IDCANCEL:
					s_stGl.bFlagStop = TRUE;
					return TRUE;
			}
		}
	}
	
	return FALSE;
}

//********************************************************************************************
/**
 * @brief		ファイルを出力
 *				m_bBackupフラグがセットしてあればバックアップをとる
 *
 * @author		N.Takeda
 * @date		2009/08/14(金) 14:55:00
 *
 * @param[in]		LPCTSTR	_pFName	名
 * @param[in,out]	char*	_pPtr	ポインタ
 * @param[in]		Int32	_iSize	サイズ
 *
 * @return		Bool	TRUE:成 / FALSE:否
 */
//********************************************************************************************
Bool	file_targetwrite( LPCTSTR _pFName, char *_pPtr, Int32 _iSize )
{
	TCHAR		cPath[_MAX_PATH], cDrive[_MAX_DRIVE], cDir[_MAX_DIR], cName[_MAX_FNAME], cExt[_MAX_EXT];
	TCHAR		cWork[ 256 ];
	Bool		bRes;
	
	
	if( _iSize == 0 )
	{
		Message_error( TEXT("OutFileSize zero.%s"), pickup_name(_pFName) );
		return FALSE;
	}
	
	if( file_backup( _pFName ) )	return FALSE;
	
	bRes = FILE_TargetWrite( _pFName, _pPtr, _iSize );
	if(bRes == 0)
	{
		/// ファイルが書き込めなかったらフォルダを作成してみる
		FILE_MakeDirectory(_pFName);
		
		/// もう一度
		bRes = FILE_TargetWrite( _pFName, _pPtr, _iSize );
		if( bRes == 0 )
		{
			if( _pFName[1] != ':' )
			{
				/// それでも書けない、しかし相対パス指定だった場合はバッチファイルからのフルパスを作成
				FILE_split( s_stGl.ScriptPath, NULL, cDir, NULL, NULL );
				FILE_split( _pFName, cDrive, cWork, cName, cExt );
				STRING_cat( cDir, cWork );
				FILE_merge( cPath, cDrive, cDir, cName, cExt );
				FILE_MakeDirectory( cPath );
				bRes = FILE_TargetWrite( cPath, _pPtr, _iSize );
			}
			if( bRes == 0 )
				Message_error( TEXT("Can't write file.%s"), pickup_name(_pFName) );
		}
	}
	
	return bRes;
}


//********************************************************************************************
/**
* @brief		file_textwrite関数
* @author		N.Takeda
* @date		2009/08/14(金) 19:48:02
*
* @param[in]	LPCTSTR	_pFName	名
* @param[in]	LPCTSTR	_pPtr	ポインタ
*
* @return		Bool	TRUE:成 / FALSE:否
*/
//********************************************************************************************
Bool	file_textwrite( LPCTSTR _pFName, LPCTSTR _pPtr )
{
	TCHAR		cPath[_MAX_PATH], cDrive[_MAX_DRIVE], cDir[_MAX_DIR], cName[_MAX_FNAME], cExt[_MAX_EXT];
	TCHAR		cWork[ 256 ];
	Bool		bRes;
	
	
	if( STRING_len( _pPtr ) == 0 )
	{
		Message_error( TEXT("OutFileSize zero.%s"), pickup_name(_pFName) );
		return FALSE;
	}
	
	if( file_backup( _pFName ) )	return FALSE;
	
	bRes = FILE_TextWrite( _pFName, _pPtr );
	if(bRes == 0)
	{
		/// ファイルが書き込めなかったらフォルダを作成してみる
		FILE_MakeDirectory(_pFName);
		
		/// もう一度
		bRes = FILE_TextWrite( _pFName, _pPtr );
		if( bRes == 0 )
		{
			if( _pFName[1] != ':' )
			{
				/// それでも書けない、しかし相対パス指定だった場合はバッチファイルからのフルパスを作成
				FILE_split( s_stGl.ScriptPath, NULL, cDir, NULL, NULL );
				FILE_split( _pFName, cDrive, cWork, cName, cExt );
				STRING_cat( cDir, cWork );
				FILE_merge( cPath, cDrive, cDir, cName, cExt );
				FILE_MakeDirectory( cPath );
				bRes = FILE_TextWrite( cPath, _pPtr );
			}
			if( bRes == 0 )
				Message_error( TEXT("Can't write file.%s"), pickup_name(_pFName) );
		}
	}
	
	return bRes;
}


//		
void	defaultpath( LPTSTR saki, LPCTSTR moto )
{
	TCHAR		cDrive[_MAX_DRIVE], cDir[_MAX_DIR], cName[_MAX_FNAME], cExt[_MAX_EXT];
	
	
	if(moto[1] == ':'){	//	フルパス
		STRING_cpy( saki, moto );
	}else{
		FILE_split( moto, NULL, NULL, cName, cExt );
		FILE_split( s_stGl.ScriptPath, cDrive, cDir, NULL, NULL );
		
		FILE_merge( saki, cDrive, cDir, cName, cExt );
	}
	
}


//********************************************************************************************
/**
 * @brief		外部モジュール実行
 * @author		N.Takeda
 * @date		2008/5/14
 *
 * @param[in]	LPCTSTR	_pCommand		コマンド文字列.
 * @param[in]	LPCTSTR	_sParamString	パラメータ文字列.
 *
 * @return		BOOL	TRUE:成 / FALSE:否
 */
//********************************************************************************************
BOOL	swriter_ExecModule( LPCTSTR _pCommand, LPCTSTR _sParamString )
{
	xstring	sWork;
	
#ifdef PROCESS_NO_WAIT
	/// プロセス終了を待たないバージョン.
	sWork = _pCommand;
	sWork += " " + _sParamString;
	
	if(WinExec( (char*)sWork.c_str(), SW_SHOW) < 32)
	{
		sWork = APP_NAME;
		sWork += " ";
		sWork += _pCommand;
		
		if(WinExec( (char*)sWork.c_str(), SW_SHOW) < 32)
		{
			Message_error("Can't exec module. \"%s\" ", (char*)sWork.c_str() );	///< エラー.
		}else{
			/// swriterバッチを実行した場合は処理を終了.
			s_stGl.err = 1;
		}
		
	}
#else
	STARTUPINFO			si;
	PROCESS_INFORMATION	pi;
	BOOL				bRes;
	
	ZeroMemory( &si, sizeof( STARTUPINFO ));
	si.cb          = sizeof( STARTUPINFO );
	si.dwFlags     = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_SHOWNORMAL;
	
	bRes = FALSE;
	
	sWork = _pCommand;
	sWork += TEXT(" ");
	sWork += _sParamString;
	
	bRes = CreateProcess( NULL,
		(LPTSTR)sWork.c_str(),	///< コマンドライン文字列.
		NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
	
	if( bRes == FALSE )
	{
		sWork = s_stGl.MainPath;
		sWork += APP_NAME;
		sWork += TEXT(" ");
		sWork += _pCommand;
		
		bRes = CreateProcess( NULL,
			(LPTSTR)sWork.c_str(),	///< コマンドライン文字列.
			NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
	}
	
	if( bRes )
	{
		Message_printf( TEXT("Process. %s"), _pCommand );
		
		/// スレッドハンドルは使わないので即座に開放.
		CloseHandle(pi.hThread);
		
		/// 起動したプロセスの終了を待つ.
		WaitForSingleObject( pi.hProcess, INFINITE );
		
		/// プロセスハンドルを開放.
		CloseHandle(pi.hProcess);
		
#if 0
		/// swriterバッチ実行は全ファイルに対して行わない.
		s_stGl.m_iIdx = (int)s_stGl.m_cXcopy.GetEntry() - 1;
#endif
	}else{
		Message_error( TEXT("Can't exec module. \"%s\""), sWork.c_str() );	///< エラー.
	}
	
#endif
	return TRUE;
}


//********************************************************************************************
/**
 * @brief		ポインタと全角文字を比較(マルチバイト互換用)
 * @author		N.Takeda
 * @date		2009/08/14(金) 18:30:49
 *
 * @param[in]	LPCTSTR	_pPtr	ポインタ
 * @param[in]	WCHAR	_cCh	
 *
 * @return		Bool	TRUE:成 / FALSE:否
 */
//********************************************************************************************
Bool	wchar_cmp( LPCTSTR _pPtr, WCHAR _cCh )
{
#ifdef	_UNICODE
	return ( *(_pPtr) == _cCh );
#else
	return ( *(WORD*)(_pPtr) == swap_word(_cCh) );
#endif
}


//********************************************************************************************
/**
 * @brief		オプションをテンプバッファに展開.
 * @author		N.Takeda
 * @date		2011/12/06(火) 17:05:51
 *
 * @param[in]		LPCTSTR		_pSection	セクション名.
 * @param[in,out]	LPTSTR		_pSwb		追加出力バッファ.
 * @param[in]		const Int32	_iSwbSize	バッファサイズ.
 * @param[in]		LPCTSTR		_pCommLine	コマンドライン文字列ポインタ.
 * @param[in]		LPCTSTR		_pOption	オプション文字列(-を含む).
 *
 * @return		Bool	TRUE:成 / FALSE:否
 */
//********************************************************************************************
Bool	catTempScript( LPCTSTR _pSection, LPTSTR _pSwb, const Int32 _iSwbSize, LPCTSTR _pCommLine, LPCTSTR _pOption )
{
	Int32	ii = 0, iStart;
	Bool	bInnerString = FALSE;
	Bool	bResult = FALSE;
	TCHAR	cTemp[ 64 ];
	
	
	LPTSTR	pPtr = STRING_str( _pCommLine, _pOption );
	if( !pPtr )	return FALSE;
	
	STRING_printf( cTemp, 64, TEXT("[%s]\r\n"), _pSection );
	
	pPtr += 2;
	STRING_cat( _pSwb, cTemp );
	
	iStart = ii = STRING_len( _pSwb );
	while( !(*pPtr == '-' && !bInnerString) && *pPtr != 0 && ii < _iSwbSize )
	{
		if( *pPtr == '\"' && *(pPtr-1) != '\\' )
			bInnerString = 1 - bInnerString;
		else if( *pPtr == '\"' && *(pPtr-1) == '\\' )
		{
			ii--;
			_pSwb[ ii++ ] = *pPtr;
		}else if( *pPtr == ';' )
		{
			_pSwb[ ii++ ] = '\r';
			_pSwb[ ii++ ] = '\n';
		}else
			_pSwb[ ii++ ] = *pPtr;
		pPtr++;
	}
	while( ii > 1 && _pSwb[ ii-1 ] <= ' ' )	ii--;
	_pSwb[ ii ] = '\0';
	if( _pSwb[ iStart ] == '"' && _pSwb[ ii-1 ] == '"' )	//!< 前後が " で括られていたら "を消去.
	{
		_pSwb[ ii-1 ] = '\0';
		BUF_copy( &_pSwb[ iStart ], &_pSwb[ iStart+1 ], (ii-iStart)*sizeof(TCHAR) );
	}
	
	STRING_cat( _pSwb, TEXT("\r\n") );
	
	return TRUE;
}


//********************************************************************************************
/**
 * @brief		引数に直にスクリプトを指定している時、テンプファイルに展開する.
 * @author		N.Takeda
 * @date		2011/11/17(木) 14:25:57
 *
 * @param[in]	LPCTSTR	_pCmdLine	コマンドライン引数.
 *
 * @return		Bool	TRUE:成 / FALSE:否
 */
//********************************************************************************************
Bool	MakeTempScript( LPCTSTR _pCmdLine )
{
	#define	SWB_BUFFMAX	(1024 * 2)
	
	TCHAR	cSwb[ SWB_BUFFMAX ];
	
	_zero( cSwb );
	
	catTempScript( TEXT("script"), cSwb, SWB_BUFFMAX, _pCmdLine, TEXT("-s") );
	catTempScript( TEXT("files"), cSwb, SWB_BUFFMAX, _pCmdLine, TEXT("-f") );
	catTempScript( TEXT("setting"), cSwb, SWB_BUFFMAX, _pCmdLine, TEXT("-o") );
	
	if( cSwb[ 0 ] != '\0' )
	{
		FILE_GetCurrentDirectory( c_sTempSwbPath );
		catyen( c_sTempSwbPath );
		STRING_cat( c_sTempSwbPath, c_sTempSwbName );
		
		FILE_delete( c_sTempSwbPath );
		FILE_stream( c_sTempSwbPath, cSwb );
		
		STRING_cpy( s_stGl.ScriptPath, c_sTempSwbPath );
		
		/// 固定される設定.
		s_stGl.m_pOption->m_bAuto = TRUE;						///< 自動起動.
		s_stGl.m_pOption->m_bAtExit = TRUE;						///< 　自動起動後自動終了.
		
		return TRUE;
	}
	return FALSE;
}


//==============================================================================================================================
//		範囲限定機能
//==============================================================================================================================

//********************************************************************************************
/**
 * @brief		コンストラクタ
 * @author		N.Takeda
 * @date		2009/08/14(金) 18:25:05
 *
 * @return		なし (none)
 */
//********************************************************************************************
CRANGE_CTRL::CRANGE_CTRL()
 : m_bMode( FALSE )
 , m_bSwitch( FALSE )
{
	
}

//********************************************************************************************
/**
 * @brief		範囲指定初期化
 *				グローバルの s_stGl.m_pOption->m_iRange を参照している
 * @author		N.Takeda
 * @date		2009/08/14(金) 18:25:03
 *
 * @param[in]	LPCTSTR	_mem	
 * @param[in]	Int32	_iLen	長さ
 *
 * @return		なし (none)
 */
//********************************************************************************************
void	CRANGE_CTRL::Init( LPCTSTR _mem, Int32 _iLen )
{
	Int32		ii, flg;
	
	/// 内部変数初期化
	m_bSwitch = FALSE;
	
	
	m_bMode = FALSE;		///< 判定なし
	if( s_stGl.m_pOption->m_iRange == 0 )	return;		///< 範囲限定なし
	m_bMode = TRUE;		///< 判定する
	if( s_stGl.m_pOption->m_iRange == 1 )	return;		///< 範囲を限定する
	
	/// 記号含み限定
	flg = 0;
	for( ii=0 ; ii<_iLen ; ii++ )
	{
		if( wchar_cmp( _mem + ii, RANGECHAR_TOP ) && wchar_cmp( _mem + ii + sizeof(TCHAR), RANGECHAR_TOP ) ){
			flg |= 1;	///< 開始記号がある
		}else if( wchar_cmp( _mem + ii, RANGECHAR_BOTTOM ) && wchar_cmp( _mem + ii + sizeof(TCHAR), RANGECHAR_BOTTOM ) ){
			flg |= 2;	///< 終了記号がある
		}
		if(flg == 3)	break;
	}
	/// 開始記号、終了記号共になければ
	if(flg != 3)	m_bMode = FALSE;	///< 判定なし
	
}

//********************************************************************************************
/**
 * @brief		範囲指定判別
 * @author		N.Takeda
 * @date		2009/08/14(金) 18:24:59
 *
 * @param[in]	LPCTSTR	_mem	
 * @param[in]	Int32	_ii		
 * @param[in]	Int32	_iLen	長さ
 *
 * @return		Bool	TRUE:成 / FALSE:否
 */
//********************************************************************************************
Bool	CRANGE_CTRL::Is( LPCTSTR _mem, Int32 _ii, Int32 _iLen )
{
	
	if( m_bMode == FALSE )	return FALSE;	///< 判定なし
	if( _ii+5 >= _iLen )	return FALSE;
	
	if( m_bSwitch == 0 )
	{
		if( wchar_cmp(_mem + _ii, RANGECHAR_TOP ) && wchar_cmp(_mem + _ii + sizeof(TCHAR), RANGECHAR_TOP ) ){
			m_bSwitch = TRUE;
			return FALSE;
		}
		return TRUE;
	}else{
		if( wchar_cmp(_mem + _ii, RANGECHAR_BOTTOM ) && wchar_cmp(_mem + _ii + sizeof(TCHAR), RANGECHAR_BOTTOM ) ){
			m_bSwitch = FALSE;
		}
	}
	return FALSE;
}

