#include "BaseForm.h"
#include "SqlCmdForm.h"
#include "SearchObjForm.h"

#include <fstream>
#include <Windows.h>
#include "ReaderClass/CreateDBCmdClass.h"
#include "ObjectDataFile/ObjectDataBaseFile.h"
#include "ViewForm.h"
#include "CopyObjForm.h"
#include "StringForm.h"
#include "SelectAbilityForm.h"
#include "SelectMoveForm.h"
#include "ShowDataForm.h"
#include "BatchUpdateForm.h"
#include "DataExportForm.h"
#include <stack>;

using namespace ObjDataEdit;
using namespace NSObjectDataFile;
using namespace DevExpress::XtraTreeList;
using namespace DevExpress::XtraTreeList::Nodes;
using namespace System::Windows::Forms;
//------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------
ReaderClass< DB_GameObjDbStruct >* BaseForm::ObjReader( )
{
	return NULL;
}
//------------------------------------------------------------------------------------------------------------
bool    BaseForm::CheckModifyAndCheckOut()
{
	if( _OnUpdate_DataToDisplay == true )
	{
		return false;
	}


    if( _OnUpdate_DataToDisplay == false && CB_Lock->Checked == false )
    {
		_Update_DataToDisplay = true;
		int Result = 0;
		Result = MessageBox::Show( "是否要鎖定資料,(Yes)鎖定" , "警告" , MessageBoxButtons::YesNo );
		if( Result != DialogResult::Yes )
        {
            return false;
        }
        Lock_Click( );
        if( CB_Lock->Checked == false )
        {
            return false;
        }

		return false;
    }
    return true;
}
Void BaseForm::GetStr_TextChanged(System::Object *  sender, System::EventArgs *  e)
{
    if( CheckModifyAndCheckOut() == false )
        return;

    if( CB_Lock->Checked == true )
        _ObjDB.IsModify = true;

    TextBox* Edit = static_cast<TextBox*>(sender);
    DB_GameObjDbStruct __pin *Data = &_ObjDB;

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    String* Tag = static_cast<String*>(Edit->Tag);

    if( Edit->Text->Length != 0 ) 
    {
		Reader->WriteStr( Data , DotNetStr::StringToChar( Tag ).c_str() , DotNetStr::StringToChar( Edit->Text).c_str() );
    }
    else
        Reader->WriteStr( Data , DotNetStr::StringToChar( Tag ).c_str() , "" );

    _OnValueChange = true;
}
//------------------------------------------------------------------------------------------------------------
Void BaseForm::GetValue_ValueChanged(System::Object *  sender, System::EventArgs *  e)
{
    if( CheckModifyAndCheckOut() == false )
        return;

    if( CB_Lock->Checked == true )
        _ObjDB.IsModify = true;

    NumericUpDown* Edit = static_cast<NumericUpDown*>(sender);
    DB_GameObjDbStruct __pin *Data = &_ObjDB;

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    String* Tag = static_cast<String*>(Edit->Tag);

    Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , float( Edit->Value ) );

    _OnValueChange = true;
}
//------------------------------------------------------------------------------------------------------------
Void BaseForm::ChangeFlag(System::Object *  sender, System::EventArgs *  e)
{
    if( CheckModifyAndCheckOut() == false )
        return;

    CheckedListBox* CBox = static_cast<CheckedListBox*>(sender);

    if( CB_Lock->Checked == true )
        _ObjDB.IsModify = true;

    int Flag = 0;
    for( int i = CBox->Items->Count -1  ; i >= 0 ; i -- )
    {
        Flag *= 2;
        if( CBox->GetItemChecked( i ) == true )
            Flag++;
    }

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    String* Tag = static_cast<String*>(CBox->Tag);

    DB_GameObjDbStruct __pin *Data = &_ObjDB;

    Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , Flag );

    _OnValueChange = true;
}
//------------------------------------------------------------------------------------------------------------
Void BaseForm::GetIndex_SelectedIndexChanged(System::Object *  sender, System::EventArgs *  e)
{
    if( CheckModifyAndCheckOut() == false )
        return;

    if( CB_Lock->Checked == true )
        _ObjDB.IsModify = true;

    ComboBox* Box = static_cast<ComboBox*>(sender);
    DB_GameObjDbStruct __pin *Data = &_ObjDB;

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    String* Tag = static_cast<String*>(Box->Tag);

    Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , Box->SelectedIndex );

    _OnValueChange = true;
}
//------------------------------------------------------------------------------------------------------------
Void BaseForm::GetItemKey_SelectedIndexChanged(System::Object *  sender, System::EventArgs *  e)
{
	if( CheckModifyAndCheckOut() == false )
		return;

	if( CB_Lock->Checked == true )
		_ObjDB.IsModify = true;

	ComboBox* Box = static_cast<ComboBox*>(sender);
	DB_GameObjDbStruct __pin *Data = &_ObjDB;

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	
	String* Tag = static_cast<String*>(Box->Tag);
	//String* Value = Box->SelectedItem->ToString();

	ComboBoxItem* pItem = (ComboBoxItem*)Box->SelectedItem;

	Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , pItem->m_Key );

	_OnValueChange = true;
}

//------------------------------------------------------------------------------------------------------------
Void BaseForm::GetValue_CheckChanged(System::Object *  sender, System::EventArgs *  e)
{
	if( CheckModifyAndCheckOut() == false )
		return;

	if( CB_Lock->Checked == true )
		_ObjDB.IsModify = true;

	CheckBox* Box = static_cast<CheckBox*>(sender);
	DB_GameObjDbStruct __pin *Data = &_ObjDB;

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	String* Tag = static_cast<String*>(Box->Tag);

	Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , int( Box->Checked ) );

	_OnValueChange = true;
}
//------------------------------------------------------------------------------------------------------------
Void BaseForm::GetFloatValue_TextChanged(System::Object *  sender, System::EventArgs *  e)
{
    if( CheckModifyAndCheckOut() == false )
        return;

    if( CB_Lock->Checked == true )
        _ObjDB.IsModify = true;

    TextBox* Edit = static_cast<TextBox*>(sender);
    DB_GameObjDbStruct __pin *Data = &_ObjDB;

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    String* Tag = static_cast<String*>(Edit->Tag);

    if( Edit->Text->Length != 0 ) 
    {
		float Value = DotNetStr::StringToFloat( Edit->Text);

        Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , Value );
    }
    else
		Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , 0 );

    _OnValueChange = true;
}
Void BaseForm::GetIntValue_TextChanged(System::Object *  sender, System::EventArgs *  e)
{
	if( CheckModifyAndCheckOut() == false )
		return;

	if( CB_Lock->Checked == true )
		_ObjDB.IsModify = true;

	TextBox* Edit = static_cast<TextBox*>(sender);
	DB_GameObjDbStruct __pin *Data = &_ObjDB;

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	String* Tag = static_cast<String*>(Edit->Tag);
	if( Tag != NULL || Tag->Length == 0 )
	{
		//Tag = String::Copy( Tag );
		if( Tag->Chars[0] == '#' )
		{
			Tag = Tag->Remove( 0 , 1 );
		}
	}

	if( Edit->Text->Length != 0 ) 
	{
		int Value = DotNetStr::StringToInt( Edit->Text);

		Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , Value );
	}
	else
		Reader->Write( Data , DotNetStr::StringToChar( Tag ).c_str() , 0 );

	_OnValueChange = true;
}
//------------------------------------------------------------------------------------------------------------
Void BaseForm::BaseForm_Closing(System::Object *  sender, System::ComponentModel::CancelEventArgs *  e)
{
    if( _IsExit == false )
    {
        e->Cancel = true;
        this->Visible = false;
        
    }
    //UnLockAndSave( );
	if( CB_Lock->Checked == true )
	{
		sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1} and LockAccount='{2}'" , (String*)_DBName , __box(_ObjGUID) , _Account );
		sqlCommand_Base->ExecuteReader()->Close();        
	}


}
//############################################################################################################
void    BaseForm::UndoData( )
{
    _ObjDB.IsModify = 0;
    //資料更新
    //_Update_ObjList = true;
	_Update_SelectObj = true;
};
//############################################################################################################
void    BaseForm::UpDate_DataToDisplay( )
{
    _OnUpdate_DataToDisplay = true;

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    map<string,ReadInfoStruct>*             ReadInfo ;
    map<string,ReadInfoStruct>::iterator    Iter;

    ReadInfo = Reader->ReadInfo();
    ComboBox* CBox;
    CheckedListBox *  CModeFlag;
	CheckBox* ChkBox;
	NumericUpDown *NumBox;

    DB_GameObjDbStruct __pin * TempObj = &_ObjDB;

	TB_ObjGUID->Text = String::Format( "{0}" , __box( TempObj->GameData.GUID ) );

    for(    Iter  = ReadInfo->begin() ; 
        Iter != ReadInfo->end() ; 
        Iter++  )
    {
        ReadInfoStruct *IDData = &(Iter->second);
        string Temp = Iter->first;
        Control* Edit = (GetEditByTagName ( this , Iter->first.c_str() )) ;

        if( Edit == NULL )
            continue;

		String*  TagStr  = static_cast<String*>( Edit->Tag );
        CBox = NULL;
        CModeFlag = NULL;
		ChkBox = NULL;
		NumBox = NULL;

        if( Edit->GetType()->GUID == __typeof( ComboBox )->GUID )
        {
            CBox = static_cast<ComboBox*> (Edit) ;
        }
        else if( Edit->GetType()->GUID == __typeof( CheckedListBox )->GUID )
        {
            CModeFlag = static_cast<CheckedListBox*> (Edit) ;
        }
		else if( Edit->GetType()->GUID == __typeof(CheckBox)->GUID )
		{
			ChkBox =  static_cast<CheckBox*> (Edit) ;
		}
		else if( Edit->GetType()->GUID == __typeof(NumericUpDown)->GUID )
		{
			NumBox =  static_cast<NumericUpDown*> (Edit) ;
		}

        switch(IDData->Type)
        {
        case ENUM_Type_FloatPoint:
            {
                float Value = *((float*)(IDData->Point + int(TempObj)));
                Edit->Text = String::Format("{0}" , __box( Value ) );
            }
            break;

        case ENUM_Type_IntPoint:
            {
                int Value = *((int*)(IDData->Point + int(TempObj)));
                unsigned UValue = *((unsigned*)(IDData->Point + int(TempObj)));
                if( CModeFlag != NULL )
                {
                    SetCheckListBoxFlag( CModeFlag , Value );
                }
                else if( CBox != NULL && CBox->DropDownStyle == ComboBoxStyle::DropDownList )   
                {
					Object* obj  = CBox->Items->get_Item(0);
					if (obj->GetType() == __typeof(ComboBoxItem))
					{
						for (int i = 0 ; i < CBox->Items->Count ;i ++)
						{
							ComboBoxItem* cbdata = static_cast<ComboBoxItem*>(CBox->Items->get_Item(i));
							if (cbdata->m_Key == UValue)
								CBox->SelectedItem = cbdata;
						}

					}
					else if( CBox->Items->Count > UValue )
						CBox->SelectedIndex = UValue;
				}
				else if( NumBox != NULL )
				{
					if( NumBox->Minimum > Value )
						NumBox->Minimum = Value;
					else if( NumBox->Maximum < Value )
						NumBox->Maximum = Value;
					NumBox->Value = Value;
				}
                else
				{
					if( TagStr->Chars[0] == '#' )
					{
						//Edit->Text = String::Format("0x{0,08:x}" , __box( UValue ) );
						Edit->Text = String::Format("0x{0:x}" , __box( UValue ) );
//						if( UValue == 0 )
//							Edit->BackColor = Color::White();
//						else
//							Edit->BackColor = Color::Color( );

					}
					else
					{
						Edit->Text = String::Format("{0}" , __box( Value ) );
					}                    
				}
            }
            break;

        case ENUM_Type_ShortPoint:
            {
                int Value = *((short*)(IDData->Point + int(TempObj)));
                Edit->Text = String::Format("{0}" , __box( Value ) );

            }                
            break;
        case ENUM_Type_CharString:
        case ENUM_Type_TextData:
            {
                char* Str = (char*)(IDData->Point + int(TempObj));
                Edit->Text = Str;
            }    
			break;
		case ENUM_Type_CharStringPoint:
		case ENUM_Type_TextDataPoint:
			{
				char* Str = *(char**)(IDData->Point + int(TempObj));
				Edit->Text = Str;
			}
            break;
		case ENUM_Type_BitPoint:
			{
				bool Value = *((bool*)(IDData->Point + int(TempObj)));
				ChkBox->Checked = Value;
				//ChkBox->Checked = true;
			}
			break;


        }

		BaseForm::OnLoadTagData( TagStr, IDData->Type, (PVOID)(IDData->Point + int(TempObj) ) );
    }
    _OnUpdate_DataToDisplay = false;
    _OnValueChange = true;
}
//############################################################################################################
void BaseForm::OnLoadTagData( String* Tag, ReadInfoTypeENUM Type, PVOID pData )
{
	if( String::Equals( Tag, "DirZoneID" ) == true )
	{
		int Value = *((int*)(pData));

		int iTotal = CB_DirZoneID->Items->Count;

		for( int i=0; i < iTotal; i++ )
		{
			ComboBoxItem* pItem = (ComboBoxItem*)CB_DirZoneID->Items->get_Item(i);

			if( pItem->m_Key == Value )
			{
				CB_DirZoneID->SelectedItem = CB_DirZoneID->Items->get_Item(i);
				break;
			}
		}
	}
	else if( String::Equals( Tag, "DirVersionID" ) == true )
	{
		int Value = *((int*)(pData));

		int iTotal = CB_DirVersionID->Items->Count;

		for( int i=0; i < iTotal; i++ )
		{
			ComboBoxItem* pItem = (ComboBoxItem*)CB_DirVersionID->Items->get_Item(i);

			if( pItem->m_Key == Value )
			{
				CB_DirVersionID->SelectedItem = CB_DirVersionID->Items->get_Item(i);
				break;
			}
		}
	}
	else if( String::Equals( Tag, "DirTagID" )  == true )
	{
		int Value = *((int*)(pData));

		int iTotal = CB_DirTagID->Items->Count;

		for( int i=0; i < iTotal; i++ )
		{
			ComboBoxItem* pItem = (ComboBoxItem*)CB_DirTagID->Items->get_Item(i);

			if( pItem->m_Key == Value )
			{
				CB_DirTagID->SelectedItem = CB_DirTagID->Items->get_Item(i);
				break;
			}
		}

	}
}
//############################################################################################################
void    BaseForm::UpDateList( )
{
	int     i;
	int     SelectID = 0;
	SqlDataReader* myReader;
	/*
	if( CB_UseSQL->Checked == true )        
	sqlCommand_Base->CommandText = String::Format( "SELECT {0}.GUID, StringDB.Content, {0}.DataGroup FROM {0} , StringDB {1}" , (String*)_DBName , TB_WhereSQLCmd->Text );
	else
	sqlCommand_Base->CommandText = String::Format( "SELECT {0}.GUID, StringDB.Content, {0}.DataGroup FROM {0} , StringDB WHERE {0}.GUID = StringDB.OrgObjID AND StringDB.KeyStr LIKE 'Sys%[_]name' ORDER BY {0}.GUID" , (String*)_DBName  );
	*/		
	int Index = CB_SelectType->SelectedIndex;
	if( TB_WhereSQLCmd->Text->Length == 0 && Index != 0 )
		Index = 3;

	switch( Index )
	{
	case 0:
		{
			int LanguageSetting = Global::LanguageSetting();
			if( LanguageSetting == -1 )
			{
				sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.[Content], n.DataGroup FROM {0} AS n INNER JOIN StringDB AS s ON n.GUID = s.OrgObjID WHERE (s.KeyStr LIKE 'Sys%[_]name') AND (n.OutputLanguage & 15 <> 0) ORDER BY   n.GUID" , (String*)_DBName  );
			}
			else
			{
				sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.[Content], n.DataGroup FROM {0} AS n INNER JOIN StringDB AS s ON n.GUID = s.OrgObjID WHERE (s.KeyStr LIKE 'Sys%[_]name') AND (n.OutputLanguage & {1} != 0) ORDER BY  n.GUID" , (String*)_DBName , __box( LanguageSetting ) );				
			}
		}
		break;
	case 1://使用名稱
		sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.[Content], n.DataGroup FROM {0} AS n INNER JOIN  StringDB AS s ON n.GUID = s.OrgObjID WHERE (RIGHT(s.KeyStr, 5) = '_name') AND (s.[Content] LIKE '%{1}%') ORDER BY n.GUID", (String*)_DBName , TB_WhereSQLCmd->Text);
		//sqlCommand_Base->CommandText = String::Format( "SELECT {0}.GUID, StringDB.Content, {0}.DataGroup FROM {0} , StringDB WHERE {0}.GUID = StringDB.OrgObjID AND StringDB.KeyStr LIKE 'Sys%[_]name' AND StringDB.Content LIKE '%{1}%' ORDER BY {0}.GUID" , (String*)_DBName , TB_WhereSQLCmd->Text );
		break;
	case 2://始用SQL
		sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.Content, n.DataGroup from {0} AS n INNER JOIN StringDB AS s ON n.GUID = s.OrgObjID {1}" , (String*)_DBName , TB_WhereSQLCmd->Text );
		break;
	case 3:
	default://不使用
		sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.Content, n.DataGroup from {0} n inner join StringDB s on n.GUID = s.OrgObjID where right(keystr,5) = '_name' order by n.guid" , (String*)_DBName  );
		break;
	}
	myReader = sqlCommand_Base->ExecuteReader();

	_ObjList->clear();
	while( myReader->Read())
	{
		DB_GameObjDbIndexStruct Temp;
		Temp.GUID = myReader->GetInt32( 0 );
		String* Str =  myReader->GetString( 1 ) ;
		strcpy( Temp.Name , DotNetStr::StringToChar( Str ).c_str() );

		Str =  myReader->GetString( 2 ) ;
		strcpy( Temp.DataGroup , DotNetStr::StringToChar( Str ).c_str() );

		_ObjList->push_back( Temp );
	}
	myReader->Close();	
	//-------------------------------------------------------------------------------------
	//更新顯示資料
	//-------------------------------------------------------------------------------------
	LB_ObjList->BeginUpdate();

	while( (int)_ObjList->size() >  LB_ObjList->Items->Count )
	{
		LB_ObjList->Items->Add( S"" );
	}

	while( LB_ObjList->Items->Count > (int)_ObjList->size() )
	{
		LB_ObjList->Items->RemoveAt( _ObjList->size() );
	}


	//找到物件位置
	for ( i = 0 ; i < (int)_ObjList->size() ; i++ )
	{
		String* Str = String::Format("{0,5} {1}", __box( (*_ObjList)[i].GUID ) , (String*)( (*_ObjList)[i].Name ) );

		LB_ObjList->Items->Item[i] = Str;

		//if( (*_ObjList)[i].GUID == _ObjGUID )
		//	SelectID = i;
	}
	if( _ObjList->size() != 0 )
	{
		LB_ObjList->SelectedIndex  = LB_ObjList->FindString(_ObjGUID.ToString());
	}
	LB_ObjList->EndUpdate();
	//-------------------------------------------------------------------------------------
	//找 Treeview 的 Node					
	//-------------------------------------------------------------------------------------
	//找到的父Node的String以FILO方式儲存至ArrayList，使用Treelist的FindNodeByFieldValue找到Node並展開
	if (_ObjGUID != -1)
	{
		int	NodeID=_ObjGUID;
		sqlCommand_Base->CommandText = String::Format("SELECT n.GUID, s.[Content], n.NodeID FROM {0} AS n INNER JOIN  StringDB AS s ON n.GUID = s.OrgObjID WHERE (RIGHT(s.KeyStr, 5) = '_name') AND (n.GUID = {1})",(String*)_DBName, __box(NodeID));
		myReader = sqlCommand_Base->ExecuteReader();
		myReader->Read();
		NodeID	= myReader->GetInt32( 2 );
		myReader->Close();
		//vector<Object*> NodeStack;
		ArrayList* NodeStack = new ArrayList;
		do 
		{
			sqlCommand_Base->CommandText = String::Format("SELECT ParentNodeID, NodeID FROM ObjGroupTreeNodeDB WHERE (UseDB = '{0}') AND (NodeID = {1})",(String*)_DBName,  __box(NodeID));
			myReader = sqlCommand_Base->ExecuteReader();
			while (myReader->Read())
			{
				NodeStack->Insert(0, __box(myReader->GetInt32( 1 )));
				NodeID = myReader->GetInt32( 0 );
			}			
			myReader->Close();
		}while (NodeID != -1);
		String* col = "ColName";
		IEnumerator* objMyEnum = NodeStack->GetEnumerator();
		while (objMyEnum->MoveNext())
		{
			TreeListNode* FindtreeNode = treeList1->FindNodeByKeyID(objMyEnum->get_Current());
			if( FindtreeNode != NULL )
			{
				FindtreeNode->set_Expanded(true);
			}
		}
		treeList1->SetFocusedNode(treeList1->FindNodeByFieldValue( col , LB_ObjList->Text ));
	}  

	LB_ObjCount->Text = String::Format( "筆數:{0}" , __box(LB_ObjList->Items->Count) );
}
//############################################################################################################
bool	BaseForm::ReadObj_ByGUID( int GUID )
{
	char	Buf[4096];
	int		i;
	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	map<string,ReadInfoStruct>*             ReadInfo ;
	map<string,ReadInfoStruct>::iterator    Iter;

	ReadInfo = Reader->ReadInfo();
	sprintf( Buf , "WHERE GUID = %d" , GUID );
	CreateDBCmdClass<DB_GameObjDbStruct> CreateCMD( Reader  , _DBName );
	sqlCommand_Base->CommandText = CreateCMD.GetSelectStr( Buf ).c_str();
	SqlDataReader* myReader = sqlCommand_Base->ExecuteReader( );


	DB_GameObjDbStruct __pin * TempObj = &_ObjDB;
	DB_GameObjDbStruct __pin * TempObj_Backup = &_ObjDB_Backup;
	TempObj->Init( );
	if( myReader->Read( ) )
	{
		for(    Iter  = ReadInfo->begin() , i = 0 ; 
			Iter != ReadInfo->end() ; 
			Iter++ , i++ )
		{
			ReadInfoStruct *IDData = &(Iter->second);
			string Str = Iter->first;

			switch(IDData->Type)
			{
			case ENUM_Type_BinaryData:
				{
					char utf8 __gc[] = myReader->GetSqlBinary(i).Value;   
					char __pin *charStr = &utf8[0];
					memcpy( (char*)(IDData->Point + int(TempObj)) , charStr , IDData->Size );
					memcpy( (char*)(IDData->Point + int(TempObj_Backup)) , charStr , IDData->Size );

				}
				break;
			case ENUM_Type_FloatPoint:
				{
					*((float*)(IDData->Point + int(TempObj))) = myReader->GetFloat( i );
					*((float*)(IDData->Point + int(TempObj_Backup))) = myReader->GetFloat( i );
				}
				break;

			case ENUM_Type_IntPoint:
				{
					*((int*)(IDData->Point + int(TempObj))) = myReader->GetInt32( i );
					*((int*)(IDData->Point + int(TempObj_Backup))) = myReader->GetInt32( i );
				}
				break;

			case ENUM_Type_ShortPoint:
				{
					*((short*)(IDData->Point + int(TempObj))) = myReader->GetInt16( i );
					*((short*)(IDData->Point + int(TempObj_Backup))) = myReader->GetInt16( i );
				}                
				break;
			case ENUM_Type_BitPoint:
				{
					*((bool*)(IDData->Point + int(TempObj))) = myReader->GetBoolean( i );
					*((bool*)(IDData->Point + int(TempObj_Backup))) = myReader->GetBoolean( i );
				}
				break;
			case ENUM_Type_CharString:
			case ENUM_Type_TextData:
				{
					String* Str = myReader->GetString( i ) ;
					strcpy( (char*)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Str ).c_str() );
					strcpy( (char*)(IDData->Point + int(TempObj_Backup)) , DotNetStr::StringToChar( Str ).c_str() );
				}    
				break;
			case ENUM_Type_CharStringPoint:
			case ENUM_Type_TextDataPoint:
				{
					//此欄位不處理
					i--;
				}
				break;
			case ENUM_Type_TimeCharString:
				{
					DateTime TempDate = myReader->GetDateTime( i );
					String* Tt= String::Format( "{0}:{1}:{2}" 
						, __box( TempDate.get_Hour() )
						, __box( TempDate.get_Minute() )
						, __box( TempDate.get_Second() ) );

					Tt =  String::Format( "{0} {1} " , TempDate.ToString( "d" ) , Tt );
					strcpy( (char*)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Tt ).c_str() );
					strcpy( (char*)(IDData->Point + int(TempObj_Backup)) , DotNetStr::StringToChar( Tt ).c_str() );

				}
				break;
			}
		}   
	}//if( myReader->Read( ) )
	else
	{
		return false;
	}

	myReader->Close( );

	//讀取字串資料
	//更新所有的字串資料
	char* OutStr;
	char* OutStr_Backup;

	for(    Iter  = ReadInfo->begin() ; 
		Iter != ReadInfo->end() ; 
		Iter++  )
	{
		ReadInfoStruct *IDData = &(Iter->second);
		string Tempstr = Iter->first;
		switch(IDData->Type)
		{
		case ENUM_Type_CharString:
		case ENUM_Type_TextData:
			continue;			
		case ENUM_Type_CharStringPoint:
		case ENUM_Type_TextDataPoint:			
			OutStr = *(char**)(IDData->Point + int(TempObj));
			OutStr[0] = 0;

			OutStr_Backup = *(char**)(IDData->Point + int(TempObj_Backup));
			OutStr_Backup[0] = 0;
			break;
		default:
			continue;
		}

		char KeyStr[256];
		sprintf( KeyStr , "Sys%d_%s" , TempObj->GameData.GUID , Iter->first.c_str() );
		
		//檢查資料是否有更新
		sprintf( Buf , "SELECT Content FROM StringDB WHERE KeyStr = '%s' " , KeyStr );  
		sqlCommand_Base->CommandText = Buf;
		myReader  = sqlCommand_Base->ExecuteReader();   
		while( myReader->Read( ) )			
		{
			String* Str = myReader->GetString( 0 );
			strcpy( OutStr , DotNetStr::StringToChar( Str ).c_str() );		
			strcpy( OutStr_Backup , DotNetStr::StringToChar( Str ).c_str() );		
		}
		myReader->Close();
		
	}
	return true;
}

bool	 BaseForm::SelectObj_byGUID( int GUID , bool NeedUpdate  )
{
	for( unsigned i = 0 ; i < _ObjList->size() ; i++ )
	{
		if( (*_ObjList)[i].GUID == GUID )
		{
			SelectObj( i , NeedUpdate );
			return true;
		}
	}
	return false;
}

void    BaseForm::SelectObj( int ID , bool NeedUpdate )
{
	
    Global::CritSect.Enter();

	int		Index = ID;
    char	Buf[4096];

	if( Index < 0 || Index >= (int)_ObjList->size() )
		return;

	SqlDataReader* myReader;

    if( _ObjDB.IsModify != 0 )
    {
		_ObjDB.IsModify = 0;

		int Result = MessageBox::Show( "是否儲存,(Yes)儲存" , "警告" , MessageBoxButtons::YesNo );        
        if( Result == DialogResult::Yes )
        {			
            UnLockAndSave( );
			_ObjGUID = (*_ObjList)[Index].GUID;

        }
		else
		{
			sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1} and LockAccount='{2}'" , (String*)_DBName , __box(_ObjGUID) , _Account );
			sqlCommand_Base->ExecuteReader()->Close();        
		}
		CB_Lock->Checked = false;
    }
    else if( IsLock() == true &&  _ObjGUID != (*_ObjList)[Index].GUID )
    {
		sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1} and LockAccount = '{2}'" , (String*)_DBName , __box(_ObjGUID) , _Account );
        sqlCommand_Base->ExecuteReader()->Close();        
    }
    CB_Lock->Checked = false;
    _ObjDB.IsModify = 0;
	_ObjGUID = (*_ObjList)[Index].GUID;
	ReadObj_ByGUID( _ObjGUID );

	if( NeedUpdate == false )
	{
		Global::CritSect.Leave();
		return;
	}
    //----------------------------------------------------------------------------------------------
    //更新所有的資料
    UpDate_DataToDisplay();
    //----------------------------------------------------------------------------------------------
    _OnUpdate_DataToDisplay = true;

    sprintf( Buf , " 最近修改 帳號:%s 日期:%s " , _ObjDB.LastModifyAccount , _ObjDB.LastModifyDate );
    LB_LastModify->Text = Buf;

    if( _ObjDB.IsLock )
    {
        if( String::Compare( _ObjDB.LockAccount , _Account , true ) == 0 )
        {
            CB_Lock->Checked = true;
            CB_Lock->Text = "(可修改)你已經鎖定資料";
            OnSelectObj( true );
            panel5_Base->BackColor = System::Drawing::SystemColors::Control;            
        }
        else
        {
			CB_Lock->Checked = false;
            sprintf( Buf , " (不可修改)資料被 %s 鎖定 " , _ObjDB.LockAccount );
            CB_Lock->Text = Buf;
            OnSelectObj( false );
            panel5_Base->BackColor = System::Drawing::SystemColors::Highlight ;
        }      
    }
    else
    {
		//(撿察是否有人索定)
		DB_GameObjDbStruct __pin * TempObj = &_ObjDB;
		sqlCommand_Base->CommandText = String::Format( "Select GUID from {0}  WHERE GUID = {1} and IsLock = 0 " , (String*)_DBName , __box(_ObjGUID)  );
		myReader = sqlCommand_Base->ExecuteReader();        
		if( myReader->HasRows == true )
		{            
			myReader->Close();
			sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 1 , LockAccount = '{1}' Where GUID = {2}" , (String*)_DBName , _Account , __box(_ObjGUID) );
			sqlCommand_Base->ExecuteReader()->Close();
			strncpy( (TempObj->LockAccount) , DotNetStr::StringToChar( _Account ).c_str() , sizeof(_ObjDB.LockAccount) );
			CB_Lock->Checked = true;
			_ObjDB.IsLock = true;
		}
		else
			myReader->Close();

		CB_Lock->Text = "(可修改)自動鎖定資料";
        OnSelectObj( true );
		//OnSelectObj(NULL, NULL);
		CB_Lock->Checked = true;
        panel5_Base->BackColor = System::Drawing::SystemColors::Highlight ;
    }


	//找到的父Node的String以FILO方式儲存至ArrayList，使用Treelist的FindNodeByFieldValue找到Node並展開
	int	NodeID= _ObjGUID;
	sqlCommand_Base->CommandText = String::Format("SELECT n.GUID, s.[Content], n.NodeID FROM {0} AS n INNER JOIN  StringDB AS s ON n.GUID = s.OrgObjID WHERE (RIGHT(s.KeyStr, 5) = '_name') AND (n.GUID = {1})",(String*)_DBName, __box(NodeID));
	myReader = sqlCommand_Base->ExecuteReader();
	myReader->Read();
	NodeID	= myReader->GetInt32( 2 );
	myReader->Close();
	ArrayList* NodeStack = new ArrayList(); 		
	do
	{
		sqlCommand_Base->CommandText = String::Format("SELECT ParentNodeID, NodeID FROM ObjGroupTreeNodeDB WHERE (UseDB = '{0}') AND (NodeID = {1})",(String*)_DBName,  __box(NodeID));
		myReader = sqlCommand_Base->ExecuteReader();
		while (myReader->Read())
		{
			NodeStack->Insert(0, __box(myReader->GetInt32( 1 )));
			NodeID = myReader->GetInt32( 0 );
		}			
		myReader->Close();
	}while(NodeID != -1);		
	String* col = "ColName";
	IEnumerator* objMyEnum = NodeStack->GetEnumerator();
	TreeListNode* FindtreeNode;
	while (objMyEnum->MoveNext())
	{
		FindtreeNode = treeList1->FindNodeByKeyID(objMyEnum->get_Current() );
		if( FindtreeNode != NULL )
		{
			FindtreeNode->set_Expanded(true);
		}
	}
	FindtreeNode = treeList1->FindNodeByFieldValue( col , LB_ObjList->Text );
	if(FindtreeNode != NULL)
	{
		treeList1->SetFocusedNode(FindtreeNode);		
		//顯示NodeID(供企劃使用)
		LB_NodeID->Text = String::Format("NodeID：{0}", FindtreeNode->Tag);
		LB_NodeID->Visible = true;
	}


    _OnUpdate_DataToDisplay = false;
    Global::CritSect.Leave();
}
//############################################################################################################
void    BaseForm::Lock_Click( )
{
    if( _IsReadOnly == true )
    {
		MessageBox::Show( "此帳號沒有權限修改" , "警告" );
        return;
    }

    SqlDataReader* myReader; 
    if( CB_Lock->Checked )
    {   //如果資料鎖定(做儲存)
        UnLockAndSave();
		//LoadTreeView();
		//UpDateList();
    }
    else
    {   
        sqlCommand_Base->CommandText = "BEGIN TRANSACTION";
        sqlCommand_Base->ExecuteReader()->Close();

        //(撿察是否有人索定)
        sqlCommand_Base->CommandText = String::Format( "Select GUID from {0} WITH(TABLOCKX) WHERE GUID = {1} and IsLock = 0 " , (String*)_DBName , __box(_ObjGUID)  );
        myReader = sqlCommand_Base->ExecuteReader();        

        if( myReader->HasRows == true )
        {            
            myReader->Close();
            sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 1 , LockAccount = '{1}' Where GUID = {2}" , (String*)_DBName , _Account , __box(_ObjGUID) );
            sqlCommand_Base->ExecuteReader()->Close();
            CB_Lock->Checked = true; 
			_ObjDB.IsLock = true;

			CB_Lock->Text = "(可修改)你已經鎖定資料";
			panel5_Base->BackColor = System::Drawing::SystemColors::Highlight;       
        }
        else
            myReader->Close();

		if( CB_Lock->Checked == false )
		{
			char	Buf[256];
			sprintf( Buf , "**是否要強制鎖定資料,目前鎖定者 %s (Yes)鎖定**" , _ObjDB.LockAccount );
			int Result = MessageBox::Show( Buf , "警告" , MessageBoxButtons::YesNo );
			if( Result == DialogResult::Yes )
			{
				sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 1 , LockAccount = '{1}' Where GUID = {2}" , (String*)_DBName , _Account , __box(_ObjGUID) );
				sqlCommand_Base->ExecuteReader()->Close();
				CB_Lock->Checked = true; 
				_ObjDB.IsLock = true;
				char __pin *LockAccount = &_ObjDB.LockAccount[0];

				strcpy( LockAccount , DotNetStr::StringToChar( _Account ).c_str() );

				CB_Lock->Text = "(可修改)你已經鎖定資料";
				panel5_Base->BackColor = System::Drawing::SystemColors::Highlight;       
			}
		}

		sqlCommand_Base->CommandText = "COMMIT TRANSACTION";
		sqlCommand_Base->ExecuteReader()->Close();

    }
    //資料更新
    //UpDateList( );
}
//############################################################################################################
void BaseForm::UnLockAndSave()
{
	if( CB_Lock->Checked == false )
		return;

    char Buf[0x20000];
	
    if( String::Compare( _ObjDB.LockAccount , _Account , true ) == 0 )
    {
		CB_Lock->Checked = false;
		CB_Lock->Text = "(不可修改)資料尚未鎖定";

		String* LockAccount = "";

		//檢查是否鎖定者正確
		sqlCommand_Base->CommandText = String::Format( "Select LockAccount from {0} WHERE GUID = {1} and IsLock = 1 " , (String*)_DBName , __box(_ObjGUID)  );
		SqlDataReader* myReader = sqlCommand_Base->ExecuteReader();        

		if( myReader->Read( ) )
		{
			LockAccount = myReader->GetString( 0 );
		}

		myReader->Close();

		if( LockAccount->Length != 0 && String::Compare( LockAccount , _Account , true ) != 0 )
		{			
			if( _ObjDB.IsModify  != false)
			{
				_ObjDB.IsModify = false;
				MessageBox::Show( "資料已被其他人強制鎖定，無法儲存" , "警告" );
			}
			return;
		}

		//沒修改
		if( _ObjDB.IsModify == 0  )
		{
			sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1}" , (String*)_DBName , __box(_ObjGUID)  );
			sqlCommand_Base->ExecuteReader()->Close();     
			return;
		}

        _ObjDB.IsModify = 0;

        sprintf( Buf , " Where GUID = %d" , _ObjGUID );

        DB_GameObjDbStruct __pin * TempObj = &_ObjDB;		
        //--------------------------------------------------------------------------------------
        //設定最後修正日期
        DateTime TempDate = DateTime::Now;
        String* NowStr= String::Format( "{0}:{1}:{2}" 
            , __box( TempDate.get_Hour() )
            , __box( TempDate.get_Minute() )
            , __box( TempDate.get_Second() ) );

        NowStr =  String::Format( "{0} {1} " , TempDate.ToString( "d" ) , NowStr );
        TempObj->IsLock   = false;
        TempObj->IsModify = false;

        strcpy( (char*)&TempObj->LastModifyAccount[0] , DotNetStr::StringToChar( _Account ).c_str() );

        strcpy( (char*)&TempObj->LastModifyDate[0] , DotNetStr::StringToChar( NowStr ).c_str() );
        //--------------------------------------------------------------------------------------


        CreateDBCmdClass<DB_GameObjDbStruct> CreateCMD(  ObjReader()  , _DBName );
//		CreateCMD.NoString( true );
        sqlCommand_Base->CommandText = CreateCMD.GetUpDateStr(  TempObj , Buf ).c_str();
        sqlCommand_Base->ExecuteReader( )->Close();

        sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1}" , (String*)_DBName , __box(_ObjGUID)  );
        sqlCommand_Base->ExecuteReader()->Close();        

		sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1}" , (String*)_DBName , __box(_ObjGUID)  );
		sqlCommand_Base->ExecuteReader()->Close();       



		//更新所有的字串資料
		ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
		map<string,ReadInfoStruct>*             ReadInfo ;
		map<string,ReadInfoStruct>::iterator    Iter;

		ReadInfo = Reader->ReadInfo();
		char* Str;

		for(    Iter  = ReadInfo->begin() ; 
			Iter != ReadInfo->end() ; 
			Iter++  )
		{
			ReadInfoStruct *IDData = &(Iter->second);

			switch(IDData->Type)
			{
			case ENUM_Type_CharString:
			case ENUM_Type_TextData:
//				Str = (char*)(IDData->Point + int(TempObj));
				continue;
				break;
			case ENUM_Type_CharStringPoint:
			case ENUM_Type_TextDataPoint:
				Str = *(char**)(IDData->Point + int(TempObj));
				break;
			default:
				continue;
			}

			if(     String::Compare( Iter->first.c_str() , "lastmodifyaccount" ) == 0 
				||  String::Compare( Iter->first.c_str() , "lockaccount" ) == 0 
				||  String::Compare( Iter->first.c_str() , "datagroup" ) == 0 )
			{
				continue;
			}

			//char* BinStr = StringToSqlX( Str , IDData->Size );
			string SQLStr = StringToSqlStr( Str , IDData->Size );
			char KeyStr[256];
			sprintf( KeyStr , "Sys%d_%s" , TempObj->GameData.GUID , Iter->first.c_str() );

			

			//檢查資料是否存在
			bool IsStrNotFind;
			sprintf( Buf , "SELECT COUNT(KeyStr) FROM StringDB WHERE KeyStr = '%s'" , KeyStr  );  
			sqlCommand_Base->CommandText = Buf;
			SqlDataReader* myReader  = sqlCommand_Base->ExecuteReader();   
			while( myReader->Read( ) )			
			{
				if( myReader->GetInt32( 0 ) == 0 )
					IsStrNotFind = true;
				else
					IsStrNotFind = false;		
			}
			myReader->Close();


			if( IsStrNotFind == true )
			{
				sprintf( Buf , "INSERT StringDB( KeyStr , Type  , Content, OrgObjID , Content_Editor ) VALUES(  '%s' , 1 , '%s' , %d , '%s' ) " , KeyStr , SQLStr.c_str() , _ObjGUID , _Account );  
				sqlCommand_Base->CommandText = Buf;
				sqlCommand_Base->ExecuteReader()->Close();   
			}
			else
			{
				//檢查資料是否有更新
				bool	IsStrChange = false;
				
				if( strcmp( Str , "" ) == 0 || strcmp( Str , " " ) == 0 )
				{
					//更新資料
					sprintf( Buf , "UPDATE StringDB SET UpdateTime = getdate() , IsConfirmed1 = 0 , IsConfirmed2 = 0 , IsConfirmed3 = 0 ,IsConfirmed4 = 0 , IsConfirmed5 = 0 , IsConfirmed6 = 0 , IsConfirmed7 = 0 ,IsConfirmed8 = 0 , IsConfirmed9 = 0 , IsConfirmed10 = 0 , IsConfirmed11 = 0 ,IsConfirmed12 = 0 , IsConfirmed13 = 0 , IsConfirmed14 = 0 , IsConfirmed15 = 0 , IsUpdate =1 , IsTranslated1 = 0 , IsTranslated2 = 0 , IsTranslated3 = 0 ,IsTranslated4 = 0 , IsTranslated5 = 0 , IsTranslated6 = 0 , IsTranslated7 = 0 ,IsTranslated8 = 0 , IsTranslated9 = 0 , IsTranslated10 = 0 , IsTranslated11 = 0 ,IsTranslated12 = 0 , IsTranslated13 = 0 , IsTranslated14 = 0 , IsTranslated15 = 0 ,  Content = '' , Content_Language1 = '' , Content_Language2 = '' , Content_Language3 = '' , Content_Language4 = '' , Content_Language5='',Content_Language6='',Content_Language7='',Content_Language8='' , Content_Language9 = '', Content_Language10 = '' , Content_Language11 = '' , Content_Language12 = '' , Content_Language13 = '' , Content_Language14 = '' , Content_Language15 = '' , Content_Editor = '%s'  WHERE KeyStr = '%s' " , _Account ,  KeyStr );  
					sqlCommand_Base->CommandText = Buf;
					sqlCommand_Base->ExecuteReader()->Close();   
				}
				else
				{
					sprintf( Buf , "SELECT COUNT(KeyStr) FROM StringDB WHERE KeyStr = '%s' and Content = '%s'" , KeyStr , SQLStr.c_str()  );  
					sqlCommand_Base->CommandText = Buf;
					SqlDataReader* myReader  = sqlCommand_Base->ExecuteReader();   
					while( myReader->Read( ) )			
					{
						if( myReader->GetInt32( 0 ) != 0 )
							IsStrChange = false;
						else
							IsStrChange = true;
					}
					myReader->Close();
					if( IsStrChange  )
					{
						//更新資料
						sprintf( Buf , "UPDATE StringDB SET UpdateTime = getdate() ,  IsConfirmed1 = 0 , IsConfirmed2 = 0 , IsConfirmed3 = 0 ,IsConfirmed4 = 0 , IsConfirmed5 = 0 , IsConfirmed6 = 0 , IsConfirmed7 = 0 ,IsConfirmed8 = 0 , IsConfirmed9 = 0 , IsConfirmed10 = 0 , IsConfirmed11 = 0 ,IsConfirmed12 = 0 , IsConfirmed13 = 0 , IsConfirmed14 = 0 , IsConfirmed15 = 0 , IsUpdate =1 , IsTranslated1 = 0 , IsTranslated2 = 0 , IsTranslated3 = 0 ,IsTranslated4 = 0 , IsTranslated5 = 0 , IsTranslated6 = 0 , IsTranslated7 = 0 ,IsTranslated8 = 0 , IsTranslated9 = 0 , IsTranslated10 = 0 , IsTranslated11 = 0 ,IsTranslated12 = 0 , IsTranslated13 = 0 , IsTranslated14 = 0 , IsTranslated15 = 0 , Content = '%s' ,Content_Editor = '%s' WHERE KeyStr = '%s' " , SQLStr.c_str() , _Account , KeyStr );  
						sqlCommand_Base->CommandText = Buf;
						sqlCommand_Base->ExecuteReader()->Close();   

						String* Name = String::Format( "{0} {1}" , __box( _ObjGUID ) , new String(SQLStr.c_str()) );
						String* col = "ColName";
						treeList1->FocusedNode->SetValue(col, Name);
					}
				}
			}

			//判斷字串是否翻譯
			int Translate = (int)(_ObjDB.Translate);
			if (_ObjDB.Translate)
			{  
				int FormType = TempObj->GameData.GUID / 10000;
				if (strcmp("name_plural", Iter->first.c_str()) == 0) //是複數名 
				{
					if (FormType == 21 ||	  //不需翻譯的複數
						FormType == 22 ||
						FormType == 49 ||
						FormType == 50 ||
						FormType == 42 ||
						FormType == 51 ||
						FormType == 52 ||
						FormType == 53 ||
						FormType == 54 ||
						FormType == 77 ||
						FormType == 61)
					{
						Translate = 0;
					}
				}
				if (strcmp("note", Iter->first.c_str()) == 0)
				{
					Translate = 0;
				}
				if (FormType == 70)
				{
					Translate = 0;
				}
				if (String::Compare(new String(Str), "") == 0 ||	    //空值
					String::Compare(new String(Str), "Noname") == 0)	//NoName  
				{
					Translate = 0;
				}
			}

			//修改翻譯分類
			sqlCommand_Base->CommandText =  String::Concat( String::Format( "UpDate StringDB SET DirZoneID = {0} , DirTagID = {1} , DirVersionID={2}  " 
				, __box( _ObjDB.ZoneID ) , __box( _ObjDB.TagID ) , __box( _ObjDB.VersionID )  ) 
				,String::Format( ",Translate={0} WHERE OrgObjID={1} AND KeyStr = '{2}'" , __box(Translate) , __box( _ObjDB.GameData.GUID ),  new String(KeyStr)) );		

			sqlCommand_Base->ExecuteReader()->Close();
		}	

		sprintf( Buf , "UPDATE StringDB SET OutputLanguage =%d WHERE OrgObjID =%d " , TempObj->GameData.LanguageSet , _ObjGUID );
		sqlCommand_Base->CommandText = Buf;
		sqlCommand_Base->ExecuteReader()->Close();   

		////修改翻譯分類
		//sqlCommand_Base->CommandText =  String::Concat( String::Format( "UpDate StringDB SET DirZoneID = {0} , DirTagID = {1} , DirVersionID={2}  " 
		//	, __box( _ObjDB.ZoneID ) , __box( _ObjDB.TagID ) , __box( _ObjDB.VersionID )  ) ,
		//	String::Format( ",Translate={0} WHERE OrgObjID={1}" , __box( int(_ObjDB.Translate)) , __box( _ObjDB.GameData.GUID ) ) );		

		//sqlCommand_Base->ExecuteReader()->Close();     

		CompareChangeLog( );

		AfterUpdateObj( TempObj );
    }
}
//############################################################################################################
Void BaseForm::CompareChangeLog( )
{
	DB_GameObjDbStruct __pin * TempObj			= &_ObjDB;
	DB_GameObjDbStruct __pin * TempObj_Backup	= &_ObjDB_Backup;

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	map<string,ReadInfoStruct>*             ReadInfo ;
	map<string,ReadInfoStruct>::iterator    Iter;

	ReadInfo = Reader->ReadInfo();

	for(    Iter  = ReadInfo->begin() ; 
		Iter != ReadInfo->end() ; 
		Iter++  )
	{
		ReadInfoStruct *IDData = &(Iter->second);

		String* ValueName = IDData->ValueName.c_str();
		switch(IDData->Type)
		{
		case ENUM_Type_FloatPoint:
			{
				float OrgValue = *((float*)(IDData->Point + int(TempObj_Backup)));
				float NewValue = *((float*)(IDData->Point + int(TempObj)));
				
				if( OrgValue == NewValue )
					continue;
				sqlCommand_Base->CommandText = String::Concat( String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID , OrgStr,NewStr ) VALUES ('{0}','{1}',{2}"
												, _Account , ValueName , __box( _ObjDB.GameData.GUID ) )
												, String::Format( " ,'{0}','{1}' )", __box(OrgValue) , __box(NewValue) ) );
				sqlCommand_Base->ExecuteReader()->Close();     

				OrgValue = NewValue;

			}
			break;

		case ENUM_Type_IntPoint:
			{
				int OrgValue = *((int*)(IDData->Point + int(TempObj_Backup)));
				int NewValue = *((int*)(IDData->Point + int(TempObj)));

				if( OrgValue == NewValue )
					continue;

				sqlCommand_Base->CommandText = String::Concat( String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID , OrgStr,NewStr ) VALUES ('{0}','{1}',{2}"
					, _Account , ValueName , __box( _ObjDB.GameData.GUID ) ) 
					, String::Format( " ,'{0}','{1}' )", __box(OrgValue) , __box(NewValue) ) );
				sqlCommand_Base->ExecuteReader()->Close();     
				OrgValue = NewValue;

			}
			break;

		case ENUM_Type_ShortPoint:
			{
				short OrgValue = *((int*)(IDData->Point + int(TempObj_Backup)));
				short NewValue = *((int*)(IDData->Point + int(TempObj)));

				if( OrgValue == NewValue )
					continue;

				sqlCommand_Base->CommandText = String::Concat( String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID, OrgStr , NewStr ) VALUES ('{0}','{1}',{2}"
					, _Account , ValueName , __box( _ObjDB.GameData.GUID ) ) 
					, String::Format( " ,'{0}','{1}' )", __box(OrgValue) , __box(NewValue) ) );
				sqlCommand_Base->ExecuteReader()->Close();     
				OrgValue = NewValue;

			}                
			break;	
		case ENUM_Type_TextData:
			{
				char* NewStr = (char*)(IDData->Point + int(TempObj));
				char* OrgStr = (char*)(IDData->Point + int(TempObj_Backup));

				if( strcmp( NewStr , OrgStr ) == 0 )
					continue;

				sqlCommand_Base->CommandText = String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID, OrgStr,NewStr ) VALUES ('{0}','{1}',{2},'no record','no record')"
					, _Account , ValueName , __box( _ObjDB.GameData.GUID ) );

				sqlCommand_Base->ExecuteReader()->Close();     
				strcpy( OrgStr , NewStr );		

			}
			break;
		case ENUM_Type_CharString:
			{
				char* NewStr = (char*)(IDData->Point + int(TempObj));
				char* OrgStr = (char*)(IDData->Point + int(TempObj_Backup));
			
				if( strcmp( NewStr , OrgStr ) == 0 )
					continue;

				sqlCommand_Base->CommandText = String::Concat( String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID, OrgStr,NewStr ) VALUES ('{0}','{1}',{2}"
					, _Account , ValueName , __box( _ObjDB.GameData.GUID ) ) 
					, String::Format( " ,'{0}','{1}' )", (String*)( OrgStr ) , (String*)( NewStr ) ) );

				sqlCommand_Base->ExecuteReader()->Close();     
				strcpy( OrgStr , NewStr );
			}
			break;
		case ENUM_Type_TextDataPoint:
			{
				char* NewStr = *(char**)(IDData->Point + int(TempObj));
				char* OrgStr = *(char**)(IDData->Point + int(TempObj_Backup));

				if( strcmp( NewStr , OrgStr ) == 0 )
					continue;

				sqlCommand_Base->CommandText =String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID, OrgStr,NewStr ) VALUES ('{0}','{1}',{2}　,'不紀錄','不紀錄' )"
					, _Account , ValueName , __box( _ObjDB.GameData.GUID ) );

				sqlCommand_Base->ExecuteReader()->Close();     
				strcpy( OrgStr , NewStr );
			}
			break;

		case ENUM_Type_CharStringPoint:
			{
				char* NewStr = *(char**)(IDData->Point + int(TempObj));
				char* OrgStr = *(char**)(IDData->Point + int(TempObj_Backup));
				String* GetNewStr = new String(NewStr);
				String* GetOrgStr = new String(OrgStr);
				GetNewStr = GetNewStr->Replace("'","''");
				GetOrgStr = GetOrgStr->Replace("'","''");
				if( strcmp( NewStr , OrgStr ) == 0 )
					continue;
				
				sqlCommand_Base->CommandText = String::Concat( String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID, OrgStr,NewStr ) VALUES ('{0}','{1}',{2}"
					, _Account , ValueName , __box( _ObjDB.GameData.GUID ) ) 
					, String::Format( " ,'{0}','{1}' )", GetOrgStr , GetNewStr ) );

				sqlCommand_Base->ExecuteReader()->Close();     
				strcpy( OrgStr , NewStr );
			}
			break;
		case ENUM_Type_BitPoint:
			{
				char* NewStr = (char*)(IDData->Point + int(TempObj));
				char* OrgStr = (char*)(IDData->Point + int(TempObj_Backup));

				if( memcmp( NewStr , OrgStr , IDData->Size ) == 0 )
					continue;
				sqlCommand_Base->CommandText =  String::Format( "INSERT EditLogDB( AccountID , ColumnName , OrgObjID ) VALUES ('{0}','{1}',{2})"
					, _Account , ValueName , __box( _ObjDB.GameData.GUID )  );
				sqlCommand_Base->ExecuteReader()->Close();     
				memcpy( OrgStr , NewStr , IDData->Size );
			}
			break;
		default:
			continue;
		}
	}
}
//############################################################################################################
Void BaseForm::NewObj( )
{
	for( int i = 0 ; i < NUD_CreateCount->Value ; i++ )
	{
		char	Buf[ 4096 ];
		DB_GameObjDbStruct __pin * TempObj = &_ObjDB;

		sqlCommand_Base->CommandText = String::Format( "Insert Into {0}( IsLock ) values ( 0 )" , (String*)_DBName );
		sqlCommand_Base->ExecuteReader()->Close();


		sprintf( Buf , "SELECT MAX(GUID) FROM %s " , (String*)_DBName );  
		sqlCommand_Base->CommandText = Buf;
		SqlDataReader* myReader  = sqlCommand_Base->ExecuteReader();   
		int		NewDBID = 0 ;
		while( myReader->Read( ) )			
		{
			NewDBID = myReader->GetInt32( 0 );
		}
		myReader->Close();


		//更新所有的字串資料
		ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
		map<string,ReadInfoStruct>*             ReadInfo ;
		map<string,ReadInfoStruct>::iterator    Iter;

		ReadInfo = Reader->ReadInfo();
		char* Str;

		for(Iter = ReadInfo->begin() ; Iter != ReadInfo->end() ; Iter++)
		{
			ReadInfoStruct *IDData = &(Iter->second);

			switch(IDData->Type)
			{
			case ENUM_Type_CharString:
			case ENUM_Type_TextData:
				//Str = (char*)(IDData->Point + int(TempObj));
				continue;
				break;
			case ENUM_Type_CharStringPoint:
			case ENUM_Type_TextDataPoint:
				Str = *(char**)(IDData->Point + int(TempObj));
				break;
			default:
				continue;
			}
			char KeyStr[256];
			sprintf( KeyStr , "Sys%d_%s" , NewDBID , Iter->first.c_str() );


			bool IsFindStr;
			sprintf( Buf , "SELECT COUNT(KeyStr) FROM StringDB WHERE KeyStr = '%s' " , KeyStr  );  
			sqlCommand_Base->CommandText = Buf;
			SqlDataReader* myReader  = sqlCommand_Base->ExecuteReader();   
			while( myReader->Read( ) )			
			{
				if( myReader->GetInt32( 0 ) != 0 )
					IsFindStr = true;
				else
					IsFindStr = false;
			}
			myReader->Close();

			//更新資料
			if( IsFindStr == false )
			{
				if( stricmp( "name" , Iter->first.c_str() ) == 0 )
				{
					sprintf( Buf , "INSERT INTO StringDB( Type , KeyStr ,OrgObjID, Content , Note ) VALUES ( 1 , '%s' , %d, 'Noname' , '系統物件字串' )" , KeyStr , NewDBID  );  
				}
				else
				{
					sprintf( Buf , "INSERT INTO StringDB( Type , KeyStr ,OrgObjID, Content , Note ) VALUES ( 1 , '%s' , %d, '' , '系統物件字串' )" , KeyStr , NewDBID  );  
				}
			}
			sqlCommand_Base->CommandText = Buf;
			sqlCommand_Base->ExecuteReader()->Close();   

		}	
	}

    //資料更新
	NUD_CreateCount->Value = 1;
	LoadTreeView();
    UpDateList( );

}
//############################################################################################################
void BaseForm::OutputFileLanguage( int LanguageID )
{
    int     i;

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    map<string,ReadInfoStruct>*             ReadInfo ;
    map<string,ReadInfoStruct>::iterator    Iter;

    ReadInfo = Reader->ReadInfo();

    CreateDBCmdClass<DB_GameObjDbStruct> CreateCMD( Reader  , _DBName );
	//測試
	//DWORD dw = GetTickCount();
    sqlCommand_Base->CommandText = CreateCMD.GetSelectStr( "" ).c_str();
    SqlDataReader* myReader = sqlCommand_Base->ExecuteReader( );
	//DWORD dw2 = GetTickCount();
	//#undef GetCurrentDirectory
	//String* GetDirPath = String::Format("{0}log.csv", System::IO::Directory::GetCurrentDirectory());
	
	//System::IO::File::AppendAllText(GetDirPath , "test");

	fstream file;
	if( BaseForm::OutputFile_SimplifyProcess( file , _OutputFileName , "DB"  ) == false )
	{
		return;
	}

	char	Buf[256];
    ObjFileHead FileHead;    

    FileHead.Size = ObjSize();
    FileHead.Idenitfy = DEF_ITEMOBJ_FILE_ID;
    FileHead.Count = 0;
	sprintf( Buf ,"%s %s %s %s" , _DEF_VERSION , DotNetStr::StringToChar( _Account ).c_str() , TimeStr::Now() , _DBName );
	strncpy( FileHead.FileInfoStr , Buf , sizeof(FileHead.FileInfoStr) );
    //strncpy( FileHead.FileInfoStr , _DBName , sizeof(FileHead.FileInfoStr) );
	

    file.write( (char*)&FileHead, sizeof(FileHead) );


    DB_GameObjDbStruct  TempObjDB;

    DB_GameObjDbStruct __pin * TempObj = &TempObjDB;
    TempObj->Init( );
    //---------------------------------------------------------------------------------
    //總數
    //---------------------------------------------------------------------------------
    //設定初始資訊
    //---------------------------------------------------------------------------------

    while( myReader->Read( ) )
    {
		memset( &TempObj->GameData , 0 , sizeof( TempObj->GameData ) );

        for(    Iter  = ReadInfo->begin() , i = 0 ; 
            Iter != ReadInfo->end() ; 
            Iter++ , i++ )
        {
            ReadInfoStruct *IDData = &(Iter->second);

            switch(IDData->Type)
            {
			case ENUM_Type_BinaryData:
				{
					char utf8 __gc[] = myReader->GetSqlBinary(i).Value;   
					char __pin *charStr = &utf8[0];
					memcpy( (char*)(IDData->Point + int(TempObj)) , charStr , IDData->Size );
				}
				break;
            case ENUM_Type_FloatPoint:
                {
                    *((float*)(IDData->Point + int(TempObj))) = myReader->GetFloat( i );
                }
                break;

            case ENUM_Type_IntPoint:
                {
                    *((int*)(IDData->Point + int(TempObj))) = myReader->GetInt32( i );
                }
                break;

            case ENUM_Type_ShortPoint:
                {
                    *((short*)(IDData->Point + int(TempObj))) = myReader->GetInt16( i );
                }                
                break;
			case ENUM_Type_BitPoint:
				{
					*((bool*)(IDData->Point + int(TempObj))) = myReader->GetBoolean( i );
				}                
				break;

            case ENUM_Type_CharString:
            case ENUM_Type_TextData:
                {
                    String* Str = myReader->GetString( i ) ;
					char*	szStr = (char*)(IDData->Point + int(TempObj));
                    strcpy( szStr , DotNetStr::StringToChar( Str ).c_str() );

					for( int i = strlen(szStr)-1 ; i >= 0 ; i-- )
					{
						if( szStr[i] == ' ' )
							szStr[i] =0;
						else
							break;
					}
                }    
				break;
			case ENUM_Type_CharStringPoint:
			case ENUM_Type_TextDataPoint:
				{
					//此欄不處理
					i--;

					//String* Str = myReader->GetString( i ) ;
					//strcpy( *(char**)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Str ) );
				}    
				break;
            case ENUM_Type_TimeCharString:
                {
                    DateTime TempDate = myReader->GetDateTime( i );
                    String* Tt= String::Format( "{0}:{1}:{2}" 
                        , __box( TempDate.get_Hour() )
                        , __box( TempDate.get_Minute() )
                        , __box( TempDate.get_Second() ) );

                    Tt =  String::Format( "{0} {1} " , TempDate.ToString( "d" ) , Tt );
                    strcpy( (char*)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Tt ).c_str() );

                }
                break;
            }
        }   

		FileHead.Count++;
        OnBaseOutputObjSetting( TempObj );

        file.write( (char*)&(TempObj->GameData) , FileHead.Size );
	}

	//////////////////////////////////////////////////////////////////////////
	//寫入結構資料
	//////////////////////////////////////////////////////////////////////////
	for(    Iter  = ReadInfo->begin() ; 
			Iter != ReadInfo->end() ; 
			Iter++  )
	{
		ReadInfoStruct *IDData = &(Iter->second);

		int	strLen = IDData->ValueName.length()+1;
		file.write( (char*)&( strLen ) , sizeof(int) );
		file.write( (char*)&(IDData->Point ) , sizeof(int) );
		file.write( (char*)IDData->ValueName.c_str() , strLen );		
	}

	//////////////////////////////////////////////////////////////////////////



    file.seekg( 0, ios_base::beg );
    file.write( (char*)&FileHead, sizeof(FileHead) );

    file.close();
    myReader->Close( );

	_Update_DataToDisplay = true;


	//////////////////////////////////////////////////////////////////////////
	//完成後上傳
	//////////////////////////////////////////////////////////////////////////   
// 	String* tempPath = String::Format("C:\\RuneTempData\\{0}.db", new String(_OutputFileName));
// 	String* RealPath = String::Format("{0}\\{1}.db", new String(Global::GetDataPath().c_str()), new String(_OutputFileName));
// 	if (!System::IO::Directory::Exists(new String(Global::GetDataPath().c_str())))
// 	{
// 		System::IO::Directory::CreateDirectory(new String(Global::GetDataPath().c_str()));
// 	}
// 	System::IO::File::Copy(tempPath, RealPath, true);
}
//############################################################################################################
void BaseForm::OutputStringToDB( )
{
    int     i;

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    map<string,ReadInfoStruct>*             ReadInfo ;
    map<string,ReadInfoStruct>::iterator    Iter;
    vector< DB_GameObjDbStruct >            DataList;

    ReadInfo = Reader->ReadInfo();

    CreateDBCmdClass<DB_GameObjDbStruct> CreateCMD( Reader  , _DBName );
    sqlCommand_Base->CommandText = CreateCMD.GetSelectStr( "" ).c_str();
    SqlDataReader* myReader = sqlCommand_Base->ExecuteReader( );


//    DB_GameObjDbStruct  TempObjDB;

    DB_GameObjDbStruct __pin * TempObj = &_ObjDB;
    TempObj->Init( );

    //---------------------------------------------------------------------------------

    while( myReader->Read( ) )
    {

        for(    Iter  = ReadInfo->begin() , i = 0 ; 
            Iter != ReadInfo->end() ; 
            Iter++ , i++ )
        {
            ReadInfoStruct *IDData = &(Iter->second);

            switch(IDData->Type)
            {
			case ENUM_Type_BinaryData:
				{
					char utf8 __gc[] = myReader->GetSqlBinary(i).Value;   
					char __pin *charStr = &utf8[0];
					memcpy( (char*)(IDData->Point + int(TempObj)) , charStr , IDData->Size );
				}
				break;
            case ENUM_Type_FloatPoint:
                {
                    *((float*)(IDData->Point + int(TempObj))) = myReader->GetFloat( i );
                }
                break;

            case ENUM_Type_IntPoint:
                {
                    *((int*)(IDData->Point + int(TempObj))) = myReader->GetInt32( i );
                }
                break;

            case ENUM_Type_ShortPoint:
                {
                    *((short*)(IDData->Point + int(TempObj))) = myReader->GetInt16( i );
                }                
                break;
            case ENUM_Type_CharString:
            case ENUM_Type_TextData:
                {
                    String* Str = myReader->GetString( i ) ;
                    strcpy( (char*)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Str ).c_str() );
                }    
                break;
			case ENUM_Type_CharStringPoint:
			case ENUM_Type_TextDataPoint:
				{
					//此欄不處理
					i--;
//					String* Str = myReader->GetString( i ) ;
//					strcpy( *(char**)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Str ) );
				}    
				break;
            case ENUM_Type_TimeCharString:
                {
                    DateTime TempDate = myReader->GetDateTime( i );
                    String* Tt= String::Format( "{0}:{1}:{2}" 
                        , __box( TempDate.get_Hour() )
                        , __box( TempDate.get_Minute() )
                        , __box( TempDate.get_Second() ) );

                    Tt =  String::Format( "{0} {1} " , TempDate.ToString( "d" ) , Tt );

                    strcpy( (char*)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Tt ).c_str() );

                }
                break;
            }
        }         
        OnBaseOutputObjSetting( TempObj );
		SaveString(TempObj);
        //DataList.push_back( *TempObj );
    }
    myReader->Close( );
/*
    for( int i = 0 ; i < (int)DataList.size() ; i++ )
    {
        SaveString( &DataList[i] );
    }
*/
	_Update_DataToDisplay = true;

}
//############################################################################################################
void    BaseForm::SaveString(  DB_GameObjDbStruct* TempObj )
{

    ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
    map<string,ReadInfoStruct>*             ReadInfo ;
    map<string,ReadInfoStruct>::iterator    Iter;
    char                                    Buf[ 0x20000 ];
    String*                                 TempStr;
    SqlDataReader*                          myReader;
	char*									Str;

    ReadInfo = Reader->ReadInfo();

    for(    Iter  = ReadInfo->begin() ; 
        Iter != ReadInfo->end() ; 
        Iter++  )
    {
        ReadInfoStruct *IDData = &(Iter->second);
        string Temp = Iter->first;

		
        switch(IDData->Type)
        {
        case ENUM_Type_CharString:
        case ENUM_Type_TextData:
            {
				//Str = (char*)(IDData->Point + int(TempObj));                       
				continue;
            }    
            break;
		case ENUM_Type_CharStringPoint:
		case ENUM_Type_TextDataPoint:
			{
				Str = *(char**)(IDData->Point + int(TempObj));                       
			}
			break;
		default:
			continue;
        }
//		char* BinStr = StringToSqlX( Str , IDData->Size );
		string SQLStr = StringToSqlStr( Str , IDData->Size );

		char KeyStr[256];
		sprintf( KeyStr , "Sys%d_%s" , TempObj->GameData.GUID , Iter->first.c_str() );

		sprintf( Buf , "Select Content from StringDB where KeyStr = '%s'" , KeyStr );

		sqlCommand_Base1->CommandText = Buf;

		myReader = sqlCommand_Base1->ExecuteReader();
		

		if( myReader->Read() )
		{
			TempStr =  myReader->GetString( 0 ) ;
			myReader->Close();
		}
		else
		{
			sprintf( Buf , "INSERT INTO StringDB( Type , KeyStr ,OrgObjID, Content , Note , Content_Editor ) VALUES ( 1 , '%s' , %d, '%s' , '%s' ) , '系統物件字串' )" , KeyStr , TempObj->GameData.GUID , SQLStr.c_str() , TempObj->LockAccount );  
			myReader->Close();
			sqlCommand_Base1->CommandText = Buf;
			sqlCommand_Base1->ExecuteReader()->Close();   
			continue;
		}

		if( TempStr->Compare( TempStr , Str ) != 0 )
		{
			sprintf( Buf , "UPDATE StringDB SET UpdateTime = getdate() , IsConfirmed1 = 0 , IsConfirmed2 = 0 , IsConfirmed3 = 0 ,IsConfirmed4 = 0 , IsConfirmed5 = 0 , IsConfirmed6 = 0 , IsConfirmed7 = 0 ,IsConfirmed8 = 0 , IsConfirmed9 = 0 , IsConfirmed10 = 0 , IsConfirmed11 = 0 ,IsConfirmed12 = 0 , IsConfirmed13 = 0 , IsConfirmed14 = 0 , IsConfirmed15 = 0 , IsUpdate =1 , IsTranslated1 = 0 , IsTranslated2 = 0 , IsTranslated3 = 0 ,IsTranslated4 = 0 , IsTranslated5 = 0 , IsTranslated6 = 0 , IsTranslated7 = 0 ,IsTranslated8 = 0 , IsTranslated9 = 0 , IsTranslated10 = 0 , IsTranslated11 = 0 ,IsTranslated12 = 0 , IsTranslated13 = 0 , IsTranslated14 = 0 , IsTranslated15 = 0 , Content = '%s' , Content_Editor = '%s') WHERE KeyStr = '%s' " , SQLStr.c_str() , TempObj->LockAccount , KeyStr );  
			sqlCommand_Base1->CommandText = Buf;
			sqlCommand_Base1->ExecuteReader()->Close();   
		}
    }          

}
//############################################################################################################
/*void BaseForm::OutputFileByStringTable(  )
{
	OutputFile( );
}
*/
//############################################################################################################
String* BaseForm::SearchObjName( int GUID, bool bNULL )
{
	static	map< int , string >	NameStrMap;
	char	KeyStr[256];
	char	Buf[256];
	std::string	Ret;
	String* Str;

	map< int , string >::iterator Iter = NameStrMap.find( GUID );
	if( Iter != NameStrMap.end() )
	{
		return Iter->second.c_str();
	}

	if( bNULL )
		Ret = "無";
	else
		Ret = "";

    if( GUID != 0 )
	{
		sprintf( KeyStr , "Sys%d_name" , GUID  );

		sprintf( Buf , "Select Content from StringDB where KeyStr = '%s'" , KeyStr );
		sqlCommand_Base->CommandText = Buf;
		SqlDataReader* myReader = sqlCommand_Base->ExecuteReader();

		if( myReader->Read() )
		{
			Str =  myReader->GetString( 0 ) ;
			Ret = DotNetStr::StringToChar( Str );
		}
		myReader->Close();


		NameStrMap[ GUID ] = Ret;
	}

    return Ret.c_str();
}

String* BaseForm::SearchObjName( int GUID )
{
	return SearchObjName( GUID, true );
}

//搜尋某物件的價值
int		BaseForm::SearchObjCost( int GUID )
{
	char	SqlCmd[1024];
	SqlDataReader* myReader;

	int  Ret = 0;
	if( GUID != 0 )
	{
		sprintf( SqlCmd , "Select Cost from ItemObjectDB  where GUID = %d" , GUID );
		sqlCommand_Base->CommandText = SqlCmd;
		myReader = sqlCommand_Base->ExecuteReader();

		if( myReader->Read() )
		{
			Ret =  myReader->GetInt32( 0 )/10 ;
			myReader->Close();
			return Ret;
		}
		myReader->Close();

		sprintf( SqlCmd , "Select Cost from WeaponObjectDB  where GUID = %d" , GUID );
		sqlCommand_Base->CommandText = SqlCmd;
		myReader = sqlCommand_Base->ExecuteReader();

		if( myReader->Read() )
		{
			Ret =  myReader->GetInt32( 0 )/10 ;
			myReader->Close();
			return Ret;
		}
		myReader->Close();

		sprintf( SqlCmd , "Select Cost from ArmorObjectDB  where GUID = %d" , GUID );
		sqlCommand_Base->CommandText = SqlCmd;
		myReader = sqlCommand_Base->ExecuteReader();

		if( myReader->Read() )
		{
			Ret =  myReader->GetInt32( 0 )/10 ;
			myReader->Close();
			return Ret;
		}
		myReader->Close();

		sprintf( SqlCmd , "Select Cost from RuneObjectDB  where GUID = %d" , GUID );
		sqlCommand_Base->CommandText = SqlCmd;
		myReader = sqlCommand_Base->ExecuteReader();

		if( myReader->Read() )
		{
			Ret =  myReader->GetInt32( 0 )/10 ;
			myReader->Close();
			return Ret;
		}
		myReader->Close();

		sprintf( SqlCmd , "Select Cost from TreasureObjectDB  where GUID = %d" , GUID );
		sqlCommand_Base->CommandText = SqlCmd;
		myReader = sqlCommand_Base->ExecuteReader();

		if( myReader->Read() )
		{
			Ret =  myReader->GetInt32( 0 );
			myReader->Close();
			return Ret;
		}
		myReader->Close();
	}

	return Ret;
}



void    BaseForm::SetCheckListBoxFlag( CheckedListBox* Edit , int Value )
{
    int i , Flag;
    for( i = 0 , Flag = 1 ; i < Edit->Items->Count ; i++ , Flag *=2 )
    {

        if( ( Flag & Value ) != 0)
            Edit->SetItemChecked( i , true );
        else
            Edit->SetItemChecked( i , false);
    }
}

Void BaseForm::SearchObj_DClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    for( int i = 0 ; i < EM_SearchFormTypeENUM_Unknow ; i++ )
        Info.TypeArr[i] = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}
Void BaseForm::SearchAttribute_Click(System::Object *  sender, System::EventArgs *  e)
{
	SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.Attribute = true;
	Info.Treasure = true;

	SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
	Control* ctrl = static_cast<Control*>(sender);
	Point Pos;
	Pos.X = 0;
	Pos.Y = ctrl->Size.Height;
	MU_SelectObj->Show( ctrl , Pos );
}


Void BaseForm::SearchMagicClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.MagicCollect = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}

Void BaseForm::SearchNPC_Click(System::Object *  sender, System::EventArgs *  e)
{
	SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
	Info.NPC = true;

	SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
	Control* ctrl = static_cast<Control*>(sender);
	Point Pos;
	Pos.X = 0;
	Pos.Y = ctrl->Size.Height;
	MU_SelectObj->Show( ctrl , Pos );
}

Void BaseForm::SearchMagicBaseClick(System::Object *  sender, System::EventArgs *  e)
{
	SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
	Info.Magic = true;

	SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
	Control* ctrl = static_cast<Control*>(sender);
	Point Pos;
	Pos.X = 0;
	Pos.Y = ctrl->Size.Height;
	MU_SelectObj->Show( ctrl , Pos );
}


Void BaseForm::SearchItemClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.Weapon = true;
    Info.Armor = true;
    Info.Item = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}
Void BaseForm::SearchRecipeClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.Recipe = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}
Void BaseForm::SearchCardClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.Card = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}
Void BaseForm::SearchKeyItemClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.KeyItem = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}

Void BaseForm::SearchWeaponClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.Weapon = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}
Void BaseForm::SearchArmorClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.Armor = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}
Void BaseForm::SearchSuitClick(System::Object *  sender, System::EventArgs *  e)
{
	SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
	Info.Suit = true;

	SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
	Control* ctrl = static_cast<Control*>(sender);
	Point Pos;
	Pos.X = 0;
	Pos.Y = ctrl->Size.Height;
	MU_SelectObj->Show( ctrl , Pos );
}


Void BaseForm::SearchImageClick(System::Object *  sender, System::EventArgs *  e)
{
    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.Image = true;

    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );
    Control* ctrl = static_cast<Control*>(sender);
    Point Pos;
    Pos.X = 0;
    Pos.Y = ctrl->Size.Height;
    MU_SelectObj->Show( ctrl , Pos );
}

void    BaseForm::SelectObject( System::Object *  sender )
{
    SearchObjForm::g_SearchObjForm->ShowDialog( );
    if( SearchObjForm::g_SearchObjForm->IsAccept() == false )
        return;

    TextBox* Edit = static_cast<TextBox*>(sender);

	if( Edit->ReadOnly == false)
		Edit->Text = String::Format( "{0}" , __box( SearchObjForm::g_SearchObjForm->SelectID() ) );
    
}

System::Void BaseForm::SelectSqlCmd_Click(System::Object *  sender, System::EventArgs *  e)
{
    if( _FormType == EM_SearchFormTypeENUM_Unknow )
    {
        SqlCmdForm* Form;
        Form = new SqlCmdForm();
        Form->ShowDialog();

        if( Form->IsAccept() == false )
            return;

        TB_WhereSQLCmd->Text = Form->SqlCmd();
        return;
    }


    SearchFormTypeStruct Info;
	Info.DataBaseName = _DBName;
    Info.TypeArr[ _FormType ] = true;
    SearchObjForm::g_SearchObjForm->SetViewFormInfo( Info );

    SearchObjForm::g_SearchObjForm->ShowDialogBox( _FormType );
    if( SearchObjForm::g_SearchObjForm->IsAccept() == false )
        return;

    TB_WhereSQLCmd->Text = SearchObjForm::g_SearchObjForm->SqlCmd();

}

//尋找某物件的GUID
System::Void BaseForm::SelectObjClick(System::Object *  sender, System::EventArgs *  e)
{
    SelectObject( MU_SelectObj->SourceControl );
}

//跳到所要尋找的GUID的位置
System::Void BaseForm::ViewSelectObj(System::Object *  sender, System::EventArgs *  e)
{
    TextBox* Edit = static_cast<TextBox*>( MU_SelectObj->SourceControl );

    if( SetActiveByObjGUID( DotNetStr::StringToInt( Edit->Text ) ) == false )
    {
        MessageBox::Show( "找不到此編輯物件 或 不可閱讀此物件" , "警告" );
    }
}

bool    BaseForm::ActiveSearchObjForm( int GUID )
{
	bool	Ret = false;
    sqlCommand_Base->CommandText = String::Format( "Select COUNT( GUID ) from {0} where GUID = {1}" , (String*)_DBName , __box( GUID ) );
    SqlDataReader* myReader = sqlCommand_Base->ExecuteReader();

    if( myReader->Read() )
    {
		if( myReader->GetInt32(0) == 0 )
			Ret = false;
		else 
			Ret = true;
    }
    myReader->Close();
    return Ret;
}

bool    BaseForm::SetActiveByObjGUID( int GUID )
{
    for( int i = 0 ; i < _FormList->Count ; i++ )
    {

        BaseForm* AddForm = ( __try_cast<BaseForm*> (_FormList->Item[i]  ) );
        if( AddForm->ActiveSearchObjForm( GUID ) == true )
        {			            
            AddForm->TB_WhereSQLCmd->Text = "";
			if( AddForm->Visible  )
			{
				AddForm->Focus();
				if( AddForm->IsLock() )
				{
					AddForm->_ObjDB.IsModify = false;
					AddForm->UnLockAndSave( );
				}
			}
			else
			{
				AddForm->Show();
				AddForm->Focus();
			}
			AddForm->_ObjGUID = GUID;
			AddForm->_Update_ObjList = true;
            AddForm->_Update_SelectObj = true;
            return true;
        }
    }
    return false;
}

int     BaseForm::ObjSize(  )
{
    return sizeof( GameObjDbStruct );
 //   int Size = sizeof( GameObjDbStruct ) - sizeof( GameObjDbStruct::Temp ) + 3;
//    Size = Size & 0xfffffC;
//    return Size;
}


System::Void BaseForm::OnTimePorcEvent(System::Object *  sender, System::EventArgs *  e)
{
	if( _EnterOnTimeProc == true )
		return;
	_EnterOnTimeProc = true;
	Global::CritSect.Enter();
	timer_Base->Enabled = false;

	if( DragNodeMouseDown != NULL )
	{
		//Point P = treeList1->PointToClient(treeList1->MousePosition) ;
		//TreeListNode* Node = treeList1->CalcHitInfo(P)->Node;
		//if( Node != NULL )
		//{			
		//	if( P.Y < 20 )
		//	{
		//		/*
		//		int Index = TV_ObjGroup->Nodes->IndexOf( Node );
		//		if( Index > 1 )
		//		{
		//		Node = TV_ObjGroup->Nodes->Item[Index-1];
		//		}
		//		*/
		//		if( Node->PrevNode != NULL )
		//			Node = Node->PrevNode;
		//		else if( Node->ParentNode != NULL )
		//			Node = Node->ParentNode; 

		//	}
		//	else if( P.Y > treeList1->Bottom - 20 )
		//	{
		//		if( Node->NextNode != NULL )
		//			Node = Node->NextNode;
		//		else if( Node->ParentNode != NULL )
		//		{
		//			if( Node->ParentNode->NextNode != NULL )
		//				Node = Node->ParentNode->NextNode;
		//		}
		//		/*
		//		int Index = TV_ObjGroup->Nodes->IndexOf( Node );
		//		if( Index <  TV_ObjGroup->Nodes->Count -2 )
		//		{
		//		Node = TV_ObjGroup->Nodes->Item[Index+1];
		//		}
		//		*/
		//	}
		//	treeList1->SetFocusedNode(Node);
		//}
		
	}
	else
	{

		if( _Update_ObjList )
		{        
			_Update_ObjList = false;
			UpDateList( );
		}
		if( _Update_DataToDisplay )
		{
			_Update_DataToDisplay = false;
			UpDate_DataToDisplay( );
		}
		if( _Update_SelectObj )
		{
			_Update_SelectObj = false;
			SelectObj( LB_ObjList->SelectedIndex , true );
		}

		if( _OnValueChange )
		{
			OnValueChange();
			_OnValueChange = false;

			DB_GameObjDbStruct __pin *Data = &_ObjDB;
			ViewForm::g_ViewForm->SetObjInfo( &Data->GameData );
			//treeList1->Select();
			/*FormControl->GetChildAtPoint(MousePosition);
			if(FormControl !=NULL)
				FormControl->Select();*/
		}
		
	}
	OnTimeProc();
	timer_Base->Enabled = true;
	Global::CritSect.Leave();

	_EnterOnTimeProc = false;
    
}
System::Void BaseForm::BaseForm_Load(System::Object *  sender, System::EventArgs *  e)
{
	SetOnEnterShowTagEvent( this );    
}


System::Void BaseForm::OnActive()
{
		//InitDir = true;

		// 初始化
		SqlDataReader* myReader;

		// 讀取資料並放入資料庫介面中

		// DirZoneID
		{
			map< int, std::string >	mapDir;

			sqlCommand_Base->CommandText = "Select KeyStr, content from StringDB Where KeyStr LIKE 'DIR_ZONEID_%' ORDER BY KeyStr";
			myReader = sqlCommand_Base->ExecuteReader();
			CB_DirZoneID->Items->Clear();
			while( myReader->Read() )
			{                
				std::string sKey			=	DotNetStr::StringToChar( myReader->GetString( 0 ) );
				std::string sContent		=	DotNetStr::StringToChar( myReader->GetString( 1 ) );

				int		iID			=	GetStringID( sKey.c_str(), "DIR_ZONEID_" );
				mapDir[ iID ]		=	sContent;
				//comboBox1->Items->Add( Str );
			}
			myReader->Close();

			for( map< int, std::string >::iterator it = mapDir.begin(); it != mapDir.end(); it++ )
			{
				ComboBoxItem* newItem = new ComboBoxItem( it->first, (it->second).c_str() );
				CB_DirZoneID->Items->Add( newItem );		
			}
		}

		// DirVersionID
		{
			map< int, std::string >	mapDir;

			sqlCommand_Base->CommandText = "Select KeyStr, content from StringDB Where KeyStr LIKE 'DIR_VERSIONID_%' ORDER BY KeyStr";
			myReader = sqlCommand_Base->ExecuteReader();
			CB_DirVersionID->Items->Clear();
			while( myReader->Read() )
			{                
				std::string sKey			=	DotNetStr::StringToChar( myReader->GetString( 0 ) );
				std::string sContent		=	DotNetStr::StringToChar( myReader->GetString( 1 ) );

				int		iID			=	GetStringID( sKey.c_str(), "DIR_VERSIONID_" );
				mapDir[ iID ]		=	sContent;
				//comboBox1->Items->Add( Str );
			}
			myReader->Close();

			for( map< int, std::string >::iterator it = mapDir.begin(); it != mapDir.end(); it++ )
			{
				ComboBoxItem* newItem = new ComboBoxItem( it->first, (it->second).c_str() );
				CB_DirVersionID->Items->Add( newItem );
			}
		}

		// DirTagID
		{
			map< int, std::string >	mapDir;

			sqlCommand_Base->CommandText = "Select KeyStr, content from StringDB Where KeyStr LIKE 'DIR_TAGID_%' ORDER BY KeyStr";
			myReader = sqlCommand_Base->ExecuteReader();
			CB_DirTagID->Items->Clear();
			while( myReader->Read() )
			{                
				std::string sKey			=	DotNetStr::StringToChar( myReader->GetString( 0 ) );
				std::string sContent		=	DotNetStr::StringToChar( myReader->GetString( 1 ) );

				int		iID			=	GetStringID( sKey.c_str(), "DIR_TAGID_" );
				mapDir[ iID ]		=	sContent;
				//comboBox1->Items->Add( Str );
			}
			myReader->Close();

			for( map< int, std::string >::iterator it = mapDir.begin(); it != mapDir.end(); it++ )
			{	
				ComboBoxItem* newItem = new ComboBoxItem( it->first, (it->second).c_str() );
				CB_DirTagID->Items->Add( newItem );
			}
		}
}




System::Void BaseForm::OnBaseFormActive(System::Object *  sender, System::EventArgs *  e)
{


    OnActive();
	if( treeList1->AllNodesCount == 0)
		LoadTreeView();

    timer_Base->Enabled = true;
}

System::Void BaseForm::SearchPath_DClick(System::Object *  sender, System::EventArgs *  e)
{    

    if( openFileDialog_Base->ShowDialog() == DialogResult::OK )
    {
        String* File = openFileDialog_Base->FileName->ToLower();
		//String* Path = String::Format( "{0}/" , openFileDialog_Base->InitialDirectory->ToLower() );
		String* Path = String::Format( "{0}/" , ((String*)Global::GetIniString( "ResourcePath" ))->ToLower());
        File = File->Replace( "\\" , "/");
        Path = Path->Replace( "\\" , "/");
        Path = Path->Replace( "//" , "/");
        File = File->Replace( Path , "" );

        TextBox* Edit = static_cast<TextBox*>(sender);
        Edit->Text = File;    
    }
}
System::Void BaseForm::SearchPath_MouseDClick(System::Object *  sender, System::Windows::Forms::MouseEventArgs *  e)
{
	if (DateTime::Now.CompareTo(mouseClicked.AddMilliseconds(SystemInformation::DoubleClickTime)) < 1)
	{
		mouseClicked = DateTime::Now;
		//DoubleClick
		if( openFileDialog_Base->ShowDialog() == DialogResult::OK )
		{
			String* File = openFileDialog_Base->FileName->ToLower();
			//String* Path = String::Format( "{0}/" , openFileDialog_Base->InitialDirectory->ToLower() );
			String* Path = String::Format( "{0}/" , ((String*)Global::GetIniString( "ResourcePath" ))->ToLower());
			File = File->Replace( "\\" , "/");
			Path = Path->Replace( "\\" , "/");
			Path = Path->Replace( "//" , "/");
			File = File->Replace( Path , "" );

			ComboBox* Edit = static_cast<ComboBox*>(sender);
			Edit->Text = File;    
		}
	}
	else
	{
		mouseClicked = DateTime::Now;
	}
}
void    BaseForm::SetFilePath( )
{
	//openFileDialog_Base->InitialDirectory = Global::GetIniString( "ResourcePath" );
}

Void BaseForm::SetNumValue_TextChanged(System::Object *  sender, System::Windows::Forms::KeyEventArgs *  e)
{
	NumericUpDown* Edit = static_cast<NumericUpDown*>(sender);
	Edit->Text		= String::Format("{0}" , __box( Edit->Value ) );
}



System::Void BaseForm::OnBaseFormDeactive(System::Object *  sender, System::EventArgs *  e)
{
	timer_Base->Enabled = false;
	OnDeactive();
}

Control* BaseForm::GetEditByTagName ( Control* parentCtrl, String* TagName ) 
{ 
	Control* ctrl;
	for( int i = 0 ; i < parentCtrl->Controls->Count ; i++ )
	{ 
		ctrl = parentCtrl->Controls->get_Item( i );
		String*  Str  = static_cast<String*>( ctrl->Tag );		
		if( Str != NULL && Str->Length != 0 )
		{                        
			//Str = String::Copy( Str );
			if( Str->Chars[0] == '#' )
			{
				Str = Str->Remove( 0 , 1 );
			}
			Str = Str->ToLower();
			if ( Str->Equals(TagName->ToLower())) 
				return ctrl; 
		}

		if ( ctrl->HasChildren) 
		{ 
			Control* Found = GetEditByTagName( ctrl , TagName ); 
			if( Found != NULL )
				return Found; 
		} 
	} 

	return NULL; 
} 
System::Void BaseForm::CB_UseSQL_CheckedChanged(System::Object *  sender, System::EventArgs *  e)
{
//	TB_WhereSQLCmd->Enabled = CB_UseSQL->Checked;
}


System::Void BaseForm::OnUpDateList(System::Object *  sender, System::EventArgs *  e)
{
	LoadTreeView();
	UpDateList();
}
System::Void BaseForm::OnNewObj(System::Object *  sender, System::EventArgs *  e)
{
	NewObj();
}
System::Void BaseForm::OnSelectObj(System::Object *  sender, System::EventArgs *  e)
{
	//if (sender->GetType() == __typeof(ListBox))
	//{
	//	_Update_SelectObj = true;
	//	return;
	//}
	//static int LIndex = -1;
	//if (LB_ObjList->SelectedIndex != -1)
	//{
	//	Object* obj = LB_ObjList->Items[LB_ObjList->SelectedIndex];
	//	int ObjID = Int32::Parse(obj->ToString()->Substring(0, 6));
	//	if (ObjID != _ObjDB.GameData.GUID)
	//	{
	//		return;
	//	}
	//}
	//String* findStr = String::Format("{0} {1}", __box(_ObjGUID), new String(_ObjDB.GameData.Name));
	//LB_ObjList->SelectedIndex = LB_ObjList->FindString(findStr);
	//if( LIndex == LB_ObjList->SelectedIndex )
	//{
	//	if( (int)_ObjList->size() > LIndex && _ObjGUID == (*_ObjList)[LIndex].GUID )
	//		return;
	//}
	//LIndex = LB_ObjList->SelectedIndex;

	//-------------------------------------------------------------------------------------
	//找 Treeview 的 Node
	//-------------------------------------------------------------------------------------
	//if( LIndex >= (int)_ObjList->size() || LIndex == -1 )
	//{
	//	LIndex = -1;
	//}
	//else	
	//{

		_Update_SelectObj = true;
	//}
}
System::Void BaseForm::OnCB_Lock_Click(System::Object *  sender, System::EventArgs *  e)
{
	Lock_Click();
}
System::Void BaseForm::BT_Undo_Click(System::Object *  sender, System::EventArgs *  e)
{
	UndoData( );
}

System::Void BaseForm::OnOutputString(System::Object *  sender, System::EventArgs *  e)
{
	//OutputString( );
	OutputStringToDB( );
}
/*
System::Void BaseForm::OnOutputFileByStringTable(System::Object *  sender, System::EventArgs *  e)
{
	OutputFileByStringTable(  );
	MessageBox::Show( "TableString 輸出完成" , "訊息" );
}
*/
void	BaseForm::OnOutputFileProc( int LanguageID )
{
	if( EM_SearchFormTypeENUM_String != _FormType )
	{
		StringForm::g_StringForm->OutputFileLanguage( LanguageID );
	}

	if( _FormType == EM_SearchFormTypeENUM_NPC || _FormType == EM_SearchFormTypeENUM_QuestObj )
	{
		BaseForm::GetQuestLink();
	}




	OutputFileLanguage( LanguageID );
	MessageBox::Show( "資料輸出完成", "訊息" );
	//資料更新
	UpDateList( );
}

System::Void BaseForm::OnOutputFileDesign(System::Object*  sender, System::EventArgs*  e)
{
	OnOutputFileProc( -2 );
}

System::Void BaseForm::OnOutputFile1(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 0 );
}

System::Void BaseForm::OnOutputFile2(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 1 );
}

System::Void BaseForm::OnOutputFile3(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 2 );
}

System::Void BaseForm::OnOutputFile4(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 3 );
}
System::Void BaseForm::OnOutputFile5(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 4 );
}

System::Void BaseForm::OnOutputFile6(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 5 );
}

System::Void BaseForm::OnOutputFile7(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 6 );
}

System::Void BaseForm::OnOutputFile8(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 7 );
}
System::Void BaseForm::OnOutputFile9(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 8 );
}
System::Void BaseForm::OnOutputFile10(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 9 );
}
System::Void BaseForm::OnOutputFile11(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 10 );
}
System::Void BaseForm::OnOutputFile12(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 11 );
}
System::Void BaseForm::OnOutputFile13(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 12 );
}
System::Void BaseForm::OnOutputFile14(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 13 );
}
System::Void BaseForm::OnOutputFile15(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 14 );
}
System::Void BaseForm::OnOutputFile16(System::Object *  sender, System::EventArgs *  e)
{
	OnOutputFileProc( 15 );
}


void BaseForm::Reload_AttrTable( )
{
	int     i,j;
	SqlDataReader* myReader;
	char    Buf[2048];

	sprintf( Buf , "SELECT Value FROM Table_SysKeyValue WHERE (KeyStr LIKE 'Rare_') Order by GUID" );
	sqlCommand_Base->CommandText = Buf;
	myReader = sqlCommand_Base->ExecuteReader();        

	for( i = 0 ; i < 10 ; i++ )
	{     
		if( myReader->Read( ) == false )
			continue;

		RoleDataEx::AddLv_byRare[ i ] = myReader->GetInt32( 0 );
	}

	myReader->Close();

	//
	for( i = 0 ; i < _MAX_RACE_COUNT_ ; i++ )
	{
//		sprintf( Buf , "SELECT BStrLv1, BStaLv1, BIntLv1, BMndLv1, BAgiLv1, BHpLv1, BMpLv1, BStrArg, BStaArg, BIntArg, BMndArg, BAgiArg, BHpArg, BMpArg, StrArg, StaArg, IntArg,MndArg,AgiArg,HpArg,MpArg,HpStrArg,HpStaArg , MPIntArg, MpMndArg, AtkStrArg, AtkIntArg, AtkAgiArg, DefArg, BaseReHP, BaseReMP, ReHpArg, ReMpArg, MAtkArg, MDefArg, MoveSpeed , ReSPNormal ,ReSPAttack , ReSPUnderAttack , ReSPAttackTime  FROM FightArg Where ID=%d and Type = 0" , i );
        sprintf( Buf , "SELECT BStrLv1, BStaLv1, BIntLv1, BMndLv1, BAgiLv1, BHpLv1, BMpLv1,BStrArg, BStaArg, BIntArg, BMndArg, BAgiArg, BHpArg, BMpArg, StrArg,StaArg, IntArg, MndArg, AgiArg, HPArg, MPArg, HpStrArg, HpStaArg, MPIntArg, MpMndArg, AtkStrArg, AtkIntArg, AtkAgiArg, DefArg, BaseReHP, BaseReMP, ReHpArg, ReMpArg, MAtkArg, MDefArg, MoveSpeed , ReSPNormal_Move , ReSPNormal_Stop  ,ReSPAttack , ReSPUnderAttack , ReSPAttackTime_Move , ReSPAttackTime_Stop , MaxSP , DmgRate FROM FightArg Where ID=%d and Type = 0" , i );
		sqlCommand_Base->CommandText = Buf;
		myReader = sqlCommand_Base->ExecuteReader();        

		if( myReader->Read( ) )
		{            
			for( j = 0 ; j < myReader->FieldCount ; j++ )
				RoleValueData::RaceArg[i].Arg[ j ] = myReader->GetFloat( j );
		}

		myReader->Close();
	}
	for( i = 0 ; i < _MAX_VOCATION_COUNT_ ; i++ )
	{
        sprintf( Buf , "SELECT BStrLv1, BStaLv1, BIntLv1, BMndLv1, BAgiLv1, BHpLv1, BMpLv1,BStrArg, BStaArg, BIntArg, BMndArg, BAgiArg, BHpArg, BMpArg, StrArg,StaArg, IntArg, MndArg, AgiArg, HPArg, MPArg, HpStrArg, HpStaArg, MPIntArg, MpMndArg, AtkStrArg, AtkIntArg, AtkAgiArg, DefArg, BaseReHP, BaseReMP, ReHpArg, ReMpArg, MAtkArg, MDefArg, MoveSpeed , ReSPNormal_Move , ReSPNormal_Stop  ,ReSPAttack , ReSPUnderAttack , ReSPAttackTime_Move , ReSPAttackTime_Stop , MaxSP , DmgRate FROM FightArg Where ID=%d and Type = 1" , i );
		sqlCommand_Base->CommandText = Buf;
		myReader = sqlCommand_Base->ExecuteReader();        

		if( myReader->Read( ) )
		{            
			for( j = 0 ; j < myReader->FieldCount ; j++ )
				RoleValueData::VocArg[i][1].Arg[ j ] = myReader->GetFloat( j );
		}
		myReader->Close();

		sprintf( Buf , "SELECT BStrLv1, BStaLv1, BIntLv1, BMndLv1, BAgiLv1, BHpLv1, BMpLv1,BStrArg, BStaArg, BIntArg, BMndArg, BAgiArg, BHpArg, BMpArg, StrArg,StaArg, IntArg, MndArg, AgiArg, HPArg, MPArg, HpStrArg, HpStaArg, MPIntArg, MpMndArg, AtkStrArg, AtkIntArg, AtkAgiArg, DefArg, BaseReHP, BaseReMP, ReHpArg, ReMpArg, MAtkArg, MDefArg, MoveSpeed , ReSPNormal_Move , ReSPNormal_Stop  ,ReSPAttack , ReSPUnderAttack , ReSPAttackTime_Move , ReSPAttackTime_Stop , MaxSP , DmgRate FROM FightArg Where ID=%d and Type = 3" , i );
		sqlCommand_Base->CommandText = Buf;
		myReader = sqlCommand_Base->ExecuteReader();        

		if( myReader->Read( ) )
		{            
			for( j = 0 ; j < myReader->FieldCount ; j++ )
				RoleValueData::VocArg[i][0].Arg[ j ] = myReader->GetFloat( j );
		}
		myReader->Close();
	}
	for( i = 0 ; i < _MAX_SEX_COUNT_ ; i++ )
	{
		//sprintf( Buf , "SELECT BStrLv1, BStaLv1, BIntLv1, BMndLv1, BAgiLv1, BHpLv1, BMpLv1,BStrArg, BStaArg, BIntArg, BMndArg, BAgiArg, BHpArg, BMpArg, StrArg, StaArg, IntArg,MndArg,AgiArg,HpArg,MpArg,HpStrArg,HpStaArg , MPIntArg, MpMndArg, AtkStrArg, AtkIntArg, AtkAgiArg, DefArg, BaseReHP, BaseReMP, ReHpArg, ReMpArg, MAtkArg, MDefArg, MoveSpeed , ReSPNormal ,ReSPAttack , ReSPUnderAttack , ReSPAttackTime FROM FightArg Where ID=%d and Type = 2" , i );
        sprintf( Buf , "SELECT BStrLv1, BStaLv1, BIntLv1, BMndLv1, BAgiLv1, BHpLv1, BMpLv1,BStrArg, BStaArg, BIntArg, BMndArg, BAgiArg, BHpArg, BMpArg, StrArg,StaArg, IntArg, MndArg, AgiArg, HPArg, MPArg, HpStrArg, HpStaArg, MPIntArg, MpMndArg, AtkStrArg, AtkIntArg, AtkAgiArg, DefArg, BaseReHP, BaseReMP, ReHpArg, ReMpArg, MAtkArg, MDefArg, MoveSpeed , ReSPNormal_Move , ReSPNormal_Stop  ,ReSPAttack , ReSPUnderAttack , ReSPAttackTime_Move , ReSPAttackTime_Stop , MaxSP , DmgRate FROM FightArg Where ID=%d and Type = 2" , i );
		sqlCommand_Base->CommandText = Buf;
		myReader = sqlCommand_Base->ExecuteReader();        

		if( myReader->Read( ) )
		{            
			for( j = 0 ; j < myReader->FieldCount ; j++ )
				RoleValueData::SexArg[i].Arg[ j ] = myReader->GetFloat( j );
		}

		myReader->Close();
	}
	//----------------------------------------------------------------------------------------------------
	//取固定的Table
    sqlCommand_Base->CommandText = "SELECT DmgAtkArg,MDmgMAtkArg,Crit_DLV,Dmg_DLV,Miss_DLV,Miss_SecHand,Dmg_SecHand,BaseCritHit,BaseCritPower,BaseMagicCritHit,BaseMagicCritPower,Dmg_MagArg,MDmg_MagArg,MDmg_DotArg,Dmg_HealArg,Dmg_HealDotArg,BaseRateArg,BaseResistArg,DLvRateArg,DLvResistArg,PhyHit_Base,PhyHit_Range,PhyHit_AgiArg,PhyAvoid_AgiArg,MagHit_Base,MagHit_Range,MagHit_MndArg,MagAvoid_AgiArg,MagAvoid_MndArg  FROM FixFightArg";
	myReader = sqlCommand_Base->ExecuteReader();        
	for( int i = 0 ; i < 2 ; i++ )
	{
		if( myReader->Read( ) )
		{            
			for( j = 0 ; j < myReader->FieldCount ; j++ )
				RoleValueData::FixArgTable[i].Arg[ j ] = myReader->GetFloat( j );
		}
	}
	myReader->Close();

	//----------------------------------------------------------------------------------------------------
	sqlCommand_Base->CommandText = "SELECT GUID , Dmg , Speed ,MAtk , StandardCostRate FROM WeaponArg";
	myReader = sqlCommand_Base->ExecuteReader();        

	while( myReader->Read( ) )
	{   
		int ID  = myReader->GetInt32( 0 );
		RoleValueData::WeaponBaseDmg[ ID ] = myReader->GetFloat( 1 );
		RoleValueData::WeaponBaseDelayTime[ ID ] = myReader->GetInt32( 2 );
		RoleValueData::WeaponBaseMAtk[ ID ] = myReader->GetFloat( 3 );
		RoleValueData::WeaponBaseCostRate[ ID ] = myReader->GetFloat( 4 );

	}  
	myReader->Close();
	//----------------------------------------------------------------------------------------------------
	sqlCommand_Base->CommandText = "SELECT GUID , HeavyArmed , LightArmed , Leather , Clothes , Robe FROM ArmorArg";
	myReader = sqlCommand_Base->ExecuteReader();        

	memset( RoleDataEx::ArmorArg , 0 , sizeof( RoleDataEx::ArmorArg ) );

	while( myReader->Read( ) )
	{   
		int ID  = myReader->GetInt32( 0 );
		for( j = 1 ; j < myReader->FieldCount ; j++ )
		{
			RoleDataEx::ArmorArg[ID/100][ID%100][ j-1 ] = myReader->GetFloat( j );
		}
	}
	myReader->Close();
	//----------------------------------------------------------------------------------------------------
	LvExpRelationTable	AllExp;
	RoleDataEx::JobSkillExpTable.clear();
	RoleDataEx::JobExp_LvGrowRateTable.clear();
	RoleDataEx::RefineExpTable.clear();
	RoleDataEx::JobExpTable.clear();
	RoleDataEx::SkillExpTable.clear();
	RoleDataEx::GatherExpTable.clear();
	RoleDataEx::PlotExpTable.clear();
	RoleDataEx::PlotMoneyTable.clear();
	RoleDataEx::StandardCostTable.clear();

	Global::BaseMagicPower.clear();
	Global::MagicPowerGrowRate.clear();
	Global::AbilityPoint.clear();				//參考數值表
	Global::DefPoint.clear();					//參考數值表
	Global::HitPoint.clear();					//參考數值表

	sqlCommand_Base->CommandText = "SELECT LV , JobExp , SkillExp,GatherExp,RefineExp , PlotExp , PlotMoney , JobExp_LvGrowRate , JobMagicExp , StandardEqCost, BaseMagicPower , MagicPowerGrowRate , AbilityPoint , DefPoint , HitPoint  FROM Table_Exp ORDER BY  LV";
	myReader = sqlCommand_Base->ExecuteReader();        

	while( myReader->Read( ) )
	{   

		AllExp.LV					= myReader->GetInt32( 0 );
		AllExp.JobExp				= myReader->GetInt32( 1 );
		AllExp.SkillExp				= myReader->GetInt32( 2 );
		AllExp.GatherExp			= myReader->GetInt32( 3 ); 
		AllExp.RefineExp			= myReader->GetInt32( 4 );
		AllExp.PlotExp				= myReader->GetInt32( 5 );
		AllExp.PlotMoney			= myReader->GetInt32( 6 );
		AllExp.JobExp_LvGrowRate = myReader->GetFloat( 7 );
		AllExp.JobMagicExp			= myReader->GetInt32( 8 );
		AllExp.StandardCost			=	myReader->GetInt32( 9 );
		AllExp.BaseMagicPower		= myReader->GetFloat( 10 );
		AllExp.MagicPowerGrowRate	= myReader->GetFloat( 11 )*100;
		AllExp.AbilityPoint			= myReader->GetInt32( 12 );
		AllExp.DefPoint				= myReader->GetInt32( 13 );
		AllExp.HPPoint				= myReader->GetInt32( 14 );
		RoleDataEx::RefineExpTable.push_back( AllExp.RefineExp	);	//煉製的經驗值表

		int ValueExp = int( AllExp.JobExp * AllExp.JobExp_LvGrowRate );
		if( ValueExp < 1000 )
			ValueExp = ValueExp / 10 * 10; 
		else if( ValueExp < 10000 )
			ValueExp = ValueExp / 100 * 100; 
		else
			ValueExp = ValueExp / 1000 * 1000; 

		RoleDataEx::JobExpTable.push_back	( ValueExp );	//經驗值表
		RoleDataEx::SkillExpTable.push_back	( AllExp.SkillExp	);	//技能經驗值表
		RoleDataEx::GatherExpTable.push_back( AllExp.GatherExp	);	//採集經驗值表
		RoleDataEx::PlotExpTable.push_back	( AllExp.PlotExp		);	//劇情可獲得經驗值
		RoleDataEx::PlotMoneyTable.push_back( AllExp.PlotMoney	);	//劇情可獲得金錢
		RoleDataEx::JobExp_LvGrowRateTable.push_back( AllExp.JobExp_LvGrowRate );
		RoleDataEx::JobSkillExpTable.push_back( AllExp.JobMagicExp );
		RoleDataEx::StandardCostTable.push_back( AllExp.StandardCost);

		Global::BaseMagicPower.push_back( AllExp.BaseMagicPower );
		Global::MagicPowerGrowRate.push_back( AllExp.MagicPowerGrowRate );
		Global::AbilityPoint.push_back( AllExp.AbilityPoint );				//參考數值表
		Global::DefPoint.push_back( AllExp.DefPoint );						//參考數值表
		Global::HitPoint.push_back( AllExp.HPPoint );		
	}

	myReader->Close();
	//----------------------------------------------------------------------------------------------------

	RoleValueData::CalBaseTB();
}
//----------------------------------------------------------------------------------------------------
System::Void BaseForm::CopyObj_Base_Click(System::Object*  sender, System::EventArgs*  e)
{
	if( CB_Lock->Checked == false )
	{
		MessageBox::Show( "資料需先鎖定" ,"錯誤" );
		return;
	}

	CopyObjForm* Form;
	Form = new CopyObjForm( _FormType , _DBName );
	Form->ShowDialog();

	if( Form->IsAccept() == false )
		return;

	int SelectID = Form->SelectID();
	ReadObj_ByGUID( SelectID );

	DB_GameObjDbStruct __pin *Data = &_ObjDB;
//	_ObjGUID = OrgID;
	Data->GameData.GUID = _ObjGUID;
	Data->IsModify = 1;
	strcpy( Data->LockAccount , DotNetStr::StringToChar( _Account ).c_str() );
    UpDate_DataToDisplay();
	OnSelectObj( true );
}

void    BaseForm::InitTable( )
{
	//出始化一些 Table 資料
	OnActive();
}
//----------------------------------------------------------------------------------------------------
void	BaseForm::OnCreateForm()
{
	_ObjList					= new vector < DB_GameObjDbIndexStruct >;
	_StrList					= new vector < char* >;
	_mapQuestLink				= new map< int, set< int > >;
	_mapQuestProviderLink		= new map< int, set< int > >;

	_ObjDB.IsModify				= 0;
	_ObjGUID					= -1;
	_OnUpdate_DataToDisplay     = true;
	_OnValueChange				= false;
	_Update_DataToDisplay		= false;
	_Update_ObjList				= false;
	_Update_SelectObj			= false;

	sqlConnection_Base->ConnectionString = Global::GetDBSource();
	sqlConnection_Base1->ConnectionString = Global::GetDBSource();

	sqlConnection_Base->Open();            
	sqlConnection_Base1->Open();            

	OnLoad();

	_FormList->Add( this );
	SetFilePath();

	_Update_ObjList = true;
	//產生字串Buf
	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	map<string,ReadInfoStruct>*             ReadInfo ;
	map<string,ReadInfoStruct>::iterator    Iter;

	ReadInfo = Reader->ReadInfo();

	DB_GameObjDbStruct __pin * TempObj		  = &_ObjDB;
	DB_GameObjDbStruct __pin * TempObj_Backup = &_ObjDB_Backup;

	for(    Iter  = ReadInfo->begin() ; 
		Iter != ReadInfo->end() ; 
		Iter++  )
	{
		ReadInfoStruct *IDData = &(Iter->second);

		switch(IDData->Type)
		{
		case ENUM_Type_FloatPoint:
			break;

		case ENUM_Type_IntPoint:
			break;

		case ENUM_Type_ShortPoint:
			break;
		case ENUM_Type_CharString:
		case ENUM_Type_TextData:
			break;
		case ENUM_Type_CharStringPoint:
		case ENUM_Type_TextDataPoint:

			char* TempBuf;			
			char* TempBuf_BK;
			if( IDData->Size == 0 )
			{
				TempBuf		= new char[2048];
				TempBuf_BK	= new char[2048];
			}
			else
			{
				TempBuf		= new char[ IDData->Size ];
				TempBuf_BK	= new char[ IDData->Size ];
			}

			*(char**)(IDData->Point + int(TempObj)) = TempBuf;
			_StrList->push_back( TempBuf );

			*(char**)(IDData->Point + int(TempObj_Backup)) = TempBuf_BK;
			_StrList->push_back( TempBuf_BK );
			break;
		}
	}

	CB_SelectType->SelectedIndex = 3;

}
//----------------------------------------------------------------------------------------------------
void	BaseForm::OnCloseForm()
{
	_FormList->Remove( this );
	if( _StrList != NULL )
	{
		for( unsigned int i = 0 ; i < _StrList->size() ; i++ )
		{
			delete (*_StrList)[ i ];
		}
		delete _StrList;
		_StrList = NULL;
	}
}
//----------------------------------------------------------------------------------------------------
bool	BaseForm::OutputFile_SimplifyProcess( fstream& file , const char* OpenFileName , const char* SubFile )
{
	char	Buf[256];
	char*	FileName;
	char    OutputFileName[256];

	sprintf( OutputFileName , "%s.%s" , OpenFileName , SubFile );
	Com_CreatePath( Global::GetDataPath().c_str() );
// 	std::string TempDir = "C:\\RuneTempData\\";
// 	Com_CreatePath(TempDir.c_str());

	FileName = CombineFilePath( Global::GetDataPath().c_str() , OutputFileName );
	//FileName = CombineFilePath( TempDir.c_str() , OutputFileName );

	file.open( FileName , ios::out | ios::binary );
	if( file.is_open() == false )
	{
		sprintf( Buf , "%s 開檔失敗" ,  OutputFileName );
		int Result = MessageBox::Show( Buf , "警告" );
		return false;
	}
	return true;
}
System::Void BaseForm::Treelist_AfterExpand(System::Object*  sender, DevExpress::XtraTreeList::NodeEventArgs*  e)
{
	TreeListNode* NodeArg;
	if (e)
	{
		NodeArg = e->Node;
	}
	else
	{
		NodeArg = 0;
	}
	
	treeList1->BeginUpdate();	
	treeList1->BeginUnboundLoad();	
	SqlDataReader* myReader;
	TreeListNode* TreeNodeMap[] = new TreeListNode* [30000];
	for( int i = 0 ; i < 30000 ; i++ )
		TreeNodeMap[i] = NULL;
	
	int ParentNodeID = -1;
	if (e)
	{
		ParentNodeID = *static_cast<__box int*>(NodeArg->Tag);
	}
	sqlCommand_Base->CommandText = String::Format( "SELECT NodeID , NodeName From ObjGroupTreeNodeDB WHERE UseDB = '{0}' AND ParentNodeID={1} ORDER BY NodeName" ,  (String*)_DBName , __box( ParentNodeID ) );
	myReader = sqlCommand_Base->ExecuteReader();
	while( myReader->Read())
	{

		int		NodeID			= myReader->GetInt32( 0 );
		String* NodeName		= myReader->GetString( 1 );
		Object* objArray __gc [] = {__box(NodeID), NodeName};


		TreeNodeMap[NodeID] =treeList1->AppendNode( objArray, NodeArg);
		TreeNodeMap[NodeID]->ImageIndex = 0;
		TreeNodeMap[NodeID]->SelectImageIndex = 0;
		TreeNodeMap[NodeID]->StateImageIndex = 0;
		TreeNodeMap[NodeID]->set_Tag(__box(NodeID));
		TreeNodeMap[NodeID]->set_HasChildren(true);
	}
	myReader->Close();

	int Index = CB_SelectType->SelectedIndex;
	if( TB_WhereSQLCmd->Text->Length == 0 && Index != 0 )
		Index = 3;
	switch( Index )
	{
	case 0:
		{
			int LanguageSetting = Global::LanguageSetting();
			if( LanguageSetting == -1 )
			{
				sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.[Content], n.NodeID FROM {0} AS n INNER JOIN StringDB AS s ON n.GUID = s.OrgObjID WHERE (s.KeyStr LIKE 'Sys%[_]name') AND (n.OutputLanguage & 15 <> 0) AND (n.NodeID = {1}) ORDER BY   n.GUID" , (String*)_DBName  , __box(ParentNodeID));
			}
			else
			{
				sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.[Content], n.NodeID FROM {0} AS n INNER JOIN StringDB AS s ON n.GUID = s.OrgObjID WHERE (s.KeyStr LIKE 'Sys%[_]name') AND (n.OutputLanguage & {1} != 0) AND (n.NodeID = {2}) ORDER BY  n.GUID" , (String*)_DBName , __box( LanguageSetting ) , __box(ParentNodeID));
				//sqlCommand_Base->CommandText = String::Format( "SELECT {0}.GUID, StringDB.Content, NodeID FROM {0} , StringDB WHERE {0}.GUID = StringDB.OrgObjID AND StringDB.KeyStr LIKE 'Sys%[_]name' AND ({0}.OutputLanguage&{1} != 0)  AND (n.NodeID = {2}) ORDER BY {0}.GUID" , (String*)_DBName , __box( LanguageSetting ) ,static_cast<String*>(e->Node->Tag));
			}
		}
		break;
	case 1://使用名稱
		sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.[Content], n.NodeID FROM {0} AS n INNER JOIN  StringDB AS s ON n.GUID = s.OrgObjID WHERE (RIGHT(s.KeyStr, 5) = '_name') AND (s.[Content] LIKE '%{1}%') AND (n.NodeID = {2}) ORDER BY n.GUID", (String*)_DBName , TB_WhereSQLCmd->Text , __box(ParentNodeID));
		//sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.Content, n.NodeID FROM {0} n inner join stringdb s on n.guid = s.orgobjid where right(keystr,5) = '_name' AND StringDB.Content LIKE '%{1}%' AND NodeID = {2} order by n.guid", (String*)_DBName , TB_WhereSQLCmd->Text ,static_cast<String*>(e->Node->Tag));
		//sqlCommand_Base->CommandText = String::Format( "SELECT {0}.GUID, StringDB.Content, NodeID FROM {0} , StringDB WHERE {0}.GUID = StringDB.OrgObjID AND StringDB.KeyStr LIKE 'Sys%[_]name' AND StringDB.Content LIKE '%{1}%' AND NodeID = {2} ORDER BY {0}.GUID" , (String*)_DBName , TB_WhereSQLCmd->Text ,static_cast<String*>(e->Node->Tag) );
		break;
	case 2://始用SQL
		sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.Content, n.NodeID from {0} AS n INNER JOIN StringDB AS s ON n.GUID = s.OrgObjID {1} AND NodeID = {2}" , (String*)_DBName , TB_WhereSQLCmd->Text , __box(ParentNodeID));
		break;
	case 3://全部
		sqlCommand_Base->CommandText = String::Format( "SELECT n.GUID, s.Content, n.NodeID from {0} n inner join StringDB s on n.guid = s.orgobjid where right(keystr,5) = '_name'  AND n.NodeID = {1} order by n.guid",(String*)_DBName, __box(ParentNodeID));
		break;
	}		
	
	myReader = sqlCommand_Base->ExecuteReader();


	int		GUID;
	int		NodeID;
	String*	ObjName;
	//顯示子node 
	while( myReader->Read())
	{

		GUID	= myReader->GetInt32( 0 );
		ObjName = myReader->GetString( 1 );
		NodeID	= myReader->GetInt32( 2 );
		String*		Name = String::Format( "{0} {1}" , __box( GUID ) , ObjName );
		Object* objArray __gc [] = {__box(GUID), Name};
		treeList1->AppendNode(objArray, NodeArg);

	}
	myReader->Close();
	treeList1->EndUnboundLoad();
	treeList1->EndUpdate();
}
//----------------------------------------------------------------------------------------------------
System::Void BaseForm::TV_ObjGroup_AfterSelect(System::Object*  sender, DevExpress::XtraTreeList::NodeEventArgs*  e)
{
	int     Index = LB_ObjList->SelectedIndex;

	TreeListNode* TNode = treeList1->FocusedNode;
	if( TNode == NULL )				   
	{
		return;
	}
	String* col ="ColName";
	if( _ObjDB.IsModify != 0 && Index != -1 )
	{
		timer_Base->Enabled = false;

		int Result = MessageBox::Show( "是否儲存,(Yes)儲存" , "警告" , MessageBoxButtons::YesNo );
		if( Result == DialogResult::Yes )
		{			
			UnLockAndSave( );
		}
		else
		{
			sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1} and LockAccount='{2}'" , (String*)_DBName , __box(_ObjGUID) , _Account );
			sqlCommand_Base->ExecuteReader()->Close();        
		}
		CB_Lock->Checked = false;
		_ObjDB.IsModify = 0;
		timer_Base->Enabled = true;
		LoadTreeView();
		UpDateList();
	}

	if( TNode->Tag != NULL  )   //如果選擇到的為目錄則return
		return;

	//DotNetStr::StringToInt(Convert::ToString(
	
	int NodeID = DotNetStr::StringToInt(TNode->GetDisplayText(col));
	if( NodeID == 0 )
		return;

	if( NodeID == _ObjGUID )
		return;



	if( CB_Lock->Checked != false)
	{
		sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1} and LockAccount = '{2}'" , (String*)_DBName , __box(_ObjGUID) , _Account );
		sqlCommand_Base->ExecuteReader()->Close();        
	}
	

	bool IsFindNode = false;

	//找到物件位置
	for ( int i = 0 ; i < (int)_ObjList->size() ; i++ )
	{
		if( (*_ObjList)[i].GUID == NodeID )
		{
			_ObjGUID = NodeID;
			LB_ObjList->SelectedIndex = i;
			IsFindNode = true;
			return;
		}
	}

	if( IsFindNode == false )
	{
		_ObjGUID = NodeID;
		_Update_ObjList = true;
		//CB_UseSQL->Checked = false;
		CB_SelectType->SelectedIndex = 3;
	}

}

System::Void BaseForm::NewToolStripMenuItem_Click(System::Object*  sender, System::EventArgs*  e)
{
	TreeListNode* Node = treeList1->FocusedNode;
	SqlDataReader* myReader;
	sqlCommand_Base->CommandText = "BEGIN TRANSACTION";
	sqlCommand_Base->ExecuteReader()->Close();


	//取最大的ID
	int	MaxNodeID = 0;
	int ParentNodeID = -1;
	String* NewNodeName = "NewField";

	sqlCommand_Base->CommandText = "Select MAX( NodeID ) , COUNT( NodeID) from ObjGroupTreeNodeDB WITH(TABLOCKX)";
	myReader = sqlCommand_Base->ExecuteReader();
	if( myReader->Read( ) )			
	{
		if( myReader->GetInt32( 1 ) != 0 )
		{
			MaxNodeID = myReader->GetInt32( 0 );
		}		
	}

	myReader->Close();

	MaxNodeID++;
	while( Node != NULL )
	{
		String* col= "ColName";
		if (Node->Tag ==NULL)
			ParentNodeID =  -1;
		else
			ParentNodeID =  *static_cast<__box int*>(Node->Tag);
		if( ParentNodeID != -1 )
			break;
		Node = Node->ParentNode;
	}
	/*if( ParentNodeID == 0 )
	{
	ParentNodeID = -1;
	}*/


	//差入新的Node
	sqlCommand_Base->CommandText = String::Format( "INSERT ObjGroupTreeNodeDB( NodeID , UseDB , NodeName , ParentNodeID ) VALUES ( {0} , '{1}' , 'NewField' , {2} )", __box( MaxNodeID ) , (String*)_DBName , __box( ParentNodeID ) );
	Object* Obj __gc [] = {NewNodeName};
	sqlCommand_Base->ExecuteReader()->Close();
	if( Node == NULL )

		treeList1->AppendNode(Obj , NULL,0,0,0)->set_Tag(__box( MaxNodeID ));
	//TV_ObjGroup->Nodes->Insert( 0 ,String::Format( "{0}" , __box( MaxNodeID ) ) , NewNodeName );		
	else
		treeList1->AppendNode(Obj , Node->Id,0,0,0)->set_Tag(__box( MaxNodeID ));
	//Node->Nodes->Insert( 0 ,String::Format( "{0}" , __box( MaxNodeID ) ) , NewNodeName );



	sqlCommand_Base->CommandText = "COMMIT TRANSACTION";
	sqlCommand_Base->ExecuteReader()->Close();
}
System::Void BaseForm::DelToolStripMenuItem_Click(System::Object*  sender, System::EventArgs*  e)
{
	TreeListNode* Node = treeList1->FocusedNode;
	String* NodeID = static_cast<String*>(Node->Tag);

	if( Node != NULL && Node->Tag == NULL)
	{
		MessageBox::Show( "不可刪除物件" , "錯誤" );		
		return;
	}

	if( Node->Nodes->Count !=0 )
	{								 
		MessageBox::Show( "子目錄要先刪除" , "錯誤" );		
		return;
	}

	int Result = MessageBox::Show( "確定要刪除目錄" , "警告" , MessageBoxButtons::YesNo );
	if( Result != DialogResult::Yes )
		return;


	//刪除Node
	sqlCommand_Base->CommandText = String::Format( "DELETE ObjGroupTreeNodeDB WHERE NodeID = {0}" , NodeID );
	sqlCommand_Base->ExecuteReader()->Close();

	//更新所有在此Node內的資料
	sqlCommand_Base->CommandText = String::Format( "UPDATE {0} Set NodeID = -1 WHERE NodeID = {1}" ,  (String*)_DBName , NodeID );
	sqlCommand_Base->ExecuteReader()->Close();

	treeList1->DeleteNode(Node);
}

System::Void BaseForm::selectmoveToolStripMenuItem_Click(System::Object*  sender, System::EventArgs*  e)
{
	SelectMoveForm* SelectForm = new SelectMoveForm;
	SelectForm->ShowDialog();
	if( SelectForm->IsAccept() == false )
		return;

	int BeginGuid = SelectForm->BeginGUID();
	int EndGuid = SelectForm->EndGUID();

	int	NodeID;
	TreeListNode* Node = treeList1->FocusedNode;

	while( Node != NULL && Node->Tag == NULL )
	{
		Node = Node->ParentNode;
	}

	if( Node == NULL )
	{
		NodeID = -1;
	}
	else
	{
		NodeID = *static_cast<__box int*>(Node->Tag);
	}

	if( EndGuid - BeginGuid >= 100 )
	{
		MessageBox::Show( NULL , "不可般移超過100筆資料" , "錯誤" );
		return;
	}
	

	//sqlCommand_Base->CommandText = String::Format( "UPDATE {0} Set NodeID = {1} WHERE GUID >= {2} and GUID <= {3}" , (String*)_DBName ,  __box( NodeID ) , __box( BeginGuid ) , __box( EndGuid ) );
	String* Str = String::Format( "UPDATE {0} Set NodeID = {1} " ,  (String*)_DBName ,  __box( NodeID ) );
	Str = String::Format( "{0} WHERE GUID >= {1} and GUID <= {2}" , Str , __box( BeginGuid ) , __box( EndGuid ) );
	sqlCommand_Base->CommandText = Str;
	sqlCommand_Base->ExecuteReader()->Close();

	LoadTreeView();
	UpDateList();
}

System::Void BaseForm::moveToolStripMenuItem_Click(System::Object*  sender, System::EventArgs*  e)
{
	int GUID = _ObjDB.GameData.GUID;
	String*		Name = String::Format( "{0} {1}" , __box( GUID ) , (String*)_ObjDB.GameData.Name );
	int	NodeID;
	TreeListNode* Node = treeList1->FocusedNode;

	while( Node != NULL && Node->Tag == NULL )
	{
		Node = Node->ParentNode;
	}  	
	String* col = "ColName";
	TreeListNode* FindtreeNode = treeList1->FindNodeByFieldValue( col , Name );
	//TreeListNode* FindtreeNode[] = TV_ObjGroup->Nodes->Find( String::Format( "@{0}" , __box( GUID ) ) , true );
	if(FindtreeNode)
	{
		treeList1->MoveNode(FindtreeNode,Node);	
		if( Node == NULL )
		{
			NodeID = -1;	
		}
		else
		{
			NodeID = *static_cast<__box int*>(Node->Tag);				
		}	


		sqlCommand_Base->CommandText = String::Format( "UPDATE {0} Set NodeID = {1} WHERE GUID = {2}" , (String*)_DBName ,  __box( NodeID ) , __box( GUID ) );
		sqlCommand_Base->ExecuteReader()->Close();
		LoadTreeView();
		UpDateList();
	}

}

System::Void BaseForm::TV_ObjGroup_AfterLabelEdit(System::Object*  sender, DevExpress::XtraTreeList::CellValueChangedEventArgs*  e)
{	 
	TreeListNode* Node = treeList1->FocusedNode;
	if( *static_cast<__box int*>(Node->Tag) == 0 ||  e->Value == NULL )
	{			
		//treeList1->EndEdit(true);
		return;
	}
	sqlCommand_Base->CommandText = String::Format( "UPDATE ObjGroupTreeNodeDB Set NodeName = '{0}' WHERE NodeID = {1}" ,  e->Value , static_cast<String*>(Node->Tag) );
	sqlCommand_Base->ExecuteReader()->Close();
	
}

System::Void BaseForm::treeList1_ShownEditor(System::Object*  sender, System::EventArgs*  e) {
	TreeListNode* Node = treeList1->FocusedNode;
	if(Node->Tag ==NULL)
		treeList1->HideEditor();
}
System::Void BaseForm::Treelist_Collapse(System::Object*  sender, DevExpress::XtraTreeList::NodeEventArgs*  e)
{
	e->Node->Nodes->Clear();
	e->Node->set_HasChildren(true);
}
void	BaseForm::LoadTreeView( )
{

	treeList1->BeginUpdate();	
	treeList1->BeginUnboundLoad();
	treeList1->ClearNodes();
	//做一個RootNode(old syntax中會強制有一個Rootnode)
// 	Object* RNode __gc [] = {new String("RootNode")};
// 	TreeListNode* firstNode = treeList1->AppendNode( RNode , NULL);
// 	firstNode->set_Tag(__box(-1));
// 	firstNode->set_HasChildren(true);
// 
// 	firstNode->set_Expanded(true);	  //觸發Treelist_AfterExpand事件

	Treelist_AfterExpand(NULL, NULL);

	treeList1->EndUnboundLoad();
	treeList1->EndUpdate();
}

System::Void BaseForm::TV_ObjGroup_MouseDown(System::Object*  sender, System::Windows::Forms::MouseEventArgs*  e)
{		
	
	TreeListHitInfo* treeInfo = treeList1->CalcHitInfo(Point(e->X, e->Y));
	DragNodeMouseDown = treeInfo->Node;

	//if ( DragNodeMouseDown != NULL )
	if ( DragNodeMouseDown != NULL )
	{
		treeList1->FocusedNode = DragNodeMouseDown;
		// Remember the point where the mouse down occurred. The DragSize indicates
		// the size that the mouse can move before a drag event should be started.
		System::Drawing::Size dragSize = SystemInformation::DragSize;

		// Create a rectangle using the DragSize, with the mouse position being
		// at the center of the rectangle.
		DragBoxFromMouseDown = System::Drawing::Rectangle(Point(e->X - (dragSize.Width / 2),e->Y - (dragSize.Height / 2)),dragSize);

		//顯示NodeID(供企劃使用)
		LB_NodeID->Text = String::Format("NodeID：{0}", DragNodeMouseDown->Tag);
		LB_NodeID->Visible = true;
	}
	else
	{
		DragBoxFromMouseDown = Rectangle::Empty;	
		LB_NodeID->Visible = false;
	}
}
System::Void BaseForm::TV_ObjGroup_MouseUp(System::Object*  sender, System::Windows::Forms::MouseEventArgs*  e)
{
	DragBoxFromMouseDown = Rectangle::Empty;
	DragNodeMouseDown = NULL;
	DropNodeMouseUp = NULL;
}
System::Void BaseForm::TV_ObjGroup_MouseMove(System::Object*  sender, System::Windows::Forms::MouseEventArgs*  e)
{
	if ( (e->Button & ::MouseButtons::Left) == ::MouseButtons::Left )
	{
		// If the mouse moves outside the rectangle, start the drag.
		if ( DragBoxFromMouseDown != Rectangle::Empty &&  !DragBoxFromMouseDown.Contains( e->X, e->Y ) )
		{

			//DragDropEffects dropEffect = this->TV_ObjGroup->DoDragDrop( DragNodeMouseDown , DragDropEffects::Move );
			DragDropEffects dropEffect = treeList1->DoDragDrop(DragNodeMouseDown , DragDropEffects::Move);
		}

		/*	TreeNode* Node = TV_ObjGroup->GetNodeAt( e->X , e->Y );
		if( Node != NULL )
		TV_ObjGroup->SelectedNode = Node;*/
	}
	else
	{
		DragBoxFromMouseDown = Rectangle::Empty;
		DragNodeMouseDown = NULL;
		DropNodeMouseUp = NULL;
	}

}
System::Void BaseForm::TV_ObjGroup_DragOver(System::Object*  sender, System::Windows::Forms::DragEventArgs*  e)
{
	//拖動物件事件

	if( DragNodeMouseDown != NULL )
	{
		e->Effect = DragDropEffects::Move;
	}
	else
	{
		e->Effect = DragDropEffects::None;
	}

}

Void BaseForm::TV_ObjGroup_DragDrop(System::Object*  sender, System::Windows::Forms::DragEventArgs*  e)
{
	String* col ="ColName";
	//DragNodeMouseDown = (TreeListNode*) e->Data->GetData(__typeof(TreeListNode));
	//__try_cast<TreeListNode*> (
	//DragNodeMouseDown = __try_cast<TreeListNode*> (e->Data->GetData(TreeListNode.GetType())) ;
	TreeListHitInfo* treeInfo = treeList1->CalcHitInfo( treeList1->PointToClient(Point(e->X,e->Y)));
	DropNodeMouseUp = treeInfo->Node;

	//treeList1->SetNodeIndex(DragNodeMouseDown, treeList1->GetNodeIndex(DropNodeMouseUp));

	if( DragNodeMouseDown == NULL || DropNodeMouseUp == NULL )
		return;

	if( DragNodeMouseDown->Id == DropNodeMouseUp->Id )
	{
		//查看看是否形成loop
			return;
	}
	////如果非目錄 移到上一層
	if( DropNodeMouseUp != NULL && DropNodeMouseUp->Tag ==NULL )//&& NodeId == 0 )
	{
		DropNodeMouseUp = DropNodeMouseUp->ParentNode;
	}
	int Result = MessageBox::Show( "是否搬移此物件" , "警告" , MessageBoxButtons::YesNo );
	if( Result == DialogResult::Yes )
	{
		//若按下滑鼠所在的Node不等於放開滑鼠所在的Node
		if(	DragNodeMouseDown != NULL && DragNodeMouseDown != DropNodeMouseUp )
		{
			
			treeList1->MoveNode(DragNodeMouseDown,DropNodeMouseUp);
		}

		int ParentNodeID = -1;
		int NodeID = DragNodeMouseDown->Id;
		if( DropNodeMouseUp != NULL)
		{
			//TreeListNode夾帶Tag值(LoadTreeView時有放進去)
			ParentNodeID = *static_cast<__box int*>(DropNodeMouseUp->Tag);
		}
		if( ParentNodeID == NodeID )
			return;

		//資料庫儲存
		//如果不是資料夾
		if( DragNodeMouseDown->Tag ==NULL )
		{
			//更新原本的ParentNode

			int ObjID = DotNetStr::StringToInt(DragNodeMouseDown->GetDisplayText(col));

			sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set NodeID = {1} Where GUID = {2}" , (String*)_DBName , __box( ParentNodeID ), __box(ObjID)  );
			sqlCommand_Base->ExecuteReader()->Close();
		}
		else
		{
			sqlCommand_Base->CommandText = String::Format( "UpDate ObjGroupTreeNodeDB Set ParentNodeID = {0} Where NodeID = {1}" , __box( ParentNodeID ) , static_cast<__box int*>(DragNodeMouseDown->Tag) );
			sqlCommand_Base->ExecuteReader()->Close();
		}

	}
	DragBoxFromMouseDown = Rectangle::Empty;
	DragNodeMouseDown = NULL;
	DropNodeMouseUp = NULL;
}
//////////////////////////////////////////////////////////////////////////
Void BaseForm::CB_SelectType_SelectedIndexChanged(System::Object*  sender, System::EventArgs*  e) 
{
 	TB_WhereSQLCmd->Text = "";
 	switch( CB_SelectType->SelectedIndex)
 	{
 	case 1://使用名稱
		TB_WhereSQLCmd->Enabled = true;
		BT_SQLStrSelect->Visible = false;
		TB_WhereSQLCmd->Text = "";
		break;
 	case 2:	//使用SQL
		TB_WhereSQLCmd->Enabled = true;
		BT_SQLStrSelect->Visible = true;
		TB_WhereSQLCmd->Text = "WHERE s.KeyStr LIKE 'Sys%[_]name'";
		break;
 	default:
		TB_WhereSQLCmd->Enabled = false;
		BT_SQLStrSelect->Visible = false;
		TB_WhereSQLCmd->Text = "";
		break;
	}
}

System::Void BaseForm::Select_Ability_Click(System::Object*  sender, System::EventArgs*  e)
{
	ComboBox* combobox = static_cast< ComboBox* >( sender );

	SelectAbilityForm::g_SelectAbilityForm->ShowForm();

	if( SelectAbilityForm::g_SelectAbilityForm->IsAccept() == true )
		combobox->SelectedIndex = SelectAbilityForm::g_SelectAbilityForm->SelectID();
}

int		BaseForm::GetStandardAbilityValue( int LV , int Type , float Rate )
{
	LV--;
	if( LV < 0 )
		LV = 0;
	if( LV >= Global::AbilityPoint.size() )
		LV = Global::AbilityPoint.size() -1;

	switch( Type )
	{
	case 0:	
		return int( Global::AbilityPoint[LV] * Rate );
	case 1:
		return int( Global::DefPoint[LV] * Rate );
	case 2:
		return int( Global::HitPoint[LV] * Rate );
	}

	return 0;
}

void BaseForm::KeyWord( const char* pszKeyWord, char* pszSourceText, int& iType )
{
	SqlDataReader* myReader;

	iType = 0;

	// you must to kill [111111]
	// you must to kill [111111]

	// 檢查是不是六位數 GUID
	int iGUID = atoi( pszKeyWord );
	if( iGUID > 100000 )
	{
		char szCommand[1024];
		sprintf( szCommand, "Select content from StringDB Where KeyStr = 'Sys%d_name'", iGUID );

		sqlCommand_Base->CommandText = szCommand;
		myReader = sqlCommand_Base->ExecuteReader();

		/*
		if( iGUID >= 100000 && iGUID < 200000 )
		{
			iType = 1;
		}
		else
		if( iGUID >= 200000 && iGUID < 300000 )
		{
			iType 
		}
		*/
	}
	else
	if( strcmp( pszKeyWord, "ZONE_" ) == 0 )
	{
		char szCommand[1024];
		sprintf( szCommand, "Select content from StringDB Where KeyStr = '%s'", pszKeyWord );
		sqlCommand_Base->CommandText = szCommand;
		myReader = sqlCommand_Base->ExecuteReader();
	}

	if( myReader->Read() == false )
	{
		// 找不到字串
		if( pszSourceText )
		{
			sprintf( pszSourceText, pszKeyWord );
		}			
	}
	else
	{
		String* Str   =  myReader->GetString( 0 );
		if( pszSourceText )
		{
			sprintf( pszSourceText, DotNetStr::StringToChar( Str ).c_str() );
		}
	}

	myReader->Close();
}

System::Void BaseForm::SetAllLanguageClick(System::Object*  sender, System::EventArgs*  e)
{
	bool Flag = !(CLB_OutputLanguage->GetItemChecked(0));

	for(  int i = 0 ; i < CLB_OutputLanguage->Items->Count ; i++ )
	{
		CLB_OutputLanguage->SetItemChecked( i , Flag );
	}
	ChangeFlag( CLB_OutputLanguage  , NULL );	
}
System::Void BaseForm::OnEnterSetTag(System::Object*  sender, System::EventArgs*  e)
{
	Control* ctrl = static_cast<Control*>(sender);

	String*  TagStr  = static_cast<String*>( ctrl->Tag );
	if( TagStr->Length == 0 )
		return;

	TB_TagText->Text = TagStr;
}

//設定所有Enter的事件
void	BaseForm::SetOnEnterShowTagEvent( Control* parentCtrl )
{
	Control* ctrl;
	for( int i = 0 ; i < parentCtrl->Controls->Count ; i++ )
	{ 
		ctrl = parentCtrl->Controls->get_Item( i );
		String*  Str  = static_cast<String*>( ctrl->Tag );		
		if( Str != NULL && Str->Length != 0 )
		{                        
			ctrl->Enter += new System::EventHandler(this, &BaseForm::OnEnterSetTag);
		}

		if ( ctrl->HasChildren) 
		{ 
			SetOnEnterShowTagEvent( ctrl ); 
		} 
	} 
}


int BaseForm::GetStringID( const char* pSource, const char* pKey )
{
	if( pSource == NULL || pKey == NULL )
		return 0;

	int iSourceLen	= strlen( pSource );
	int iKeyLen		= strlen( pKey );
	int iValueLen	= iSourceLen - iKeyLen;

	char szValue[1024];

	ZeroMemory( szValue, sizeof( szValue ));
	memcpy( szValue, pSource + iKeyLen, iValueLen );

	int iVal		= atoi( szValue );

	return iVal;

}

void	FilePuts( fstream& file , const char* str )
{
	file.write( str , strlen(str) );
}
System::Void BaseForm::ExportDataClick(System::Object*  sender, System::EventArgs*  e)
{
	ListBox* ListAll	= DataExportForm::g_DataExportForm->GetList_All();
	ListBox* ListSelect = DataExportForm::g_DataExportForm->GetList_Select();
	ListAll->Items->Clear();
	ListSelect->Items->Clear();

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	map<string,ReadInfoStruct>*             ReadInfo ;
	map<string,ReadInfoStruct>::iterator    Iter;

	ReadInfo = Reader->ReadInfo();

	for(    Iter  = ReadInfo->begin() ; 
		Iter != ReadInfo->end() ; 
		Iter++  )
	{
		ReadInfoStruct *IDData = &(Iter->second);
		if( stricmp( IDData->ValueName.c_str() , "guid" ) == 0 )
			continue;

		String* ValueName = IDData->ValueName.c_str();
		switch(IDData->Type)
		{
		case ENUM_Type_FloatPoint:
		case ENUM_Type_IntPoint:
		case ENUM_Type_ShortPoint:
		case ENUM_Type_TextData:
		case ENUM_Type_CharString:
		case ENUM_Type_TextDataPoint:
		case ENUM_Type_CharStringPoint:
			ListAll->Items->Add( ValueName );
			break;
		case ENUM_Type_BitPoint:
		case ENUM_Type_TimeCharString:
		default:
			continue;
		}
	}


	DataExportForm::ShowForm();
	if( DataExportForm::IsAccept() == false )
		return;

	string FileName = DotNetStr::StringToChar( DataExportForm::OutputFile() );
	fstream file;
	file.open( FileName.c_str() , ios::out );
	if( file.is_open() == false )
	{
		char Buf[512];
		sprintf( Buf , "%s 開檔失敗" ,  FileName.c_str() );
		int Result = MessageBox::Show( Buf , "警告" );
		return ;
	}

	//file.write( "GUID" , 4 );
	FilePuts( file , "GUID" );
	for( int i = 0 ; i < ListSelect->Items->Count; i++ )
	{
		file.write( "\t" , 1 );
		string chStr = DotNetStr::StringToChar( ListSelect->Items->Item[i]->ToString() );
		//file.write( chStr , strlen(chStr) ;
		FilePuts( file , chStr.c_str() );

	}
	file.write( "\n" , 1);

	//////////////////////////////////////////////////////////////////////////
	Global::CritSect.Enter();

	DB_GameObjDbStruct __pin * TempObj = &_ObjDB;
	for( int i = 0 ; i < _ObjList->size() ; i++ )
	{
		DB_GameObjDbIndexStruct& ObjIndexInfo =  (*_ObjList)[i];
		int GUID = ObjIndexInfo.GUID;

		//讀取原本資料
		SelectObj_byGUID( GUID , false );
		

		FilePuts( file , IntToStr(GUID).c_str() );

		for( int j = 0 ; j < ListSelect->Items->Count; j++ )
		{
			file.write( "\t" , 1 );

			Iter = ReadInfo->find( DotNetStr::StringToChar( ListSelect->Items->Item[j]->ToString() ) );

			{
				ReadInfoStruct *IDData = &(Iter->second);
				string Str = Iter->first;

				switch(IDData->Type)
				{
				case ENUM_Type_BinaryData:
					{
					}
					break;
				case ENUM_Type_FloatPoint:
					{
						float Value = *((float*)(IDData->Point + int(TempObj))) ;
						//file.puts( FloatToStr(Value).c_str() );
						FilePuts( file , FloatToStr(Value).c_str() );
					}
					break;

				case ENUM_Type_IntPoint:
					{
						int Value = *((int*)(IDData->Point + int(TempObj)));
						//file.puts( IntToStr(Value).c_str() );
						FilePuts( file , IntToStr(Value).c_str() );
					}
					break;

				case ENUM_Type_ShortPoint:
					{
						short Value = *((short*)(IDData->Point + int(TempObj)));
						//file.puts( IntToStr(Value).c_str() );
						FilePuts( file , IntToStr(Value).c_str() );
					}                
					break;
				case ENUM_Type_BitPoint:
					{
						bool Value = *((bool*)(IDData->Point + int(TempObj)));
						//file.puts( IntToStr(Value).c_str() );
						FilePuts( file , IntToStr(Value).c_str() );
					}
					break;
				case ENUM_Type_CharString:
				case ENUM_Type_TextData:
					{
						char* Value = (char*)(IDData->Point + int(TempObj));
						//file.puts( Value );
						FilePuts( file , Value );
					}    
					break;
				case ENUM_Type_CharStringPoint:
				case ENUM_Type_TextDataPoint:
					{
						char* Value = *(char**)(IDData->Point + int(TempObj));
						String* str = new String(Value);
						str = str->Replace("\n", "<n>");
						FilePuts( file , (const char*)(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str).ToPointer()) );
					}
					break;
				case ENUM_Type_TimeCharString:
					{
					}
					break;
				}
			}   
		}
		file.write("\n" , 1 );
	}
	
	Global::CritSect.Leave();
	_Update_ObjList = true;
	_Update_SelectObj = true;

	file.close();

	MessageBox::Show( "OK" , "訊息" );

}

System::Void BaseForm::BatchUpdate_Click(System::Object*  sender, System::EventArgs*  e)
{
	BatchUpdateForm::ShowForm();
	if( BatchUpdateForm::IsAccept() == false )
		return;

	DB_GameObjDbStruct __pin * TempObj = &_ObjDB;

	ListView*	PreView = BatchUpdateForm::PreView();

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );
	map<string,ReadInfoStruct>* ReadInfo = Reader->ReadInfo();
	map<string,ReadInfoStruct>::iterator Iter;


	//////////////////////////////////////////////////////////////////////////
	//檢查欄位名稱是否有問題
	bool CheckColumn = true;
	for( int i = 0 ; i <  PreView->Columns->Count ; i++ )
	{

		String* ColumnStr =  PreView->Columns->Item[i]->Text;
		Iter = ReadInfo->find( DotNetStr::StringToChar( ColumnStr->ToLower() ) );
		if( Iter == ReadInfo->end() )
		{
			String* Str = String::Format( "欄位{0}找不到" , ColumnStr );
			MessageBox::Show( Str );
			CheckColumn = false;
			//return;
		}

	}
	if( CheckColumn == false )
		return;
	//////////////////////////////////////////////////////////////////////////
	Global::CritSect.Enter();

	for( int i = 0 ; i < PreView->Items->Count ; i++ )
	{
		int GUID = DotNetStr::StringToInt( PreView->Items->Item[i]->Text );


		//讀取原本資料
		if( SelectObj_byGUID( GUID , true ) == false )
		{
			Global::CritSect.Leave();
			String* Str = String::Format( "GUID={0} 找不到" , __box(GUID) );
			MessageBox::Show( Str );			
			return;
		}
		sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set IsLock = 0 Where GUID = {1}" , (String*)_DBName , __box(GUID)  );
		sqlCommand_Base->ExecuteReader()->Close();       

		CB_Lock->Checked = true;

		for( int j = 1 ; j < PreView->Columns->Count ; j++ )
		{
			Iter = ReadInfo->find( DotNetStr::StringToChar( PreView->Columns->Item[j]->Text->ToLower() ) );
			
			{
				ReadInfoStruct *IDData = &(Iter->second);
				string Str = Iter->first;

				ListViewItem* Item1 = PreView->Items->Item[i];
				String* Value = Item1->SubItems->Item[j]->Text;
				//->SubItems->Item[j]->Text->ToSting();
				switch(IDData->Type)
				{
				case ENUM_Type_BinaryData:
					{
					}
					break;
				case ENUM_Type_FloatPoint:
					{
						*((float*)(IDData->Point + int(TempObj))) = DotNetStr::StringToFloat( Value );
					}
					break;

				case ENUM_Type_IntPoint:
					{
						*((int*)(IDData->Point + int(TempObj))) = DotNetStr::StringToInt( Value );
					}
					break;

				case ENUM_Type_ShortPoint:
					{
						*((short*)(IDData->Point + int(TempObj))) = DotNetStr::StringToInt( Value );
					}                
					break;
				case ENUM_Type_BitPoint:
					{
						*((bool*)(IDData->Point + int(TempObj))) = DotNetStr::StringToInt( Value ) != 0;
					}
					break;
				case ENUM_Type_CharString:
				case ENUM_Type_TextData:
					{
						String* Str = Value;
						strcpy( (char*)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Str ).c_str() );
					}    
					break;
				case ENUM_Type_CharStringPoint:
				case ENUM_Type_TextDataPoint:
					{
						String* Str = Value;
						strcpy( *(char**)(IDData->Point + int(TempObj)) , DotNetStr::StringToChar( Str ).c_str() );
					}
					break;
				case ENUM_Type_TimeCharString:
					{
					}
					break;
				}
			}   
		}
		//UpDate_DataToDisplay();
		_ObjDB.IsModify = 1;

		UnLockAndSave( );
	}

	Global::CritSect.Leave();
	_Update_ObjList = true;
	_Update_SelectObj = true;

	MessageBox::Show( "OK" , "訊息" );
}

System::Void BaseForm::ShowHistoryClick(System::Object*  sender, System::EventArgs*  e)
{

	String*  TagStr  = TB_TagText->Text;
	if( TagStr->Length == 0 )
		return;

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );

	ReadInfoStruct*  IDData = Reader->GetColumnInfo( DotNetStr::StringToChar( TagStr ).c_str() );
	if( IDData == NULL )
		return;

	ShowDataForm::g_ShowDataForm->Clear();
	SqlDataReader* myReader;

	System::String* StrList[] = new System::String*[5];

	sqlCommand_Base->CommandText = String::Format( "Select Time , ColumnName , AccountID , OrgStr , NewStr  from EditLogDB WHERE OrgObjID = {0} and ColumnName ='{1}' order by Time DESC " 
		, __box( _ObjDB.GameData.GUID) , TagStr );
	myReader = sqlCommand_Base->ExecuteReader();
	while( myReader->Read())
	{

		StrList[0] = String::Format("{0}" , __box( myReader->GetDateTime( 0 ) ) );
		StrList[1] = myReader->GetString( 1 );
		StrList[2] = myReader->GetString( 2 );
		StrList[3] = myReader->GetString( 3 );
		StrList[4] = myReader->GetString( 4 );
		ShowDataForm::g_ShowDataForm->SetHistory( StrList );
	}
	myReader->Close();

	ShowDataForm::g_ShowDataForm->ShowForm();
}	
System::Void BaseForm::ShowAllHistoryClick(System::Object*  sender, System::EventArgs*  e)
{

	ReaderClass< DB_GameObjDbStruct >*      Reader = ObjReader( );

	ShowDataForm::g_ShowDataForm->Clear();
	SqlDataReader* myReader;

	System::String* StrList[] = new System::String*[5];

	sqlCommand_Base->CommandText = String::Format( "Select Time , ColumnName , AccountID , OrgStr , NewStr  from EditLogDB WHERE OrgObjID = {0} order by Time DESC , ColumnName DESC" 
		, __box( _ObjDB.GameData.GUID) );
	myReader = sqlCommand_Base->ExecuteReader();
	while( myReader->Read())
	{

		StrList[0] = String::Format("{0}" , __box( myReader->GetDateTime( 0 ) ) );
		StrList[1] = myReader->GetString( 1 );
		StrList[2] = myReader->GetString( 2 );
		StrList[3] = myReader->GetString( 3 );
		StrList[4] = myReader->GetString( 4 );
		ShowDataForm::g_ShowDataForm->SetHistory( StrList );
	}
	myReader->Close();

	ShowDataForm::g_ShowDataForm->ShowForm();
}	
/*
System::Void BaseForm::VersionTransferClick(System::Object*  sender, System::EventArgs*  e)
{

	SqlDataReader* myReader;
	SqlDataReader* myReaderString;
	sqlCommand_Base->CommandText = String::Format( "Select GUID , DirZoneID , DirVersionID , DirTagID from {0}" , (String*)_DBName );
	myReader = sqlCommand_Base->ExecuteReader();


	for( int i = 0 ; ; i++ )
	{                
		if( myReader->Read() == false )
			break;

		sqlCommand_Base1->CommandText = String::Concat(  
			  String::Format( "UPDATE StringDB SET DirZoneID = {0},DirVersionID = {1} , DirTagID = {2} " , __box( myReader->GetInt32( 1 ) ) , __box( myReader->GetInt32( 2 ) ) , __box( myReader->GetInt32( 3 ) ) )
			, String::Format( "WHERE OrgObjID = {0}" , __box( myReader->GetInt32( 0 ) ) ) );
		sqlCommand_Base1->ExecuteReader()->Close();


	}
	myReader->Close();
}*/

bool BaseForm::GetQuestLink()
{
	// 將所有任務相關的東西都撈出來

	SqlDataReader* myReader;

	string sSQL = "Select GUID";

	for( int i=1; i<=_MAX_SIZE_QUEST_ITEM; i++ )
	{
		char szObj[128];
		sprintf( szObj, ",iRequest_KillID%d", i );

		sSQL += szObj;
	}

	for( int i=1; i<=_MAX_SIZE_QUEST_CONDITION; i++ )
	{
		char szObj[128];
		sprintf( szObj, ",iProcess_KilltoGetItem_ObjID%d", i );

		sSQL += szObj;
	}	

	for( int i=1; i<=_MAX_SIZE_QUEST_CONDITION; i++ )
	{
		char szObj[128];
		sprintf( szObj, ",iProcess_ClickToGetItem_ObjID%d", i );

		sSQL += szObj;
	}

	for( int i=1; i<=_MAX_SIZE_QUEST_ITEM; i++ )
	{
		char szObj[128];
		sprintf( szObj, ",iQuestLinkNPC%d", i );

		sSQL += szObj;
	}

	sSQL += " from QuestDetailObjectDB";

	sqlCommand_Base->CommandText = sSQL.c_str();

	myReader = sqlCommand_Base->ExecuteReader();

	_mapQuestLink->clear();

	int iTotalObj = ( _MAX_SIZE_QUEST_ITEM * 2 ) + ( _MAX_SIZE_QUEST_CONDITION * 2 );

	while( myReader->Read())
	{
		int iGUID	= myReader->GetInt32( 0 );
		
		for( int i=1; i<=iTotalObj; i++ )
		{
			int iNPCID = myReader->GetInt32( i );

			if( iNPCID != 0 )
			{
				map< int, set< int > >::iterator it = _mapQuestLink->find( iNPCID );
				if( it == _mapQuestLink->end() )
				{
					(*_mapQuestLink)[ iNPCID ].insert( iGUID );
				}
				else
				{
					it->second.insert( iGUID );
				}
			}
		}
	}
	myReader->Close();


	// 設定任務題供者的連結
	//------------------------------------------------------------------
	_mapQuestProviderLink->clear();

	sSQL = "Select GUID";

	for( int i=1; i<=_MAX_NPC_QUEST_COUNT_; i++ )
	{
		char szObj[128];
		sprintf( szObj, ",iQuestID%d", i );

		sSQL += szObj;
	}

	sSQL += " from QuestNPCObjectDB";

	sqlCommand_Base->CommandText = sSQL.c_str();

	myReader = sqlCommand_Base->ExecuteReader();

	while( myReader->Read())
	{
		int iGUID	= myReader->GetInt32( 0 );

		for( int i=1; i<=_MAX_NPC_QUEST_COUNT_; i++ )
		{
			int iQuestID = myReader->GetInt32( i );

			if( iQuestID != 0 )
			{
				(*_mapQuestProviderLink)[ iQuestID ].insert( iGUID );
			}
		}
	}
	myReader->Close();



	return true;
}

void BaseForm::OnBaseOutputObjSetting( DB_GameObjDbStruct* TempObj )
{
	OnOutputObjSetting( TempObj );

	if(		TempObj->GameData.Classification == EM_ObjectClass_NPC
		||	TempObj->GameData.Classification == EM_ObjectClass_QuestDetail
		||	TempObj->GameData.Classification == EM_ObjectClass_QuestNPC		
		||	TempObj->GameData.Classification == EM_ObjectClass_Treasure		
		||	TempObj->GameData.Classification == EM_ObjectClass_CreateRole		
		)
		TempObj->GameData.iTagID	= TempObj->TagID;
	else
		TempObj->GameData.iTagID	= 0;

}
void BaseForm::OnMoveOutSide(System::Object*  sender, System::EventArgs*  e)
{
	//不是資料夾
	if( treeList1->FocusedNode->Tag == NULL )
	{
		String* col = "ColName";
		int ObjID = DotNetStr::StringToInt(treeList1->FocusedNode->GetDisplayText(col));
		//移動物件到最外層
		sqlCommand_Base->CommandText = String::Format( "UpDate {0} Set NodeID = -1 Where GUID = {1}" , (String*)_DBName , __box(ObjID)  );
		sqlCommand_Base->ExecuteNonQuery();
	}
	//資料夾
	else
	{
		sqlCommand_Base->CommandText = String::Format( "UpDate ObjGroupTreeNodeDB Set ParentNodeID = -1 Where NodeID = {0}" , static_cast<__box int*>(treeList1->FocusedNode->Tag) );
		sqlCommand_Base->ExecuteNonQuery();

	}


	TreeListNode* NullNode = NULL;
	treeList1->MoveNode(treeList1->FocusedNode, NullNode);
}
System::Void BaseForm::LoadFolderItem(System::Object*  sender, System::EventArgs*  e)
{
	ComboBox* senderBox = static_cast<ComboBox*>(sender);
	if (senderBox->Items->Count == 0 &&
		senderBox->Text->Length == 0)
	{
		return;
	}
	char* ResourcePath = Global::GetIniString("ResourcePath");
	String* PathString = new String(ResourcePath);

	if (String::Compare(PathString->Substring(PathString->Length - 1), "\\") != 0)
	{
		PathString = String::Format("{0}\\", PathString);
	}
	String* OrgText = senderBox->Text;
	String* fileLoc = String::Format("{0}{1}", PathString, OrgText);
	fileLoc = fileLoc->Replace("/", "\\");
	fileLoc = fileLoc->Replace("\\\\", "\\");
	fileLoc = fileLoc->Substring(0, fileLoc->LastIndexOf("\\") + 1);
	if (System::IO::Directory::Exists(fileLoc))
	{
		String* Dirfiles __gc[] = System::IO::Directory::GetFiles(fileLoc);
		senderBox->Items->Clear();
		for (int i = 0 ; i < Dirfiles->Length ; i ++)
		{
			String* tempfileName = Dirfiles[i]->Replace(PathString, "");
			senderBox->Items->Add(tempfileName);
		}
		senderBox->TextChanged -= new System::EventHandler(this, &BaseForm::LoadFolderItem);
		senderBox->Text = OrgText;
		senderBox->Select(senderBox->Text->Length, 0);
		senderBox->TextChanged += new System::EventHandler(this, &BaseForm::LoadFolderItem);
	}
}