//---------------------------------------------------------------------------
//
#include <vcl.h>
#include <System.IOUtils.hpp>
#pragma hdrstop

#include "GlobalUnit.h"
#include "ContentPanelUnit.h"
#include "ToolpalPanel.h"
#include "UseStylePanel.h"
#include "PreStylePanel.h"
#include "AudStylePanel.h"
#include "ChordPanel.h"
#include "TrackPanel.h"
#include "PlayTimePanel.h"
#include "MainFormUnit.h"
#include "MessageFormUnit.h"
#include "ProgressFormUnit.h"
#include "CapButton.h"
#include "ImportFormUnit.h"
#include "SaveFormUnit.h"   //add by lm 14.1.7
#include "LoginFormUnit.h"  //add by lm 14.1.17
#include "ShowUserInfoPanel.h" //add by lm 14.1.17
#include "AboutFormUnit.h"
#include "ManageSongFormUnit.h"
#include "UploadFormUnit.h"
#include "UpdateFormUnit.h"  	//add by laq 2014.1.22
#include "ScoreFormUnit.h"
#include "PayMentFormUnit.h"
#include "PredefineProjectFormUnit.h"
#include "CustomerSettingFormUnit.h"
#include "SaveLocalStyleFormUnit.h"
#include "ImportSegmentFormUnit.h"
#include "StyleUploadFormUnit.h"
#include "StyleSpecsFormUnit.h"
#include "Undo.h"
#include "Project.h"
#include "SplashFormUnit.h"
#include "MidiTrack.h"
#include "VSTPathFormUnit.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PNGButton"
#pragma link "ComboBoxComponent"
#pragma link "LineEdit"
#pragma link "TextButton"
#pragma resource "*.dfm"
TMainForm *MainForm;

#define PANEL_BOUND			3
#define CONTENT_MINWIDTH	515
#define TOOLPAL_MINWIDTH   	210
#define TOOLPAL_MINHEIGHT  	26

#define IDM_OPENPROJECT     0x100

//拖动操作相关变量
TImage * w_imgDrag = NULL;  //透明图片
bool w_bDraging = false;
int w_iDragMode = 0,
	w_xImgDrag = 0, //透明图片位置(screen坐标)
	w_yImgDrag = 0,
	w_xOldDrag = 0,  //上次位置
	w_yOldDrag = 0,
	w_xOffDrag = 0, //左上角与鼠标的距离
	w_yOffDrag = 0;

TCursor crBrush = 0x50,
		crBrushAdd = 0x51,
		crBrushNo = 0x52;

int BREAK_LINE_Y = 35;
const COLORREF CLR_TOP = RGB( 74, 80, 88 ),
		CLR_BOTTOM = RGB( 39, 42, 47 ),
		CLR_BR_OUT = RGB( 106, 111, 117 ),
		CLR_BR_IN =	RGB( 44, 46, 48 ),
		CLR_BR_FILL	= RGB( 70, 73, 76 );

TUndoLite* u_pUploadLite = NULL;

//字体检查回调函数
int CALLBACK FontEnumProc (const ENUMLOGFONTEX *lpelfe, const NEWTEXTMETRICEX *lpntme, unsigned long FontType, LPARAM lParam)
{
	if( FontType==TRUETYPE_FONTTYPE  ){
		return 0;
	}

	return 1;
}

bool CheckFontYaHeiInstalled(String sFontName)
{
    // Get the screen DC
    HDC hDC = GetDC(NULL);
    LOGFONTW lf;
    lf.lfCharSet = DEFAULT_CHARSET;
    wcscpy(lf.lfFaceName, sFontName.w_str());
    // Enumerate fonts
    return EnumFontFamiliesEx(hDC, &lf,  (FONTENUMPROC)FontEnumProc, 0, 0);
}

//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
	: TForm(Owner)
{
	m_pMenuBar = NULL;
	m_pMenu = m_pPopMenu = NULL;
	m_HelpForm = NULL;
	m_pVolumeForm = NULL;
	m_pContentPanel = NULL;
	m_pUseStylePanel = m_pAudStylePanel = m_pPreStylePanel
				= m_pChordPanel = m_pTrackPanel = NULL;
	m_ToolpalWidth = 263;
	m_UseStyleHeight = TOOLPAL_MINHEIGHT;
	m_PreStyleHeight = 206;

	m_bFromFile = false;
	m_pNotificationGetTimer = NULL;
    m_pNotificationForm = NULL;

	HintWindowClass = __classid(TSkinHintWindow);

	m_nVolLevel = 0;

	m_pCDTimer = NULL;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCreate(TObject *Sender)
{
	Screen->Cursor = crHourGlass;

    Randomize();
    DragAcceptFiles( Handle, true );

	g_hProjectEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
	Color = CLR_TOP;

	//设置全局提示框属性
	Application->HintHidePause = 10000;
	Screen->HintFont->Color = RGB( 213, 221, 232 );
	Screen->HintFont->Size = 10;

    //菜单字体使用微软雅黑
    String sMenuFont = "Microsoft YaHei UI";
	if( !CheckFontYaHeiInstalled(sMenuFont) ){
        Canvas->Font->Name = sMenuFont;
        Canvas->Font->Size = g_szFont10;
    }
    else{
        Canvas->Font->Name = g_strTxtFontName;
        Canvas->Font->Size = g_szFont9;
    }

	CreateMenus();

	BREAK_LINE_Y = MENUBAR_TOP * 2 + m_pMenuBar->GetHeight() + 1;

	m_lblLogon->Font->Color = CLR_TEXT_NOR;
	m_lblLogon->Height = m_pMenuBar->GetHeight();

	if( g_strProjectName.length()>0 )
		m_lblTitle->Caption = g_strProjectName.c_str();
	else
		m_lblTitle->Caption = L"Untitle";

	m_lblTitle->Font->Color = CLR_TEXT_HOT;//RGB( 218, 221, 232 );
	m_lblTitle->Left = MENUBAR_LEFT + m_pMenuBar->Width + OFFSET_BR*2;
	m_lblTitle->Width = m_lblLogon->Left - OFFSET_BR*2 - m_lblTitle->Left;
	m_lblTitle->Height = m_pMenuBar->GetHeight();

	//创建时间显示框
	m_pPlayTimePanel = new TPlayTimePanel(this);
	m_pPlayTimePanel->Parent = this;
	m_pPlayTimePanel->OnClick = PlayTimeClick;
	m_pPlayTimePanel->SetBounds( 150, 46, 80, 26 );

	// 执行文件版本信息
	DWORD dwHandle;
	DWORD dwVerLen = GetFileVersionInfoSize(Application->ExeName.c_str(), &dwHandle);
	if (dwVerLen) {
		TCHAR *lpData = new TCHAR[dwVerLen];
		if (GetFileVersionInfo(Application->ExeName.c_str(), 0, dwVerLen, lpData)) {
			PVSFixedFileInfo lpffi;
			UINT uLen;
			if (VerQueryValue(lpData, TEXT("\\"), (void **)&lpffi, &uLen)) {
				g_infoSoftwareUpdate.version.majorVersion =
					HIWORD(lpffi->dwFileVersionMS);
				g_infoSoftwareUpdate.version.minorVersion =
					LOWORD(lpffi->dwFileVersionMS);
				g_infoSoftwareUpdate.version.modifyVersion =
					HIWORD(lpffi->dwFileVersionLS);
				g_infoSoftwareUpdate.version.buildVersion =
					LOWORD(lpffi->dwFileVersionLS);
			}
		}
		delete[]lpData;
	}

	sprintf(g_strCurrentVersion, "%d.%d.%d.%d",
		g_infoSoftwareUpdate.version.majorVersion, g_infoSoftwareUpdate.version.minorVersion,
		g_infoSoftwareUpdate.version.modifyVersion, g_infoSoftwareUpdate.version.buildVersion);

	DebugPrint("软件版本：%d.%d.%d.%d \n",
		g_infoSoftwareUpdate.version.majorVersion, g_infoSoftwareUpdate.version.minorVersion,
		g_infoSoftwareUpdate.version.modifyVersion, g_infoSoftwareUpdate.version.buildVersion);

	string strRoot = ((AnsiString)g_strUserPath.c_str()).c_str();

	HRESULT hResult = f_CS_GetVersion();
	if( hResult!=CS_VERSION ){
		if( SOFTWARE_ID==e_Pro_Lite )
			MessageForm->ShowMessage("初始化风格组件失败!",	MB_ICONERROR | MB_OK);
		else
			MessageForm->ShowMessage("初始化网络服务组件失败!",	MB_ICONERROR | MB_OK);
		PostMessage(Handle, WM_CLOSE, 0, 0);
		return;
	}

	SplashForm->ShowProgress( "初始化媒体控制组件......" );
	hResult = f_MM_GetVersion();
	if( hResult!=MM_VERSION || f_MM_InitialObjects(Handle, (char*)strRoot.c_str())!=S_OK ){
		MessageForm->ShowMessage("初始化媒体控制组件失败！", MB_ICONERROR | MB_OK);
		PostMessage(Handle, WM_CLOSE, 0, 0);
		return;
	}

	GetInitVar();

	InitSegmentColor();
	SetMelodyTS(g_iMelodyTimeSignature, true);
	SetMelodyTempo(g_nMelodyTempo, true);

	SplashForm->ShowProgress( "初始化输入输出设备......" );
	HRESULT res = f_MM_CheckIODevice( g_iPlaybackDevice, g_strPlaybackDevice,
										g_iRecordDevice, g_strRecordDevice );
	if( !(res&0xFF) )
		g_iPlaybackOutput = -1;

	if( !(res&0xFF00) )
		g_iRecordInput = -1;

	res = f_MM_SetIODevice( g_iPlaybackDevice, g_iPlaybackOutput, g_iRecordDevice, g_iRecordInput );

	if( res!=S_OK ){
		g_iPlaybackDevice = -1;
		g_iPlaybackOutput = -1;
		g_iRecordDevice = -1;
		g_iRecordInput = -1;
		g_strPlaybackDevice[0] = 0;
		g_strRecordDevice[0] = 0;

		f_MM_SetIODevice( g_iPlaybackDevice, g_iPlaybackOutput, g_iRecordDevice, g_iRecordInput );
		f_MM_CheckIODevice( g_iPlaybackDevice, g_strPlaybackDevice,	g_iRecordDevice, g_strRecordDevice );
	}

	f_MM_SetRecordAutoAdjust( g_bRecordAutoAdjust );

	if( g_fSpeakerVolume<0 )
		g_fSpeakerVolume = f_MM_GetStreamVolume( 0 ) / 100.0;
	else
		f_MM_SetStreamVolume(0, g_fSpeakerVolume);

	if( g_fRecordVolume<0 )
		g_fRecordVolume = f_MM_GetStreamVolume( 1 ) / 100.0;
	else
		f_MM_SetStreamVolume( 1, g_fRecordVolume );

	g_fSpeakerVolume_SVD = g_fSpeakerVolume;
	g_fRecordVolume_SVD = g_fRecordVolume;

	m_cbKey->SetFont(g_strTxtFontName, g_szFont9);// >SetFontSize( g_szFont9 );
	m_cbKey->Left = m_pPlayTimePanel->Left + m_pPlayTimePanel->Width + OFFSET_BR * 3;
	m_cbKey->Top = m_pPlayTimePanel->Top;
	m_cbKey->AddItem( "  C" );
	m_cbKey->AddItem( "bD" );
	m_cbKey->AddItem( "  D" );
	m_cbKey->AddItem( "bE" );
	m_cbKey->AddItem( "  E" );
	m_cbKey->AddItem( "  F" );
	m_cbKey->AddItem( "#F" );
	m_cbKey->AddItem( "  G" );
	m_cbKey->AddItem( "bA" );
	m_cbKey->AddItem( "  A" );
	m_cbKey->AddItem( "bB" );
	m_cbKey->AddItem( "  B" );
	m_cbKey->DefItemIndex = -1;
	m_cbKey->Enabled = false;

	m_btnTS->SetFont(g_strTxtFontName, g_szFont9);
	m_btnTS->Left = m_cbKey->Left + m_cbKey->Width + OFFSET_BR;
	m_btnTS->Top = m_pPlayTimePanel->Top;
	m_btnTS->Caption = g_strTimeSignature[g_iMelodyTimeSignature];

	m_btnTempo->SetFont(g_strTxtFontName, g_szFont9);
	m_btnTempo->Left = m_btnTS->Left + m_btnTS->Width + OFFSET_BR;
	m_btnTempo->Top = m_pPlayTimePanel->Top;
	m_btnTempo->Caption = IntToStr(g_nMelodyTempo);

	m_cbPreStage->SetFont(g_strTxtFontName, g_szFont9);//SetFontSize( g_szFont9 );
	m_cbPreStage->Top = m_pPlayTimePanel->Top;
	m_cbPreStage->Left = m_btnTempo->Left + m_btnTempo->Width + OFFSET_BR;
	m_cbPreStage->AddItem( "初始化" );
	m_cbPreStage->AddItem( "I M E" );
	m_cbPreStage->AddItem( "I M I M E" );
	m_cbPreStage->AddItem( "自定义" );
	m_cbPreStage->DefItemIndex = g_iPreStage;

	SplashForm->ShowProgress( "扫描SF音色库......" );
	InitFontList();

	if( g_lstFonts.empty() ){
		MessageForm->ShowMessage("初始化音色库失败！", MB_ICONERROR | MB_OK);
		PostMessage(Handle, WM_CLOSE, 0, 0);
		return;
	}
	else{
		SetSelectFont();
		strcpy( g_strSoundFont_SVD, g_strSoundFont );	//全局音色库名(已保存)

		//音色库列表加载
		int iSelFont = -1;
		for( int i=0; i<g_lstFonts.size(); i++ ){
			FONTINFO* pFont = g_lstFonts[i];

			if( pFont->nInstCount>0 && pFont->nDrumCount>0 ){
				if( i==g_idFont )
					iSelFont = m_cbFontSelect->ItemsCount;

				TComboBoxItem* pItem = m_cbFontSelect->AddItem( g_lstFonts[i]->strFontName );
				pItem->Tag = i;
			}
		}

		m_cbFontSelect->SetFont(g_strTxtFontName, g_szFont9);
		m_cbFontSelect->DefItemIndex = iSelFont;
		m_cbFontSelect->Enabled = !g_bExtFont;
		m_btnExtFontOn->Visible = g_bExtFontUsable && g_bExtFont;
		m_btnExtFontOff->Visible = g_bExtFontUsable && !g_bExtFont;
		m_lblExtFont->Visible = !g_bExtFontUsable;
	}

	SplashForm->ShowProgress( "初始化网络服务组件......" );

	//初始化网络服务
// 	strcpy( g_strServerURL, "new.ichangzuo.com" );
// 	strcpy( g_strServerURL, "www.ichangzuo.com" );
// 	strcpy( g_strServerURL, "LocalHost" );
//	strcpy( g_strServerURL, "47.98.232.209" );
//	strcpy( g_strServerURL, "192.168.5.80" );

	char* idDevice = GetMacAdress();
	DebugPrint("MAC: %02X-%02X-%02X-%02X-%02X-%02X", (UCHAR)idDevice[0],(UCHAR)idDevice[1],(UCHAR)idDevice[2]
														,(UCHAR)idDevice[3],(UCHAR)idDevice[4],(UCHAR)idDevice[5] );

	int ret_CS = f_CS_InitialService( Handle, SOFTWARE_ID, &g_infoSoftwareUpdate, g_strServerURL,
												(char*)strRoot.c_str(), idDevice );
	if( ret_CS==-1 ){
			MessageForm->ShowMessage("初始化风格组件失败!",	MB_ICONERROR | MB_OK);
			PostMessage(Handle, WM_CLOSE, 0, 0);
			return;
	}
	else if( ret_CS==S_FALSE ) {
		m_lblLogon->Visible = false;
		g_bUpdateMandatory = true;

		if( SOFTWARE_ID!=e_Pro_Lite ){
			MessageForm->ShowMessage("网络服务启动失败!\n(将无法进行网络相关操作)",
															MB_ICONERROR | MB_OK);
		}
	}
	else {
		g_bAutoLogin = GetAutoLogin(g_infoUser.strUserName, g_infoUser.strPassword);

		if (g_bAutoLogin) {
			m_lblLogon->Caption = L"正在登录...";
			m_lblLogon->Tag = 1;
			m_lblLogon->Hint = L"点击取消登录";
			f_CS_Login(&g_infoUser, false);
		}

		f_CS_AutoDownloadStyle( g_bAutoDownloadStyle );
	}

 	SplashForm->ShowProgress( "初始化窗体组件......" );

	//创建内容面板
	m_pContentPanel = new TContentPanel(this);
	m_pContentPanel->Parent = this;
	m_pContentPanel->OnMouseMove = PanelMouseMove;
	m_pContentPanel->OnMouseUp = PanelMouseUp;
	m_pContentPanel->SetBounds( PANEL_BOUND,
								PANEL_TOP,
								Width - m_ToolpalWidth - PANEL_BOUND * 2,
								Height - PANEL_TOP - STATE_HEIGHT);
	m_pContentPanel->Show() ;

	//创建风格面板
	TStylePanel::LoadImages();

	m_pAudStylePanel = new TAudStylePanel(this);
	m_pAudStylePanel->Parent = this;
	m_pAudStylePanel->OnMouseMove = PanelMouseMove;
	m_pAudStylePanel->OnMouseUp = PanelMouseUp;
	m_pAudStylePanel->SetBounds( m_pContentPanel->Width + PANEL_BOUND,
								 m_pContentPanel->Top + m_UseStyleHeight + m_PreStyleHeight,
								 m_ToolpalWidth,
								 m_pContentPanel->Height - m_UseStyleHeight
														- m_PreStyleHeight );

	m_pPreStylePanel = new TPreStylePanel(this);
	m_pPreStylePanel->Parent = this;
	m_pPreStylePanel->OnMouseMove = PanelMouseMove;
	m_pPreStylePanel->OnMouseUp = PanelMouseUp;
	m_pPreStylePanel->SetBounds( m_pAudStylePanel->Left,
								 m_pContentPanel->Top + m_UseStyleHeight,
								 m_ToolpalWidth,
								 m_PreStyleHeight );

	m_pUseStylePanel = new TUseStylePanel(this);
	m_pUseStylePanel->Parent = this;
	m_pUseStylePanel->OnMouseMove = PanelMouseMove;
	m_pUseStylePanel->OnMouseUp = PanelMouseUp;
	m_pUseStylePanel->SetBounds( m_pAudStylePanel->Left,
								 m_pContentPanel->Top,
								 m_ToolpalWidth,
								 m_UseStyleHeight );

	m_pAudStylePanel->Show();
	m_pPreStylePanel->Show();
	m_pUseStylePanel->Show();

	//创建和弦面板
	m_pChordPanel = new TChordPanel(this);
	m_pChordPanel->Parent = this;
	m_pChordPanel->OnMouseMove = PanelMouseMove;
	m_pChordPanel->OnMouseUp = PanelMouseUp;
	m_pChordPanel->SetBounds( m_pContentPanel->Width + PANEL_BOUND,
								 m_pContentPanel->Top,
								 m_ToolpalWidth,
								 m_pContentPanel->Height );

	//创建轨道面板
	m_pTrackPanel = new TTrackPanel(this);
	m_pTrackPanel->Parent = this;
	m_pTrackPanel->OnMouseMove = PanelMouseMove;
	m_pTrackPanel->OnMouseUp = PanelMouseUp;
	m_pTrackPanel->SetBounds( m_pContentPanel->Width + PANEL_BOUND,
								 m_pContentPanel->Top,
								 m_ToolpalWidth,
								 m_pContentPanel->Height );

	m_pContentPanel->SetStylePanel( m_pUseStylePanel );
	m_pContentPanel->SetChordPanel( m_pChordPanel );
	m_pContentPanel->SetTrackPanel( m_pTrackPanel );

	((TUseStylePanel*)m_pUseStylePanel)->SetContentPanel( m_pContentPanel );
	((TChordPanel*)m_pChordPanel)->SetContentPanel( m_pContentPanel );
	((TTrackPanel*)m_pTrackPanel)->SetContentPanel( m_pContentPanel );

	m_pPopMenu = new TMenuPanel(this);
	m_pPopMenu->Parent = this;
 	m_pContentPanel->SetPopMenu( m_pPopMenu );
	TToolpalPanel::SetPopMenu( m_pPopMenu );

	//模拟键盘
	m_KeyBoard = new TKeyBoard(this);
	m_KeyBoard->Visible = false;
	m_KeyBoard->Parent = this;
	m_KeyBoard->Left = m_panelVolLevel->Left + 195;
	m_KeyBoard->Top = m_btnKeyboard->Top - 145;

	f_MM_ActiveAPR( false );

	Screen->Cursors[crBrush] = LoadCursor(HInstance, L"CursorBrush");
	Screen->Cursors[crBrushAdd] = LoadCursor(HInstance, L"CursorBrushAdd");
	Screen->Cursors[crBrushNo] = LoadCursor(HInstance, L"CursorBrushNo");

//	m_pNotificationGetTimer = new TTimer(this); //add by tj 2014/04/18
//	m_pNotificationGetTimer->Interval = NOTIFICATION_GETNOTI_PERIOD;
//	m_pNotificationGetTimer->OnTimer  = NotificationTimerProc;
//	m_pNotificationGetTimer->Enabled = true;

	WindowState = g_iWindowState;
	SetTransparent( this );

	if( g_iToolPanelShow!=0 ){
		int iTPS = g_iToolPanelShow;
		g_iToolPanelShow = 0;
		ShowToolPanels( iTPS );
	}
    else if( WindowState==wsNormal )
		ViewLayout();

	g_strAutoProjName = g_strUserPath;
	g_strAutoProjName += _T(AUTOSAVE_FILENAME);

	bool bWaitScanVST = false;
	CheckVSTScanReg();
	if( !g_strVSTPath.empty() || !g_strVSTiPath.empty() ){
		SplashForm->ShowProgress( "扫描VST插件......" );
		InitVSTList();
	}
	else if( g_bShowVSTPath ){
		bWaitScanVST = true;
		PostMessage(Handle, UM_VSTPATH, 1, 0);
	}

	UnicodeString strParam = ParamStr(1);
	if( !strParam.IsEmpty() ){
		m_strLoadProjectName = strParam.c_str();

		if( !bWaitScanVST )
			PostMessage(Handle, UM_LOADPROJECT, 0, 0);

		SetAutoSaveReg( false );
	}
	else if( g_bAutoSave ){
		if( !bWaitScanVST )
			PostMessage(Handle, UM_OPENAUTOPROJ, 0, 0);
	}
	else if( g_bAutoOpenProject && g_bAutoOpenProjectEnable ){
		DisableAutoOpen();

		String fileName = g_lstRecentProject.begin()->c_str();
		if( FileExists(fileName) ){
			m_strLoadProjectName = fileName;
			if( !bWaitScanVST )
				PostMessage(Handle, UM_LOADPROJECT, 0, 0);
		}
		else{
			g_lstRecentProject.erase( g_lstRecentProject.begin() );
			PostMessage(Handle, UM_NEWPROJECT, 0, 0);
		}
	}
	else{
		PostMessage(Handle, UM_NEWPROJECT, 0, 0);
	}

	Screen->Cursor = crDefault;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnViewMode(TObject *Sender)
{
	int index = (int)Sender;

	if( index==3 ){
		m_pContentPanel->SetScrollMode( !m_pContentPanel->IsVertical() );

		if( m_pContentPanel->IsVertical() )
			ViewLayout();
	}
	else{
		SetMode( index+1 );

		if( g_iToolPanelShow & 0x02 ){
			ShowToolPanels( g_iToolPanelShow & 0x01 );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMSetViewMode(TMessage &Message)
{
	int index = Message.WParam;

	SetMode( index );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SetMode( int iMode, bool bForce )
{
	if( m_btnRecord->Down )
		return;

	if( g_Theme.Empty() )// g_lstRawBars.size()==0 )
		iMode = VIEW_INIT;

	if( !bForce && g_iViewMode==iMode )
		return;

	g_iViewMode = iMode;

	m_pContentPanel->SetMode( iMode );

	if( iMode==VIEW_INIT ){
		g_bPredefine = false;
		g_bMidiMelody = false;
		g_bComposeMute = false;

		m_iStartBar = m_iLastStartBar = 0;
		m_dblStartPoint = m_dblLastStartPoint = 0;
		m_dwLastVol = 0;
		m_pContentPanel->InitialVars( true );
		//m_pContentPanel->SetScrollMode( true );
		//m_pContentPanel->SetPlayPoint( 0, 0 );
		ShowPlayTime();

		m_tabStyle->Down = true;
		m_tabStyle->BringToFront();
		m_tabChord->Down = false;
		m_tabAudio->Down = false;
		m_tabAudio->SendToBack();

		g_iMelodyKey = -1;
		m_cbKey->DefItemIndex = -1;
		m_cbKey->Enabled = false;

		if( !g_pPreStyle )
			((TStylePanel*)m_pPreStylePanel)->InitItems();
		((TUseStylePanel*)m_pUseStylePanel)->InitOpus( NULL, -1 );

		if( g_Undo.GetUndoType()<0 ){
			//add by tj 2014/05/15
			if( (0<=g_iPreStageDefault) && (g_iPreStageDefault<=2) ){
				m_cbPreStage->DefItemIndex = g_iPreStage = g_iPreStageDefault;
			}else{
				g_iPreStage = g_iPreStageDefault = 2;
			}
		}

		m_PreStyleHeight = m_PreStyleHeight + m_UseStyleHeight - TOOLPAL_MINHEIGHT;
		m_UseStyleHeight = TOOLPAL_MINHEIGHT;

		m_pUseStylePanel->SetBounds( m_pUseStylePanel->Left,
									 PANEL_TOP,
									 m_ToolpalWidth,
									 m_UseStyleHeight );

		m_pPreStylePanel->SetBounds( m_pUseStylePanel->Left,
									 m_pUseStylePanel->Top + m_UseStyleHeight,
									 m_ToolpalWidth,
									 m_PreStyleHeight );

		m_btnPlay->Enabled = false;
		m_btnSave->Enabled = false;
		m_btnUpload->Enabled = false;
		m_tabChord->Enabled = false;
		m_tabAudio->Enabled = false;

		m_pContentPanel->SetFocus();
	}
	else{
		m_tabChord->Enabled = true;
		m_tabAudio->Enabled = true;

		if( iMode==VIEW_TRACK ){
			m_tabStyle->Down = false;
			m_tabChord->Down = false;
			m_tabChord->SendToBack();
			m_tabAudio->Down = true;
			m_tabAudio->BringToFront();
		}
		else if( iMode==VIEW_CHORD ){
			g_iSelAudio = -1;
			m_tabStyle->Down = false;
			m_tabChord->Down = true;
			m_tabChord->BringToFront();
			m_tabAudio->Down = false;
			m_tabAudio->SendToBack();
		}
		else if( iMode==VIEW_STYLE ){
			g_iSelAudio = -1;
			m_tabStyle->Down = true;
			m_tabStyle->BringToFront();
			m_tabChord->Down = false;
			m_tabAudio->Down = false;
			m_tabAudio->SendToBack();
		}
	}

	m_btnRecord->Enabled = RecordEnabled();

	if( g_iToolPanelShow<2 ){
		m_pUseStylePanel->Visible = iMode==VIEW_STYLE || iMode==VIEW_INIT;
		m_pPreStylePanel->Visible = iMode==VIEW_STYLE || iMode==VIEW_INIT;
		m_pAudStylePanel->Visible = iMode==VIEW_STYLE || iMode==VIEW_INIT;

		m_pChordPanel->Visible = iMode==VIEW_CHORD;
		m_pTrackPanel->Visible = iMode==VIEW_TRACK;
//		if( iMode==VIEW_TRACK )
//			((TTrackPanel*)m_pTrackPanel)->ResetSelPos();
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CreateMenus()
{
	m_pMenuBar = new TMenuBar( this,Canvas );

	m_pMenuBar->AddMenu( "文件", "F", MENU_FILE );
	m_pMenuBar->AddMenu( "编辑", "E", MENU_EDIT );
	m_pMenuBar->AddMenu( "视图", "V", MENU_VIEW );
	m_pMenuBar->AddMenu( "轨道", "K", MENU_TRACK );
	m_pMenuBar->AddMenu( "工具", "T", MENU_TOOL );
	m_pMenuBar->AddMenu( "帮助", "H", MENU_HELP );

	TMenuPanel::LoadResources();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnShowMenu(TMessage &msg)
{
	int iType = msg.WParamLo;
	bool bShow = msg.WParamHi;
	int left = msg.LParamLo;
	int top = msg.LParamHi;

	if( m_pMenu && ( !bShow && ( m_pMenu->Type==iType )
					 ||	bShow && m_pMenu->Type!=iType )){
		m_pMenu->Hide();
		delete m_pMenu;
		m_pMenu = NULL;
	}

	if( bShow && !m_pMenu ){
		m_pMenu = new TMenuPanel( this, iType );
		m_pMenu->Parent = this;

		if( iType==MENU_FILE ){ //创建文件菜单
			CMenuItem* pMenuItem = m_pMenu->CreateMenu( "新建工程" );
			pMenuItem->Enabled = !m_btnRecord->Down;
			if( pMenuItem->Enabled ){
				pMenuItem->AppendMenu( "空白工程", "F5", OnCreateNewProject );
				pMenuItem->AppendMenu( "导入主旋律...", "F12", OnLoadMelody );
				pMenuItem->AppendMenu( "预定义工程...", "", OnPredefineProject );
			}

			pMenuItem = m_pMenu->CreateMenu( "打开工程...", "F2", OnLoadProject, IDM_OPENPROJECT-1 );
			pMenuItem->Enabled = !m_btnRecord->Down;
			//index = m_pMenu->CreateMenuItem("打开工程...", "F2", OnLoadProject, IDM_OPENPROJECT-1 );
			//m_pMenu->EnabledMenuItem(index, !m_btnRecord->Down);

			pMenuItem = m_pMenu->CreateMenu( "打开最近工程" );
			pMenuItem->Enabled = !g_lstRecentProject.empty() && !m_btnRecord->Down;
			if( pMenuItem->Enabled ){
				for (int i = 0; i < g_lstRecentProject.size(); i++) {
					String strText = g_lstRecentProject[i].c_str();
					pMenuItem->AppendMenu( strText, "", OnLoadProject, IDM_OPENPROJECT+i );
				}
			}

			pMenuItem = m_pMenu->CreateMenu( "保存工程", "F3", OnSaveProject );
			pMenuItem->Enabled = HasProjectModified() && !m_btnRecord->Down;

			pMenuItem = m_pMenu->CreateMenu( "导出为...", "F4", OnSaveAs );
			pMenuItem->Enabled = g_lstOpusStages.size()>0 && !m_btnRecord->Down;

			m_pMenu->CreateMenu( "-" );
			m_pMenu->CreateMenu( "退出", "", CloseClick );
		}
		else if( iType==MENU_EDIT ){ //创建编辑菜单
			String strText = "撤销 ";
			int iOp = g_Undo.GetUndoType(),
				iT1 = ( iOp>>4 ),
				iT2 = ( iOp & 0x0F );

			if( iOp>=0 )
				strText += g_strUndoType[iT1][iT2];

			CMenuItem* pMenuItem = m_pMenu->CreateMenu( strText, "Ctrl+Z", OnUndo );
			pMenuItem->Enabled = iOp>=0 && !m_btnRecord->Down;

			strText = "重做 ";
			iOp = g_Undo.GetRedoType();
			iT1 = ( iOp>>4 );
			iT2 = ( iOp & 0x0F );

			if( iOp>=0 )
				strText += g_strUndoType[iT1][iT2];

			pMenuItem = m_pMenu->CreateMenu( strText, "Ctrl+Shift+Z", OnRedo );
			pMenuItem->Enabled = iOp>=0 && !m_btnRecord->Down;

			if( m_pContentPanel )
				m_pContentPanel->CreateEditMenu(m_pMenu, !m_btnRecord->Down);
		}
		else if( iType==MENU_VIEW ){ //创建视图菜单
			CMenuItem* pMenuItem = m_pMenu->CreateMenu( "轨道", "F9", OnViewMode, 0 );
			pMenuItem->Enabled = !g_Theme.Empty() && !m_btnRecord->Down;

			pMenuItem = m_pMenu->CreateMenu( "和弦", "F10", OnViewMode, 1 );
			pMenuItem->Enabled = !g_Theme.Empty() && !m_btnRecord->Down;

			pMenuItem = m_pMenu->CreateMenu( "风格", "F11", OnViewMode, 2 );
			pMenuItem->Enabled = !m_btnRecord->Down;

			m_pMenu->CreateMenu("-");

			String strText = m_pContentPanel->IsVertical() ? "显示MIDI轨道(横向)"
														: "不显示MIDI轨道(纵向)";
			pMenuItem = m_pMenu->CreateMenu( strText, "Ctrl+Tab", OnViewMode, 3 );
			pMenuItem->Enabled = !m_btnRecord->Down && g_iViewMode!=VIEW_INIT;

			m_pMenu->CreateMenu("-");

			if( g_iToolPanelShow & 0x2 ){
				m_pMenu->CreateMenu( "显示工具面版", "", OnShowToolPanels );
			}
			else{
				m_pMenu->CreateMenu( "隐藏工具面版", "", OnShowToolPanels );
				if( g_iToolPanelShow==0 )
					m_pMenu->CreateMenu( "左边显示工具面板", "", OnShowToolPanels, 0 );
				else
					m_pMenu->CreateMenu( "右边显示工具面板", "", OnShowToolPanels, 0 );
			}
		}
		else if( iType==MENU_TRACK ){
			if(m_pContentPanel != NULL){
				m_pContentPanel->CreateTrackMenu(m_pMenu, !m_btnRecord->Down);
			}
		}
		else if( iType==MENU_TOOL ){ //创建工具菜单
			m_pMenu->CreateMenu( "模拟键盘", "F6", OnKeyBoard);
			m_pMenu->CreateMenu( "音量设置", "F7", VolSetClick);

			CMenuItem* pMenuItem = m_pMenu->CreateMenu( "音频设备设置...", "F8", OnMicSetting );
			pMenuItem->Enabled = !m_btnRecord->Down;

			m_pMenu->CreateMenu("-");
			m_pMenu->CreateMenu("偏好设置...","",OnCustomerSetting);
			m_pMenu->CreateMenu("VST路径设置...","",OnVSTPathSetting);
		}
		else if( iType==MENU_HELP ){ //创建帮助菜单
			m_pMenu->CreateMenu("帮助中心", "F1", OnUserHelp);
			m_pMenu->CreateMenu("用户手册", "", OnUserManual);
			m_pMenu->CreateMenu("更多软件...", "", OnShowMore);
//			m_pMenu->CreateMenu("唱作网动态", "", OnNotification);
			m_pMenu->CreateMenu("-");
			m_pMenu->CreateMenu("关于...", "", OnAbout);
		}

		m_pMenu->Show( left, top );
	}
}
// ---------------------------------------------------------------------------
/*
void __fastcall TMainForm::OnMenuCall(TMessage &msg)
{
	m_pMenuBar->Reset();

	TNotifyEvent* CallProc = (TNotifyEvent*)msg.LParam;
	(*CallProc)( (TObject*)msg.WParam );
}
// ---------------------------------------------------------------------------
*/
void __fastcall TMainForm::OnMenuClose(TMessage & Msg)
{
	if( m_pMenuBar )
		m_pMenuBar->Reset();
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::FormResize(TObject *Sender)
{
	switch (WindowState) {
	case wsMaximized:
	case wsNormal: {
			Canvas->Lock();

			m_btnClose->Left = Width - 12 - m_btnClose->Width;
			m_btnMax->Left = m_btnClose->Left - 27;
			m_btnRest->Left = m_btnClose->Left - 27;
			m_btnMin->Left = m_btnMax->Left - 27;

			m_lblLogon->Left = m_btnMin->Left - OFFSET_BR*2 - m_lblLogon->Width - 21;
			m_pbUserNoticeNum->Left = m_lblLogon->Left + m_lblLogon->Width;

			if(m_pMenuBar)
				m_lblTitle->Left = MENUBAR_LEFT + m_pMenuBar->Width + OFFSET_BR*2;
			m_lblTitle->Width = m_lblLogon->Left - m_lblTitle->Left;
			m_lblWebsite->Left = Width - m_lblWebsite->Width - 14;

			m_btnVolSet->Top = Height - STATE_HEIGHT + 2;
			m_panelVolLevel->Top = Height - STATE_HEIGHT + 3;
			m_cbFontSelect->Top = Height - STATE_HEIGHT + 2;
			m_btnKeyboard->Top = Height - STATE_HEIGHT - 2;
			m_btnExtFontOn->Top = m_btnKeyboard->Top + 3;
			m_btnExtFontOff->Top = m_btnExtFontOn->Top;
			m_lblExtFont->Top = m_btnExtFontOn->Top + 5;
			m_lblWebsite->Top = m_lblExtFont->Top + 6;

			if(m_KeyBoard)
				m_KeyBoard->Top = m_btnKeyboard->Top - 145;

			if (WindowState == wsMaximized) {
				Align = alClient;
				m_btnMax->Visible = false;
				m_btnRest->Visible = true;
			}
			else {
				Align = alNone;
				m_btnMax->Visible = true;
				m_btnRest->Visible = false;
			}

			if(m_pContentPanel)
				ViewLayout();

			Canvas->Unlock();

			Invalidate();
		}

		break;

	default:
		break;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ViewLayout()
{
	bool bVertical = m_pContentPanel->IsVertical();
	int wContent = Width - m_ToolpalWidth - PANEL_BOUND * 2 - 10,
		hContent = Height - PANEL_TOP - STATE_HEIGHT,
		offset = bVertical && m_pContentPanel->GetBarNum()>0 ? wContent % POINTS_PER_BAR : 0,
		lContent = PANEL_BOUND,
		lToolPanel = PANEL_BOUND;

	if( offset > (POINTS_PER_BAR>>1) && (m_ToolpalWidth-offset)>=TOOLPAL_MINWIDTH ){
		wContent += POINTS_PER_BAR - offset;
		m_ToolpalWidth -= POINTS_PER_BAR - offset;
	}
	else{
		wContent -= offset;
		m_ToolpalWidth += offset;
	}

	wContent += 10;

	int wRealContent = wContent;
	if( g_iToolPanelShow & 0x02 ){
		wRealContent += m_ToolpalWidth;
	}
	else{
		if( g_iToolPanelShow & 0x01 ){
			lContent = m_ToolpalWidth + PANEL_BOUND;
			m_tabStyle->Left = PANEL_BOUND + 7;
			m_tabChord->Left = m_tabStyle->Left + 41;
			m_tabAudio->Left = m_tabChord->Left + 41;

		}
		else{
			lToolPanel = wContent + PANEL_BOUND;
			m_tabStyle->Left = Width-144;
			m_tabChord->Left = m_tabStyle->Left + 41;
			m_tabAudio->Left = m_tabChord->Left + 41;
		}

		m_pChordPanel->SetBounds( lToolPanel,
									 PANEL_TOP,
									 m_ToolpalWidth,
									 hContent );

		m_pTrackPanel->SetBounds( lToolPanel,
									 PANEL_TOP,
									 m_ToolpalWidth,
									 hContent );

		int hAud = hContent - m_UseStyleHeight - m_PreStyleHeight;
		if( hAud<TOOLPAL_MINHEIGHT )
			hAud = TOOLPAL_MINHEIGHT;

		int hPre = hContent - m_UseStyleHeight - hAud;
		if( hPre<TOOLPAL_MINHEIGHT )
			hPre = TOOLPAL_MINHEIGHT;

		int hUse = hContent - hAud - hPre;
		if( hUse<TOOLPAL_MINHEIGHT ){
			hAud -= TOOLPAL_MINHEIGHT - hUse;
			hUse = TOOLPAL_MINHEIGHT;
			hPre = hContent - hAud - hUse;
		}

		m_UseStyleHeight = hUse;
		m_PreStyleHeight = hPre;

		m_pUseStylePanel->SetBounds( lToolPanel,
									 PANEL_TOP,
									 m_ToolpalWidth,
									 m_UseStyleHeight );

		m_pPreStylePanel->SetBounds( lToolPanel,
									 m_pUseStylePanel->Top + m_UseStyleHeight,
									 m_ToolpalWidth,
									 m_PreStyleHeight );

		m_pAudStylePanel->SetBounds( lToolPanel,
									 m_pPreStylePanel->Top + m_PreStyleHeight,
									 m_ToolpalWidth,
									 hContent - m_UseStyleHeight - m_PreStyleHeight );
	}

	m_pContentPanel->SetBounds( lContent,
								PANEL_TOP,
								wRealContent,
								hContent );

	m_btnRecord->Left = lContent + 25;
	m_btnPlay->Left = m_btnRecord->Left + 40;
	m_btnPause->Left = m_btnPlay->Left;
	m_btnStop->Left = m_btnPlay->Left + 40;
	m_pPlayTimePanel->Left = m_btnStop->Left + 42;
	m_cbKey->Left = m_btnStop->Left + 130;
	m_btnTS->Left = m_cbKey->Left + m_cbKey->Width;
	m_btnTempo->Left = m_btnTS->Left + m_btnTS->Width;
	m_cbPreStage->Left = m_btnTempo->Left + m_btnTempo->Width;

	m_btnUpload->Left = lContent + wContent - m_btnUpload->Width - 4;//m_btnSave->Left + 43;
	m_btnSave->Left = m_btnUpload->Left - 43;
	m_btnOpen->Left = m_btnSave->Left - 43;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CloseClick(TObject *Sender)
{
	Close();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
	if( m_pPreStylePanel && ((TPreStylePanel*)m_pPreStylePanel)->CheckModified() ){
		int mrRet = MessageForm->ShowMessage("是否保存预编风格到本地？",
											MB_ICONQUESTION | MB_YESNOCANCEL);

		if( mrRet==mrYes ){
			Perform( UM_SAVELOCALSTYLE, 0, 0 );
		}
		else if( mrRet==mrCancel ){
			CanClose = false;
			return;
		}
	}

	if( HasProjectModified() && g_lstOpusStages.size()>0 ) {
		int mrRet = MessageForm->ShowMessage("是否保存当前工程？",
											MB_ICONQUESTION | MB_YESNOCANCEL);
		if (mrRet == mrYes) {
			DebugPrint("确认保存");
			OnSaveProject(NULL);
		}
		else if (mrRet == mrCancel) {
			CanClose = false;
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
	ClearCDTimer();

	if( g_bLogon ){
		f_CS_Logoff();
	}

	if( m_pPopMenu ){
		m_pPopMenu->Hide();
		m_pPopMenu->Parent = NULL;
		delete m_pPopMenu;
		m_pPopMenu = NULL;
	}

	if( m_pContentPanel ){
		StopClick(NULL);
		SetInitVar(true);
	}

	if( m_pNotificationGetTimer ){
		delete m_pNotificationGetTimer;
		m_pNotificationGetTimer = NULL;
	}
	if( m_pNotificationForm ) {
		delete m_pNotificationForm;
		m_pNotificationForm = NULL;
	}

//// 自动保存 //////////
	ClearAutoProj();
/////////////////////////

	if( m_pContentPanel ){
		delete m_pContentPanel;
		m_pContentPanel = NULL;
	}

	if (m_pMenuBar){
		delete m_pMenuBar;
		m_pMenuBar = NULL;
	}
	TMenuPanel::FreeResources();

	if( m_pUseStylePanel ){
		delete m_pUseStylePanel;
		m_pUseStylePanel = NULL;
	}

	if( m_pPreStylePanel ){
		delete m_pPreStylePanel;
		m_pPreStylePanel = NULL;
	}

	if( m_pAudStylePanel ){
		delete m_pAudStylePanel;
		m_pAudStylePanel = NULL;
	}

	if( m_pChordPanel ){
		delete m_pChordPanel;
		m_pChordPanel = NULL;
	}

	if( m_pTrackPanel ){
		delete m_pTrackPanel;
		m_pTrackPanel = NULL;
	}

	TStylePanel::FreeImages();

	HRESULT hr;

	if (f_CS_DestroyService) {
		if (FAILED(hr = f_CS_DestroyService())) {
			DebugPrint("Destroy client service failed! code=%x\n", hr);
		}
	}

	if (f_MM_DestroyObjects) {
		if (FAILED(hr = f_MM_DestroyObjects())) {
			DebugPrint("Destroy media module Failed! code=%x\n", hr);
		}
	}

	if (f_CM_Release) {
		if (FAILED(hr = f_CM_Release())) {
			DebugPrint("Relase compose module failed! code=%x\n", hr);
		}
	}

	if( m_HelpForm ){
		delete m_HelpForm;
		m_HelpForm = NULL;
	}

	ClearFontList();
	ClearVSTList();
	ClearStyleList();

	CloseHandle(g_hProjectEvent);

	for(int i=0; i<g_lstMacAddress.size(); i++) {
		SAFE_DELETE(g_lstMacAddress[i])
	}
	g_lstMacAddress.clear();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::MaxClick(TObject *Sender)
{
	WindowState = wsMaximized;
	g_iWindowState = WindowState;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::MinClick(TObject *Sender)
{
	WindowState = wsMinimized;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::RestClick(TObject *Sender)
{
	WindowState = wsNormal;
	g_iWindowState = WindowState;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::WMNCHitTest(TWMNCHitTest &Msg)
{
	TForm::Dispatch(&Msg);

	if( Msg.Result==HTCLIENT && !m_pMenuBar->HitTest(Msg.XPos-Left, Msg.YPos-Top)){
		if( Msg.YPos<Top+BREAK_LINE_Y-2 && Msg.XPos < Left + m_lblLogon->Left
							&& Msg.XPos > Left + m_pMenuBar->Width + OFFSET_BR + 3 )
			Msg.Result = HTCAPTION;
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::WMNCLButtonDown(TWMNCLButtonDown &Msg)
{
	if (Msg.HitTest == HTCAPTION ) {
		m_pMenuBar->HitTest( Msg.XCursor-Left, Msg.YCursor-Top, true );
	}

	TForm::Dispatch(&Msg);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::WMNCRButtonDown(TWMNCRButtonDown &Msg)
{
	if (Msg.HitTest == HTCAPTION ) {
		m_pMenuBar->HitTest( Msg.XCursor-Left, Msg.YCursor-Top, true );
	}

//	TForm::Dispatch(&Msg);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::WMWindowPosChanged(TWMWindowPosChanged &Msg)
{
	if( m_HelpForm ){
		if( m_HelpForm->Window_state==HLP_WINDOW_MIN ){
			m_HelpForm->Left = Msg.WindowPos->x + Msg.WindowPos->cx - 160;
			m_HelpForm->Top = Msg.WindowPos->y + Msg.WindowPos->cy - 34;
		}
		else if( m_HelpForm->Window_state==HLP_WINDOW_MAX ){
			m_HelpForm->SetBounds( Msg.WindowPos->x,
									Msg.WindowPos->y + STATE_HEIGHT,
									Msg.WindowPos->cx,
									Msg.WindowPos->cy - STATE_HEIGHT );
		}
	}

	TForm::Dispatch(&Msg);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::WMNCLButtonDblClk(TWMNCLButtonDblClk &Msg)
{
	if (Msg.HitTest == HTCAPTION ) {
		if (WindowState == wsNormal) {
			WindowState = wsMaximized;
		}
		else
			WindowState = wsNormal;

		g_iWindowState = WindowState;
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnRestoreWindow(TMessage &msg)
{
	if (WindowState == wsMinimized) {
		WindowState = g_iWindowState;
	}

	FormStyle = fsStayOnTop;
	Application->BringToFront();
	FormStyle = fsNormal;
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnNetworkError(TMessage &msg)
{
	WORD eMessage = HIWORD(msg.WParam);
	WORD eExtra = LOWORD(msg.WParam);

	DebugPrint("网络访问错误，消息号：%d，错误号：0x%X\n", eMessage, eExtra);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnNetworkMessage(TMessage &msg)
{
	WORD eMessage = HIWORD(msg.WParam);
	WORD eExtra = LOWORD(msg.WParam);

	if(eMessage == e_loginResponse){
		if(eExtra == 0){
            DebugPrint(
				"用户信息：\nID=%d\n 昵称: %s\n账户余额：%d\n权限：0x%X\n已购买风格数：%d\n头像: %s\nVIP: %d\n",
				g_infoUser.accountInfo.ID,
                g_infoUser.strNickName,
                g_infoUser.accountInfo.balance,
//                g_infoUser.accountInfo.pops,
//				g_infoUser.accountInfo.fans,
//				g_infoUser.accountInfo.songs,
				g_infoUser.accountInfo.authority,
				g_infoUser.ownStyleNum,
				g_infoUser.strIconFile,
				g_infoUser.accountInfo.vipPeriod);

            m_lblLogon->Caption = String(g_infoUser.strNickName);
            m_lblLogon->Tag = 2; // 登录成功
			m_lblLogon->Hint = String(g_infoUser.strNickName);

			g_bLogon = true;

            // 显示标记
			int nUser = f_CS_GetNewNoticeNum( g_infoUser.accountInfo.ID );
			int nPublic = f_CS_GetNewNoticeNum( 0 );

			if(nUser > 0 || nPublic > 0) {
				if(!m_pbUserNoticeNum->Visible)
					m_pbUserNoticeNum->Visible = true;

				m_pbUserNoticeNum->Tag = nUser + nPublic;
				m_pbUserNoticeNum->Refresh();

				String strNoticeHint = "有 ";
				if( nPublic>0 ){
					strNoticeHint += nPublic;
					strNoticeHint += " 条网站最新公告";
					if( nUser>0 ){
						strNoticeHint += "\n和 ";
					}
				}

				if( nUser>0 ){
					strNoticeHint += nUser;
					strNoticeHint += " 条未读个人消息\n请点击查看";
				}

				m_pbUserNoticeNum->Hint = strNoticeHint;
			}
			else {
				if(m_pbUserNoticeNum->Visible)
					m_pbUserNoticeNum->Visible = false;
			}

//			if( m_HelpForm ){
 //				m_HelpForm->SetNoticeNum( noticeNum, 0 );
//				m_HelpForm->SetNoticeNum( zoneNum, 1 );
//			}
			g_bRecProtect = IsProtected();
			f_MM_SetRecordProtect( g_bRecProtect );
			((TAudStylePanel*)m_pAudStylePanel)->ReloadLocalStyle( false );
		}
		else{
			// 登录失败
			g_infoUser.strPassword[0] = 0;

			if(eExtra == e_LoginPasswordError || eExtra == e_LoginUserNotExist || eExtra==e_VipExceeded
													|| eExtra==e_UserLocked || eExtra == e_UserDeleted) {
            	m_lblLogon->Tag = 0;
				m_lblLogon->Caption = L"点击登录";
                m_lblLogon->Hint = L"点击登录或注册";
				ShowErrorMessage( eExtra, "登录失败!" );
            	//MessageForm->ShowMessage(L"密码错误或用户名不存在!", MB_ICONERROR | MB_OK);
				PostMessage(Handle, UM_LOGIN, 0, 0);
			}
        }
	}
	else if( eMessage==e_versionResponse ){       //add by laq 2014.1.22
		if (eExtra == e_DatabaseError) {
			DebugPrint("服务器数据访问失败！\n");
		}
		else {
			if (eExtra == e_UpdateMandatory || eExtra == e_UpdateOptional) {
				int year = g_infoSoftwareUpdate.tIssueDate >> 16;
				int month = (g_infoSoftwareUpdate.tIssueDate & 0xFF00) >> 8;
				int day = g_infoSoftwareUpdate.tIssueDate & 0xFF;

				string sDescribe = UTF8ToMBCS(g_infoSoftwareUpdate.strDescribe);

				DebugPrint(
					"最新的客户端版本：Ver %d.%d.%d.%04d\n发布时间：%d-%d-%d\n文件大小：%dK\n文件描述：%s\n",
					g_infoSoftwareUpdate.version.majorVersion,
					g_infoSoftwareUpdate.version.minorVersion,
					g_infoSoftwareUpdate.version.modifyVersion,
					g_infoSoftwareUpdate.version.buildVersion, year, month, day,
					g_infoSoftwareUpdate.nFileSize, sDescribe.c_str());

				if (eExtra == e_UpdateMandatory) {
					DebugPrint("该版本为强制更新版。\n\n");

					Logout();

					g_bUpdateMandatory = true;
					m_lblLogon->Visible = false;
					m_btnUpload->Enabled = false;
				}

				// don't display the update information while new user operator the software first
				UpdateForm = new TUpdateForm(NULL);
				UpdateForm->ShowModal();
				delete UpdateForm;
			}
		}

	}
	else if( eMessage==e_noticeUpdateResponse ) {
		if (eExtra == 0) {
			WORD idUser = HIWORD(msg.LParam);
			WORD nUnchecked = LOWORD(msg.LParam);

			int nUser = 0;

			if(g_bLogon)
				nUser = f_CS_GetNewNoticeNum( g_infoUser.accountInfo.ID );

			int nPublic = f_CS_GetNewNoticeNum( 0 );

			if( nUser>0 || nPublic>0 ){
				m_pbUserNoticeNum->Tag = nUser + nPublic;

				if( !m_pbUserNoticeNum->Visible ){
					m_pbUserNoticeNum->Visible = true;
				}
				else{
					m_pbUserNoticeNum->Invalidate();
				}

				String strNoticeHint = "有 ";
				if( nPublic>0 ){
					strNoticeHint += nPublic;
					strNoticeHint += " 条网站最新公告";
					if( nUser>0 ){
						strNoticeHint += "\n和 ";
					}
				}

				if( nUser>0 ){
					strNoticeHint += nUser;
					strNoticeHint += " 条未读个人消息\n请点击查看";
				}

				m_pbUserNoticeNum->Hint = strNoticeHint;
			}
			else{
				m_pbUserNoticeNum->Visible = false;
			}

//			if( m_HelpForm ){
//				m_HelpForm->SetNoticeNum( iNotice, 0 );
//				m_HelpForm->SetNoticeNum( iUser, 1 );
//			}
		}
	}
	else if( eMessage==e_logoffResponse ){
		m_lblLogon->Caption = L"点击登录";
		m_lblLogon->Tag = 0;
		m_lblLogon->Hint = L"点击登录或注册";

		if( !strcmp( g_infoSong.strSinger, g_infoUser.strNickName ) )
			g_infoSong.strSinger[0] = '\0';
		if( !strcmp( g_infoSong.strLyricist, g_infoUser.strNickName ) )
			g_infoSong.strLyricist[0] = '\0';
		if( !strcmp( g_infoSong.strComposer, g_infoUser.strNickName ) )
			g_infoSong.strComposer[0] = '\0';
		if( !strcmp( g_infoSong.strArranger, g_infoUser.strNickName ) )
			g_infoSong.strArranger[0] = '\0';

		char strName[80];
		strcpy(strName, g_infoUser.strUserName);
		memset(&g_infoUser, 0, sizeof(g_infoUser));
		strcpy(g_infoUser.strUserName, strName);

		if(m_pbUserNoticeNum->Visible)
			m_pbUserNoticeNum->Visible = false;

		if( m_HelpForm ){
			m_HelpForm->SetNoticeNum( 0, 1 );
		}

		g_bLogon = false;
	}
	else if( eMessage==e_styleDataResponse || eMessage==e_styleInfoResponse
							|| eMessage==e_styleRecomResponse ){
		m_pAudStylePanel->Perform( MSG_NETWORKMESSAGE, msg.WParam, msg.LParam );

		if( eMessage==e_styleDataResponse && eExtra == 0 && !g_pPreStyle ){
			((TPreStylePanel*)m_pPreStylePanel)->SetPreStyle( 0, msg.LParam );
		}
	}
}

void __fastcall TMainForm::FormPaint(TObject *Sender)
{
	//绘制菜单栏
	if( m_pMenuBar ){
		m_pMenuBar->DrawMenuBar();

		//绘制分区线
		TColor clrOldPen = Canvas->Pen->Color;

		int xL = MENUBAR_LEFT + m_pMenuBar->Width + OFFSET_BR,
			xR = m_btnMin->Left - 3 - OFFSET_BR,
			h = m_pMenuBar->GetHeight(),
			xP = m_pPlayTimePanel->Left + m_pPlayTimePanel->Width + OFFSET_BR,
			yP = m_pPlayTimePanel->Top,
			hP = m_pPlayTimePanel->Height;

		Canvas->Pen->Color = CLR_BR_OUT;
		Canvas->MoveTo( 0, BREAK_LINE_Y-1 );
		Canvas->LineTo( Width, BREAK_LINE_Y-1 );
		Canvas->MoveTo( 0, BREAK_LINE_Y+1 );
		Canvas->LineTo( Width, BREAK_LINE_Y+1 );

		Canvas->MoveTo( xL, MENUBAR_TOP+3 );
		Canvas->LineTo( xL, MENUBAR_TOP+h-2 );
		Canvas->MoveTo( xL+2, MENUBAR_TOP+3 );
		Canvas->LineTo( xL+2, MENUBAR_TOP+h-2 );

		Canvas->MoveTo( xR, MENUBAR_TOP+3 );
		Canvas->LineTo( xR, MENUBAR_TOP+h-2 );
		Canvas->MoveTo( xR+2, MENUBAR_TOP+3 );
		Canvas->LineTo( xR+2, MENUBAR_TOP+h-2 );

		Canvas->MoveTo( xP, yP+3 );
		Canvas->LineTo( xP, yP+hP-2 );
		Canvas->MoveTo( xP+2, yP+3 );
		Canvas->LineTo( xP+2, yP+hP-2 );

		Canvas->Pen->Color = CLR_BR_IN;
		Canvas->MoveTo( 0, BREAK_LINE_Y );
		Canvas->LineTo( Width, BREAK_LINE_Y );

		Canvas->MoveTo( xL+1, MENUBAR_TOP+3 );
		Canvas->LineTo( xL+1, MENUBAR_TOP+h-2 );
		Canvas->Pixels[xL+1][MENUBAR_TOP+2] = CLR_BR_FILL;
		Canvas->Pixels[xL+1][MENUBAR_TOP+h-2] = CLR_BR_FILL;

		Canvas->MoveTo( xR+1, MENUBAR_TOP+3 );
		Canvas->LineTo( xR+1, MENUBAR_TOP+h-2 );
		Canvas->Pixels[xR+1][MENUBAR_TOP+2] = CLR_BR_FILL;
		Canvas->Pixels[xR+1][MENUBAR_TOP+h-2] = CLR_BR_FILL;

		Canvas->MoveTo( xP+1, yP+3 );
		Canvas->LineTo( xP+1, yP+hP-2 );
		Canvas->Pixels[xP+1][yP+2] = CLR_BR_FILL;
		Canvas->Pixels[xP+1][yP+hP-2] = CLR_BR_FILL;

		Canvas->Pen->Color = clrOldPen;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormMouseDown(TObject *Sender, TMouseButton Button,
							TShiftState Shift, int X, int Y)
{
	m_pMenuBar->HitTest( X, Y, true );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::WMEraseBkgnd(Winapi::Messages::TWMEraseBkgnd &Message)
{
	TRect rect = GetClientRect();
	TRect rectFill = rect;

	TCanvas* tempCanvas = new TCanvas;
	tempCanvas->Handle = Message.DC;

	//绘制上部底色
	rectFill.Bottom = rect.Height() - STATE_HEIGHT - 1;
	tempCanvas->Brush->Color = CLR_TOP;
	tempCanvas->FillRect( rectFill );

	//绘制下部底色
	rectFill.Top = rectFill.Bottom;//rect.Height() - 41;
	rectFill.Bottom = rect.Bottom;
	tempCanvas->Brush->Color = CLR_BOTTOM;
	tempCanvas->FillRect(rectFill);

	delete tempCanvas;

	Message.Result = true;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::LogonMouseEnter(TObject *Sender)
{
	m_lblLogon->Font->Color = CLR_TEXT_HOT;
	m_lblLogon->Font->Style = TFontStyles()<<fsUnderline;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::LogonMouseLeave(TObject *Sender)
{
	m_lblLogon->Font->Color = CLR_TEXT_NOR;
	m_lblLogon->Font->Style = TFontStyles();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CreateParams(TCreateParams &Params)
{
	TForm::CreateParams(Params);

	wcscpy(Params.WinClassName, (LPCTSTR)APPNAME);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnSaveProject(TObject *Sender)
{
/*	int ret = CanSaveProj();
	if( ret==E_PROJ_NOLOCALTEMPSTYLE ){ //使用了非本地的自制风格
		MessageForm->ShowMessage( "当前工程使用了未知风格，无法保存！",
												MB_ICONERROR | MB_OK, "保存工程" );
		return;
	}

	if( ret==E_PROJ_UNSAVEDTEMPSTYLE ){ //自制风格尚未保存，提示保存
*/
	if( CanSaveProj()==E_PROJ_UNSAVEDTEMPSTYLE ){ //自制风格尚未保存，提示保存
		if( mrOk==MessageForm->ShowMessage( "请先保存正在编辑的自制风格！",
												MB_ICONQUESTION | MB_OKCANCEL, "保存工程" )){
			Application->MainForm->Perform( UM_SAVELOCALSTYLE, 0, 0 );
		}
		else{
			return;
		}
	}

	if( g_strProjectName.length()==0 ){
		SaveAs( SAVE_PROJECT );
	}
	else{
		TProgressForm *frmProgress = new TProgressForm(NULL);

		int ret = frmProgress->Project_Save( g_strProjectName.c_str() );
		int eExtra = frmProgress->GetOpertaionResult();

		if (ret == mrOk && eExtra==0 ) {
			MessageForm->ShowMessage("工程文件保存成功。", MB_OK | MB_ICONINFORMATION);
			SetInitVar();
		}
		else if( eExtra!=0 && eExtra!=e_UserCanceled ){
			MessageForm->ShowMessage( "工程文件保存失败!", MB_ICONERROR|MB_OK );
		}

		delete frmProgress;
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnCreateNewProject(TObject *Sender)
{
	if( !g_Theme.Empty() && (g_strProjectName.length()==0 ||
												HasProjectModified())) {
		int mrRet = MessageForm->ShowMessage("是否保存当前工程？",
			MB_ICONQUESTION | MB_YESNOCANCEL);
		if (mrRet == mrYes) {
			DebugPrint("确认保存");
			OnSaveProject(NULL);
		}
		else if (mrRet == mrCancel) {
			return;
		}
	}

	NewProject();
	ClearAutoProj();
	SetInitVar(true);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnPredefineProject(TObject * Sender)
{
	if( !g_pPreStyle || g_pPreStyle->nSegNum[SEGTYPE_VAR]==0 ){
		MessageForm->ShowMessage( "请为预编风格添加伴奏片段！", MB_ICONERROR|MB_OK );

		return;
	}

	OnCreateNewProject( NULL );

	if( !g_Theme.Empty() )
		return;

	//显示预定义工程窗口
	TPredefineProjectForm *ppf = new TPredefineProjectForm(NULL);
	if( ppf->ShowModal()==mrOk ){

		//设置节拍速度
		ChangeTT( true, ppf->m_Ts );
		ChangeTT( false, ppf->m_Tempo );

		int iTonal = ppf->m_KeyType;
		int nMSNum = ppf->m_RavStage;
		int aPreset[3] = { 7, 5, 0 };

		memcpy(aPreset, ppf->m_Preset, 3 * sizeof(int));

		// 建立初始段落变量
		TBarList lstBars;
		vector<int> lstStages;

		//预定义RawStages
		g_iMelodyKey = ppf->m_Key;
		for( int i=0; i<nMSNum; i++ ){
			int ind = i;

			if( nMSNum>2 ){
				if( i==1 ) ind = 2;
				else if( i==2 )	ind = 1;
			}

			int nRepeat = (ind==2) ? 1 : 2;
			for( int r=0; r<nRepeat; r++ ){
				for( int j=0; j<8; j++ ){
					TBar * pBar = new TBar;
					pBar->iBarKey = g_iMelodyKey;
					int iKey = u_arrPredefChords[ind][iTonal][aPreset[i]][j] / 4 + g_iMelodyKey,
						iType = u_arrPredefChords[ind][iTonal][aPreset[i]][j] % 4;

//					DebugPrint( "%d ", u_arrPredefChords[ind][iTonal][aPreset[i]][j] / 4 );

					if( iKey>11 ) iKey -= 12;

					for( int k=0; k<4; k++ ){
						pBar->aChords.iKey[k] = iKey;
						pBar->aChords.iType[k] = iType;
					}

					lstBars.push_back( pBar );
				}

//				DebugPrint( "\n" );

				lstStages.push_back( lstBars.size()-1 );
			}
		}

		g_Theme.Build( lstBars, lstStages );

		//预定义OpusStages，构建UseStyleItem
		g_iViewMode = VIEW_STYLE;
//		g_iPreStage = 3;
		((TUseStylePanel*)m_pUseStylePanel)->InitOpus( g_pPreStyle,	g_iPreStage );

		AfterLoadProject();

		g_bPredefine = true;
	}

	delete ppf;
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::AcceptFiles(TMessage& Msg)
{
	const int m_nMaxFileNameLen = 255;
	wchar_t m_wsFileName[m_nMaxFileNameLen];
	DragQueryFile((HDROP)Msg.WParam, 0, m_wsFileName, m_nMaxFileNameLen);

	if( !g_Theme.Empty() && ( g_strProjectName.length()==0 || HasProjectModified())) {
		int mrRet = MessageForm->ShowMessage("是否保存当前工程？",
										MB_ICONQUESTION | MB_YESNOCANCEL);
		if (mrRet == mrYes) {
			DebugPrint("确认保存");
			OnSaveProject(NULL);
		}
		else if (mrRet == mrCancel) {
			return;
		}
	}

	SetInitVar(true);
	DoLoadProject(m_wsFileName);
	DragFinish((HDROP)Msg.WParam);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnLoadProject(TObject *Sender)
{
	if( g_aOriginStyles.empty() ) //还未加载风格
		return;

//	DWORD param = (DWORD)Sender;
//	int iMenuType = LOWORD( param );
//	int iMenuIndex = HIWORD( param );
	int ind = Sender ? (int)Sender - IDM_OPENPROJECT : -1;
	wstring strProjectName;

	if( ind<0 ) {
		strProjectName = m_strLoadProjectName.c_str();
	}
	else{
		strProjectName = g_lstRecentProject[ind];
	}

	if( !g_Theme.Empty() && (g_strProjectName.length()==0 ||
											HasProjectModified())) {
		int mrRet = MessageForm->ShowMessage("是否保存当前工程？",
										MB_ICONQUESTION | MB_YESNOCANCEL);
		if (mrRet == mrYes) {
			DebugPrint("确认保存");
			OnSaveProject(NULL);
		}
		else if (mrRet == mrCancel) {
			return;
		}
	}

	SetInitVar(true);

	if( strProjectName.empty() ){
		// 指定工程文件名
		TOpenDialog * pDlg = new TOpenDialog(NULL);
		pDlg->Title = "打开工程";
		pDlg->Options << ofFileMustExist;
		pDlg->FileName = ExtractFileName(g_strProjectName.c_str());
		pDlg->InitialDir = ExtractFilePath(g_strProjectName.c_str());
		pDlg->Filter = "编曲工程文件 (*.cpj)|*.cpj";
		pDlg->DefaultExt = "cpj";
		if (pDlg->Execute(Handle)) {
			strProjectName = pDlg->FileName.c_str();
		}
		delete pDlg;
	}

	if( !strProjectName.empty() ){
		DoLoadProject(strProjectName.c_str());

		Update();
	}

	m_strLoadProjectName = "";
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::DoLoadProject(LPCTSTR strName)
{
	Perform( UM_STOP, STOP_ALL, 0 );

	m_pContentPanel->InitialVars( true );

	g_Midi.ClearMidiTracks();
	((TStylePanel*)m_pUseStylePanel)->SetStyleItem( g_pUseStyle = NULL );

//	ClearAutoSave();

	TProgressForm *frmProgress = new TProgressForm(NULL);
	int ret = frmProgress->Project_Load(strName);
	DWORD iResult = frmProgress->GetOpertaionResult();

	delete frmProgress;

	if( ret==mrOk ){
		g_bAutoOpenProjectEnable = true;  //add by tj 2014/05/15

		if( SetSelectFont() ){
			TComboBoxItem* pItem = m_cbFontSelect->GetItem( m_cbFontSelect->DefItemIndex );

			if( pItem->Tag != g_idFont ){
				for( int i=0; i<m_cbFontSelect->ItemsCount; i++ ){
					pItem = m_cbFontSelect->GetItem( i );

					if( pItem->Tag==g_idFont ){
						m_cbFontSelect->DefItemIndex = i;
						break;
					}
				}
			}
		}
		else{
			iResult |= E_PROJ_INVALIDFONT;
		}

		if( iResult & E_PROJ_INVALIDFONT  ){
			String strMsg;
			strMsg = g_strProjError[0];
			MessageForm->ShowMessage(strMsg, MB_ICONINFORMATION | MB_OK);
		}

		if( iResult & E_PROJ_INVALSTAGESTYLE  ){
			String strMsg;
			strMsg = g_strProjError[1];
			MessageForm->ShowMessage(strMsg, MB_ICONINFORMATION | MB_OK);
		}

		if( iResult & E_PROJ_INVALIDFX  ){
			String strMsg;
			strMsg = g_strProjError[2];
			MessageForm->ShowMessage(strMsg, MB_ICONINFORMATION | MB_OK);
		}

		AfterLoadProject();

//		m_lblTitle->Caption = TPath::GetFileNameWithoutExtension(strName);
	}
	else{
		if( iResult!=e_UserCanceled ){
			String strErr;
			if (iResult > E_PROJ_FATALERROR) {
				strErr = g_strProjError[iResult - E_PROJ_FATALERROR];
			}

			MessageForm->ShowMessage(strErr, MB_ICONERROR | MB_OK, "提示");

			for (int i = 0; i < g_lstRecentProject.size(); i++) {
				if (LowerCase(g_lstRecentProject[i].c_str()) == LowerCase(strName))
				{
					g_lstRecentProject.erase(g_lstRecentProject.begin() + i);
					break;
				}
			}
		}

		NewProject();
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::AfterLoadProject()
{
	m_cbFontSelect->Enabled = !g_bExtFont;
	m_btnExtFontOn->Visible = g_bExtFontUsable && g_bExtFont;
	m_btnExtFontOff->Visible = g_bExtFontUsable && !g_bExtFont;

//	SetInitVar();

	if( g_pPreStyle )
		((TStylePanel*)m_pPreStylePanel)->SetStyleItem( g_pPreStyle );
	else
		((TStylePanel*)m_pPreStylePanel)->InitItems();

	((TStylePanel*)m_pUseStylePanel)->SetStyleItem( g_pUseStyle );
	((TChordPanel*)m_pChordPanel)->EnableChordModify( false, -1, -1, -1 );

	m_UseStyleHeight = m_UseStyleHeight + m_PreStyleHeight - TOOLPAL_MINHEIGHT;
	m_PreStyleHeight = TOOLPAL_MINHEIGHT;

	m_pUseStylePanel->SetBounds( m_pUseStylePanel->Left,
								m_pUseStylePanel->Top,
								m_pUseStylePanel->Width,
								m_UseStyleHeight );
	m_pPreStylePanel->SetBounds( m_pPreStylePanel->Left,
								m_pUseStylePanel->Top + m_UseStyleHeight,
								m_pPreStylePanel->Width,
								m_PreStyleHeight );

	m_btnTempo->Caption = IntToStr(g_nMelodyTempo);
	m_btnTempo->Invalidate();
	m_cbPreStage->DefItemIndex = g_iPreStage;
	m_cbKey->DefItemIndex = g_iMelodyKey;
	m_cbKey->Enabled = true;

	m_iStartBar = 0;
	m_dblStartPoint = 0;
	m_dwLastVol = 0;
	m_pContentPanel->SetPlayPoint( 0, 0 );
	m_pContentPanel->SelectTrack( -1, -1, -1 );
	ShowPlayTime();

	m_strUploadFile = "";
	u_pUploadLite = NULL;

	SetMode( g_iViewMode, true );

	m_pContentPanel->OnStageChanged( 0, MODE_INIT );

	for( int i=0; i<g_aAudioTracks.size(); i++ ){
		AudioEffectsSet( i );
	}

	m_btnPlay->Enabled = !g_lstOpusStages.empty();
	m_btnSave->Enabled = !g_lstOpusStages.empty();
	m_btnUpload->Enabled = !g_bUpdateMandatory && !g_lstOpusStages.empty();

	//初始化g_infoSong
	memset( &g_infoSong, 0, sizeof(TSONGINFO) );
	memset( g_infoSong.iMusicStyle, -1, 4 );

	g_infoSong.size = sizeof(tSongInfo);
	g_infoSong.iTS = g_iMelodyTimeSignature;
	g_infoSong.iTempo = g_nMelodyTempo;
	g_infoSong.iSubmit = 1;

	//Title
	if( g_strProjectName.length()==0 )
		m_lblTitle->Caption = L"Untitle";
	else{
		String strName = g_strProjectName.c_str();
		AnsiString strTitle = TPath::GetFileNameWithoutExtension( strName );
		m_lblTitle->Caption = strTitle;
		strcpy( g_infoSong.strSongName, strTitle.c_str() );
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnLoadProjectMessage(TMessage &msg)
{
	if (msg.LParam != 0) {
		int BUF_SIZE = 256;
		TCHAR szName[] = TEXT("MyFileMappingObject");
		LPTSTR pBuf;
		HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,
			// read/write access
			FALSE, // do not inherit the name
			szName); // name of mapping object

		if (hMapFile) {
			pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object
				FILE_MAP_ALL_ACCESS, // read/write permission
				0, 0, BUF_SIZE);

			if (pBuf) {
				m_strLoadProjectName = pBuf;
				UnmapViewOfFile(pBuf);
				PostMessage(Handle, UM_LOADPROJECT, 0, 0);
			}

			CloseHandle(hMapFile);
		}
	}
	else {
		OnLoadProject(NULL);
	}

	msg.Result = true;
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnSaveProjectMessage(TMessage &msg)
{
	SaveAs( msg.WParam + msg.LParam );
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnNewProjectMessage(TMessage &msg)
{
	NewProject();
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::NewProject()
{
	if( g_iViewMode==VIEW_INIT )
		return;

	Perform( UM_STOP, STOP_ALL, 0 );

	DisableAutoOpen();  //add by tj 2014/05/15

	m_lblTitle->Caption = L"Untitle";
	m_strUploadFile = "";
	u_pUploadLite = NULL;

	g_bMidiMelody = false;
	g_iMelodyKey = -1;
	g_fMusicVolume = 1;
	g_bComposeMute = false;
//	g_iSelAudio = -1;
	g_strProjectName.clear();
	g_Opus.Clear();

	//初始化g_infoSong
	memset( &g_infoSong, 0, sizeof(TSONGINFO) );
	memset( g_infoSong.iMusicStyle, -1, 4 );

	g_infoSong.size = sizeof(tSongInfo);
	g_infoSong.iTS = g_iMelodyTimeSignature;
	g_infoSong.iTempo = g_nMelodyTempo;
	g_infoSong.iSubmit = 1;

	ClearGlobalVars();
	ClearSVDVars();
	ClearProjStyleMap();
	f_CS_ResetProject();
	f_MM_ResetProject();
	g_bProjStylePaid = false;

	SetMode( VIEW_INIT, true );
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnUserHelp(TObject *Sender)
{
	if( !m_HelpForm ){
		m_HelpForm = new THelpForm(this);
		int iPublic = 0, iUser = 0;

		if(g_bLogon)
			iUser = f_CS_GetNewNoticeNum( g_infoUser.accountInfo.ID );

		m_HelpForm->SetNoticeNum(iUser, 1);

		m_HelpForm->Show();
	}
	else if( m_HelpForm->Window_state==HLP_WINDOW_MIN ){
		m_HelpForm->SetSize( HLP_WINDOW_NORMAL );
	}
}
// ---------------------------------------------------------------------------

 void __fastcall TMainForm::OnUserManual(TObject *Sender)
{
	PostMessage(Handle, UM_OPENMANUAL, 0, 0);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnForumVist(TObject *Sender)
{
	char strURL[256];
	f_CS_GetWebPageURL( URL_TECHFORUM, strURL );
	ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnMicSetting(TObject *Sender)
{
	StopClick( NULL );

	TMicSetForm * pDlg = new TMicSetForm(this);
	pDlg->ShowModal();
	delete pDlg;
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnVSTPathSetting(TObject *Sender)
{
	PostMessage(Handle, UM_VSTPATH, 0, 0);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnAbout(TObject *Sender)
{
	PostMessage(Handle, UM_SHOWABOUT, 0, 0);
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::OnShowAbout(TMessage & Msg)
{
	TAboutForm * pDlg = new TAboutForm(NULL);

	pDlg->ShowModal();

	delete pDlg;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnShowMore(TObject *Sender)
{
    char strURL[256];
    f_CS_GetWebPageURL(URL_SOFTWARE, strURL);
    ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnOpenManual(TMessage & Msg)
{
	HWND hHelp = FindWindow(NULL, L"唱作魔方专业版用户手册");
	if (hHelp) {
		ShowWindow(hHelp, SW_RESTORE);
	}
	else {
		String helpFile = g_strExecutePath.c_str();
		helpFile += "Help/ACProManual.chm";
		ShellExecute(Handle, L"Open", helpFile.c_str(), NULL, NULL,	SW_MAXIMIZE);
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShowPlayTime()
{
	int iTime[3];
	GetPlayTime( m_iStartBar, m_dblStartPoint, iTime );

	m_pPlayTimePanel->SetTime( iTime );
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::RecordClick(TObject *Sender)
{
	PostMessage( Handle, UM_RECORD, 0, 0 );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMRecord(TMessage &Message)
{
	HRESULT hr = S_FALSE;
	m_bFromFile = false;
	m_iRecordBar = 0;
	m_dblRecordPoint = 0;
	m_nDelayPoint = -1;

	Perform( UM_STOP, STOP_ALL, 0 );

	m_pContentPanel->SetFocus();

	int iModifyBeginBar, iModifyBeginPoint, iModifyEndBar, iModifyEndPoint;
	m_pContentPanel->GetSelectRange(iModifyBeginBar, iModifyBeginPoint,
										iModifyEndBar,	iModifyEndPoint);

	if( g_iSelAudio<0 ){
		if( g_iViewMode==VIEW_INIT ){
			g_iSelAudio = 0;
		}
		else{
			bool bResetRange = g_iViewMode==VIEW_STYLE;
			if( g_iViewMode!=VIEW_TRACK )
				SetMode( VIEW_TRACK );

			for( int i=0; i<g_aAudioTracks.size(); i++ ){
				if( !g_aAudioTracks[i]->IsHide() && !g_aAudioTracks[i]->lstBars.empty() ){
					int iShowTrack = m_pContentPanel->GetShowTrackId( ST_AUDIO, i ) - 1;
					m_pContentPanel->SelectTrack( iShowTrack, -1, -1 );

					break;
				}
			}

			if( bResetRange )
				m_pContentPanel->SetSelectRange( iModifyBeginBar, iModifyBeginPoint,
													iModifyEndBar,	iModifyEndPoint );
		}
	}

	double dblEditStartBar = -1,
		dblEditEndBar = -1,
		dblPlayStartBar = 0;
	int iWithCompose = 0;

	bool bModify = g_iViewMode!=VIEW_INIT;//!g_lstOpusStages.empty() && g_iPreStage>0 || g_bPredefine || m_pContentPanel->IsModifyMode();
	bool bBeatHint = false;

//不清除当前内容，仅提示预编风格，g_iSelAudio=0 && g_lstRawStages.empty 为初始录音，否则AddUndo(UNDO_AUDIO_RECORD)
	if( bModify ) {
		if( g_iPreStage>0 )
			iWithCompose = TYPE_COMPOSE;
		else
			iWithCompose = TYPE_BASECOMPOSE;

		if( g_bPredefine || g_bMidiMelody )
			iWithCompose |= TYPE_PREDEFINE;

		GenerateCompose();

		int nBarCount = g_aAudioTracks[g_iSelAudio]->lstBars.size();
//		int iModifyBeginBar, iModifyBeginPoint, iModifyEndBar, iModifyEndPoint;
//		m_pContentPanel->GetSelectRange(iModifyBeginBar, iModifyBeginPoint,
//										iModifyEndBar,	iModifyEndPoint);

		if( iModifyBeginBar<1 ){
			bBeatHint = true;
			m_iStartBar = 0;
			m_dblStartPoint = 0;
			m_pContentPanel->SetPlayPoint(0, 0);
		}

		if( m_iStartBar>iModifyBeginBar || ( m_iStartBar==iModifyBeginBar
									&& m_dblStartPoint>=iModifyBeginPoint )){
			if (iModifyBeginBar > 0)
				m_iStartBar = iModifyBeginBar - 1;
			else
				m_iStartBar = 0;

			m_dblLastStartPoint = m_dblStartPoint = 0;
			m_pContentPanel->SetPlayPoint(m_iStartBar, 0);
		}

		dblPlayStartBar = m_iStartBar + m_dblStartPoint/POINTS_PER_BAR;

		if( iModifyBeginBar>=0 )
			dblEditStartBar = iModifyBeginBar + (double)iModifyBeginPoint/POINTS_PER_BAR;
		else
			iModifyBeginBar = iModifyBeginPoint = 0;

		if( iModifyEndBar>=0 )
			dblEditEndBar = iModifyEndBar + (double)iModifyEndPoint/POINTS_PER_BAR;
		else if( g_iSelAudio>0 ){
			iModifyEndBar = nBarCount;
			iModifyEndPoint = 0;
		}

		if( g_bPredefine && g_iPreStage==0 && dblEditStartBar<0 && dblEditEndBar<0 ){
			dblEditStartBar = 0;
			dblEditEndBar = nBarCount;// g_lstRawBars.size();
		}

		if( g_iSelAudio>0 ){
			DWORD* aWave = NULL;
			CopyWave( g_iSelAudio, iModifyBeginBar, iModifyBeginPoint, iModifyEndBar, iModifyEndPoint, &aWave );

			g_Undo.AddUndo( UNDO_AUDIO_RECORD, g_iSelAudio, MAKELONG( iModifyBeginPoint, iModifyBeginBar ),
													MAKELONG( iModifyEndPoint, iModifyEndBar ), aWave, NULL );
		}
		else{
			TAudioTrack* pAudio = CopyAudioTrack( 0, 0, nBarCount );
			g_Undo.AddUndo( UNDO_AUDIO_RECORD, 0, g_iMelodyKey, -1, pAudio, NULL );
		}

		f_MM_AddUndoBefore( 1, &g_iSelAudio );
	}
	else{
		//检查预设风格片段
		if( !g_pPreStyle || g_pPreStyle->nSegNum[SEGTYPE_VAR]==0 ){
			MessageForm->ShowMessage( "请为预编风格添加伴奏片段！", MB_ICONERROR|MB_OK );

			return;
		}

		if( g_Undo.GetUndoType()>=0 ){
			TAudioTrack* pAudio = CopyAudioTrack( 0, 0, 0 );
			g_Undo.AddUndo( UNDO_AUDIO_RECORD, 0, g_iMelodyKey, -1, pAudio, NULL );

			int iAT = 0;
			f_MM_AddUndoBefore( 1, &iAT );
		}
	}

	BYTE* pBeatData = NULL;
	int nBeatSize = 0;

 	if( g_bPrebeat || bModify ){
		pBeatData = new BYTE[1000000];
		nBeatSize = 1000000;

		TStylePanel* pStyPanel = (TStylePanel*)( bModify ? m_pUseStylePanel : m_pPreStylePanel );
		if( !pStyPanel->GetPrebeat( pBeatData, nBeatSize ) ){
			nBeatSize = 0;
		}
	}

	f_MM_LoadPrebeat( pBeatData, nBeatSize );

	if( pBeatData ){
		delete[] pBeatData;
		pBeatData = NULL;
	}

	hr = f_MM_AudioRecord( Handle, g_iSelAudio, dblPlayStartBar, dblEditStartBar, dblEditEndBar, iWithCompose );

	if( hr==S_OK ){
		SetRecordState( true );

		m_cbKey->Enabled = false;

		m_btnRecord->Enabled = false;
		m_btnRecord->Down = true;

		m_btnStop->Enabled = true;
		m_btnPlay->Enabled = false;
		m_btnPlay->Visible = true;
		m_btnPause->Visible = false;

		if( !bModify || bBeatHint ){
			m_pContentPanel->ShowBeatHint( g_nChordNumPerBar - 1 );

			if( bBeatHint ){
				int tInterval = (int)(( g_iMelodyTimeSignature==3 ? 90000.0 : 60000.0 )
															 / g_nMelodyTempo + 0.5 );

				SetPlayTimer(true, m_tBeatHint, m_tAccuracy, Handle, tInterval);
			}
			else{
				// 第一小节
				TWaveBar * pBar = new TWaveBar;
				g_aAudioTracks[0]->lstBars.push_back(pBar);
				g_aAudioTracks[0]->Hide(false);

				m_pContentPanel->AddNewBar(0);
			}
		}

		if( !bBeatHint ){
			SetPlayTimer(true, m_tTimer, m_tAccuracy, Handle);
			m_pContentPanel->Play(true);
		}
	}
	else{
		ShowErrorMessage( hr, "" );

		if( hr==3 || hr==6 || hr==37 || hr==46 || hr==23 ){
			g_iRecordDevice = g_iRecordInput = -1;
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShowErrorMessage( int errcode, String strOperation )
{
	String msg;
	if( strOperation.Length()==0 ){
		if( errcode==46 ){
			msg += L"录音设备被其它程序占用。";
		}
		else if( errcode==6 ){
			msg += L"录音设备不支持所需格式。";
		}
		else if( errcode==1 ){
			msg += L"内存空间不足。";
		}
		else if( errcode==37 ){
			msg += L"录音设备无法打开。";
		}
		else if( errcode==3 ){
			msg += L"录音设备驱动无效。";
		}
		else if( errcode==23 ){
			msg += L"录音设备不可用。";
		}
		else{
			msg += L"录音设备启动失败。";
		}
	}
	else{
		msg = strOperation + L"\n\n";

		if( errcode==e_InvalidUserID ){
			msg += L"无效的用户。";
		}
		else if( errcode==e_InvalidAuthority ){
			msg += L"该用户无操作权限。";
		}
		else if( errcode==e_InvalidStyleID ){
			msg += L"所选的风格之一已失效。";
		}
		else if( errcode==e_VerifyInsufficient ){
			msg += L"唱作音符余额不足，请登录网站获取。";
		}
		else if( errcode==e_DatabaseError ){
			msg += L"数据库访问失败，请稍后重试。";
		}
		else if( errcode==e_ServiceBusy ){
			msg += L"服务器忙，请稍后重试。";
		}
		else if( errcode==e_SocketError ){
			msg += L"网络故障，请关闭程序后重试。";
		}
		else if( errcode==e_WaitTimeout ){
			msg += L"网络超时，请稍后重试。";
		}
		else if( errcode==e_LoginPasswordError ){
			msg += L"输入密码错，请重新输入。";
		}
		else if( errcode==e_LoginUserNotExist ){
			msg += L"无效的用户名，请重新输入。";
		}
		else if( errcode==e_UsernameExist ){
			msg += L"用户名已存在，请重新注册。";
		}
		else if( errcode==e_UserLocked ){
			msg += L"该账户被冻结，请重新注册。";
		}
		else if( errcode==e_UserDeleted ){
			msg += L"该账户已被删除，请重新注册。";
		}
		else if( errcode==e_OpenFileFailed ){
			msg += L"文件操作错误。";
		}
		else if( errcode==e_InvalidDataID
					|| errcode==e_InvalidPackID
					|| errcode==e_InvalidData ){
			msg += L"文件传输失败。";
		}
		else if( errcode==e_FormatErr ){
			msg += L"文件格式错误。";
		}
		else if( errcode==e_TrkToMuch ){
			msg += L"轨道数过多，请删除主旋律以外的轨道。";
		}
		else if( errcode==e_NoTrack ){
			msg += L"文件不包含有效轨道。";
		}
		else if( errcode==e_VipExceeded ){
			msg += L"账号登录设备数已达上限，请稍后再试。";
		}
		else if( errcode==e_NoService ){
			msg += L"所需服务组件加载失败。";
		}
		else{
			msg += L"未知原因。";
        }
    }

	MessageForm->ShowMessage( msg, MB_ICONERROR|MB_OK );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMMediaTime(TMessage &Message)
{
	if( Message.WParam==m_tBeatHint ){
		int iInterval = ( g_nChordNumPerBar==4 ? 30 : g_nChordNumPerBar==3 ? 40 : 60 );

		m_dblStartPoint += iInterval;

		if( m_dblStartPoint >= (double)POINTS_PER_BAR ){
			m_dblStartPoint = 0;

			SetPlayTimer( false, m_tBeatHint, m_tAccuracy);
			SetPlayTimer(true, m_tTimer, m_tAccuracy, Handle);

			m_pContentPanel->ShowBeatHint( -1 );
			m_pContentPanel->Play(true);
		}
		else{
			int iIndex = m_dblStartPoint/iInterval;
			m_pContentPanel->ShowBeatHint( g_nChordNumPerBar-iIndex-1 );
		}

		return;
	}

	if( !m_pContentPanel || !m_pContentPanel->IsPlaying() )
		return;

	int iModifyBeginBar(-1), iModifyBeginPoint(-1),
		iModifyEndBar(-1), iModifyEndPoint(-1);
	bool bRecording = m_btnRecord->Down,
		bNewBar = false;
	int iBar = m_iStartBar;
	double dblStartPoint = m_dblStartPoint + g_dblStep;

	if( (int)dblStartPoint==(int)m_dblStartPoint ){
		m_dblStartPoint = dblStartPoint;

		return;
	}

	if (dblStartPoint >= (double)POINTS_PER_BAR) {
		dblStartPoint -= POINTS_PER_BAR;
		iBar++;
		bNewBar = true;
	}

	if( bNewBar ){
		bool bAutoStop = !bRecording || g_bPredefine || g_bMidiMelody
						|| ( g_iViewMode!=VIEW_INIT && g_iPreStage!=0 );

		if( !bAutoStop && g_iViewMode!=VIEW_INIT && g_iPreStage==0
										&& m_pContentPanel->IsModifyMode() ){
			m_pContentPanel->GetSelectRange( iModifyBeginBar, iModifyBeginPoint,
											iModifyEndBar, iModifyEndPoint);

			if( iModifyEndBar>=0 )
				bAutoStop = true;
		}

		if( m_pContentPanel->GetBarNum()==iBar && bAutoStop ){
			if( bRecording ){
				m_iRecordBar = iBar-1;
				m_dblRecordPoint = POINTS_PER_BAR - 1;
			}

			StopClick(NULL);
			return;
		}

		bool bExtend = g_iViewMode==VIEW_INIT || g_iPreStage==0;
		if( bRecording && bExtend && iBar==g_aAudioTracks[0]->lstBars.size() ){
			m_pContentPanel->ShowBeatHint( -1 );

			TWaveBar* pBar = new TWaveBar;
			g_aAudioTracks[0]->lstBars.push_back( pBar );

			m_pContentPanel->AddNewBar(iBar);
		}
	}
	else if( g_iViewMode==VIEW_INIT && iBar<1 ){
		int iInterval = ( g_nChordNumPerBar==4 ? 30 : g_nChordNumPerBar==3 ? 40 : 60 );
		int iIndex = dblStartPoint/iInterval;

		m_pContentPanel->ShowBeatHint( g_nChordNumPerBar-iIndex-1 );
	}

	if( bRecording ){
		if( g_iViewMode==VIEW_INIT ){
			iModifyBeginBar = 0;
			iModifyBeginPoint = POINTS_PER_BAR/2;
		}
		else if( m_pContentPanel->IsModifyMode() ){
			m_pContentPanel->GetSelectRange( iModifyBeginBar, iModifyBeginPoint,
											iModifyEndBar, iModifyEndPoint);
		}

		if( m_nDelayPoint<0 && ( iBar>iModifyBeginBar || iBar==iModifyBeginBar
											&& dblStartPoint>(double)iModifyBeginPoint ) ){
			float fLatency = f_MM_GetLatency( false ) / 1000;
			m_nDelayPoint =  (int)( fLatency / g_dblTimePerBar * POINTS_PER_BAR + 0.5 );
		}

		if( m_nDelayPoint>0 ){
			if( iModifyBeginBar>=0 ){
				iModifyBeginPoint += m_nDelayPoint;
				if( iModifyBeginPoint>=POINTS_PER_BAR ){
					iModifyBeginPoint -= POINTS_PER_BAR;
					iModifyBeginBar++;
				}
			}
			else{
				iModifyBeginBar = 0;
				iModifyBeginPoint = m_nDelayPoint;
			}

			if( iModifyEndBar>=0 ){
				iModifyEndPoint += m_nDelayPoint;

				if( iModifyEndPoint>=POINTS_PER_BAR ){
					iModifyEndPoint -= POINTS_PER_BAR;
					iModifyEndBar++;
				}
			}
		}

		if( !((iBar>iModifyBeginBar || iBar==iModifyBeginBar
							&& dblStartPoint>=(double)iModifyBeginPoint) && (iModifyEndBar<0
							|| iBar<iModifyEndBar || iBar==iModifyEndBar
							&& dblStartPoint<(double)iModifyEndPoint)) ) {
			bRecording = false;
		}
	}

	// 获取实时音量
	DWORD dwVolume = 0;

	if( bRecording ){
		dwVolume = f_MM_GetStreamVolume(1);
	}
	else{
		dwVolume = f_MM_GetStreamVolume(6);
	}

	if( dwVolume==(DWORD)-1 ){
		dwVolume = 0;
	}

	m_nVolLevel = ( 53 * LOWORD(dwVolume) ) / 0x8000;
	m_pbVolLevel->Invalidate();

	if( bRecording ){
		int iWave = m_pContentPanel->GetShowTrackId( ST_AUDIO, g_iSelAudio );

		if( (iBar>iModifyBeginBar || iBar==iModifyBeginBar
						&& dblStartPoint>=(double)iModifyBeginPoint)
						&& (iModifyEndBar<0	|| iBar<iModifyEndBar || iBar==iModifyEndBar
						&& dblStartPoint<(double)iModifyEndPoint) ) {
			int iLastBar = m_iStartBar, iCurrBar = iBar,
				iLastPoint = (int)m_dblStartPoint - m_nDelayPoint,
				iCurrPoint = (int)dblStartPoint - m_nDelayPoint;

			if( iLastPoint<0 ){
				iLastPoint += POINTS_PER_BAR;
				iLastBar--;
			}

			if( iCurrPoint<0 ){
				iCurrPoint += POINTS_PER_BAR;
				iCurrBar--;
			}

			TWaveBar * pBar = g_aAudioTracks[g_iSelAudio]->lstBars[iLastBar];

			if( iLastBar<iCurrBar ){
				if( iLastPoint<POINTS_PER_BAR-1 ){
					for( int i=iLastPoint+1; i<POINTS_PER_BAR; i++ ){
						pBar->aVols[i] = m_dwLastVol;
					}

					m_pContentPanel->InvalidateBar( iLastBar, iLastPoint, POINTS_PER_BAR-1, BAR_TRACK | iWave );
				}

				iLastPoint = 0;

				pBar = g_aAudioTracks[g_iSelAudio]->lstBars[iCurrBar];
			}

			if( iLastPoint<iCurrPoint ){
				for (int i=iLastPoint+1; i<iCurrPoint; i++ ){
					pBar->aVols[i] = m_dwLastVol;
				}
			}

			pBar->aVols[iCurrPoint] = dwVolume;
			m_dwLastVol = dwVolume;

			m_pContentPanel->InvalidateBar( iCurrBar, iLastPoint, iCurrPoint,  BAR_TRACK | iWave );
		}

		m_iRecordBar = iBar;
		m_dblRecordPoint = dblStartPoint;
	}

	m_pContentPanel->SetPlayPoint( iBar, (int)dblStartPoint );

	m_iStartBar = iBar;
	m_dblStartPoint = dblStartPoint;

	ShowPlayTime();
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::UMAutoRecognition(TMessage &Message)
{
	g_iMelodyKey = -1;
	AutoRecognition( Message.WParam );
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::UMRecordComplete(TMessage &Message)
{
	if( !m_pContentPanel )
		return;

	StopClick( NULL );

	if( m_pVolumeForm ){
		m_pVolumeForm->OnRecord( false );
	}

	int iBeginBar, iBeginPoint, iEndBar, iEndPoint;
	m_pContentPanel->GetSelectRange( iBeginBar, iBeginPoint,
									iEndBar, iEndPoint);
	if( iBeginBar<0 ){
		iBeginBar = 0;
		iBeginPoint = 0;
	}

	if( iEndBar<0 ){
		iEndPoint = 0;

		if( g_iSelAudio==0 )
			iEndBar = g_aAudioTracks[0]->lstBars.size();
		else
			iEndBar = GetBarCount();
	}

	if( ( m_iRecordBar<iBeginBar || m_iRecordBar==iBeginBar
								&& (int)m_dblRecordPoint<=iBeginPoint )
								&& g_Undo.GetUndoType()>=0 ){
		g_Undo.CancelUndo();
		f_MM_CancelAddUndo();
	}
	else{
		if( g_iSelAudio==0 ){
			AutoRecognition( MODE_RECORD );
		}
		else{
			f_MM_AddUndoAfter( 1, &g_iSelAudio );

			TUndoLite* pUndo = g_Undo.GetLastLite();

			if( m_iRecordBar<iEndBar || m_iRecordBar==iEndBar
									&& (int)m_dblRecordPoint<iEndPoint ){
				iEndBar = m_iRecordBar;
				iEndPoint = (int)m_dblRecordPoint;

				int len = ( iEndBar * POINTS_PER_BAR + iEndPoint )
								- ( iBeginBar * POINTS_PER_BAR + iBeginPoint );

				DWORD* aNewWave = new DWORD[len];
				memcpy( aNewWave, pUndo->pBefore, sizeof(DWORD) * len );
				delete[] (DWORD*)pUndo->pBefore;

				pUndo->pBefore = aNewWave;
				pUndo->iEnd = MAKELONG( iEndPoint, iEndBar );
			}

			DWORD* aWave = NULL;
			CopyWave( g_iSelAudio, iBeginBar, iBeginPoint, iEndBar, iEndPoint, &aWave );
			pUndo->pAfter = aWave;

			m_btnRecord->Down = false;
			m_btnPlay->Visible = true;
			m_btnPlay->Enabled = !g_lstOpusStages.empty();
			m_btnRecord->Enabled = RecordEnabled();
			m_btnPause->Visible = false;
			m_btnStop->Enabled = false;
			m_btnSave->Enabled = !g_lstOpusStages.empty();
			m_btnUpload->Enabled = !g_bUpdateMandatory && !g_lstOpusStages.empty();
			//g_bSongSaved = false;
			m_bFromFile = false;
			m_cbKey->DefItemIndex = g_iMelodyKey;
			m_cbKey->Enabled = g_iMelodyKey>=0;
		}
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::UMRecordVolJust(TMessage &Message)
{
	g_fRecordVolume = (int)Message.WParam / 100.0;

	if( m_pVolumeForm ){
		m_pVolumeForm->ChangeRecordVol();
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::UMPlayOver(TMessage &Message)
{
//	if( !m_btnRecord->Down )
	Perform( UM_STOP, STOP_ALL, 0 );
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::StopClick(TObject *Sender)
{
	f_MM_Stop();

	if( m_pContentPanel->IsPlaying() ){
		m_pContentPanel->Play(false);

		SetPlayTimer(false, m_tTimer, m_tAccuracy);

		m_nVolLevel = 0;
		m_pbVolLevel->Invalidate();
	}

	if( m_tTimer )
		SetPlayTimer(false, m_tTimer, m_tAccuracy);
	if( m_tBeatHint )
		SetPlayTimer(false, m_tBeatHint, m_tAccuracy);

	m_pContentPanel->ShowBeatHint( -1 );

	if( m_btnRecord->Down )
		SetRecordState( false );

	m_iStartBar = m_iLastStartBar;
	m_dblStartPoint = m_dblLastStartPoint;
	m_pContentPanel->SetPlayPoint(m_iStartBar, (int)m_dblStartPoint);
	ShowPlayTime();

	m_btnStop->Enabled = false;
	m_btnRecord->Enabled = RecordEnabled();
	m_btnRecord->Down = false;
	m_btnPlay->Visible = true;
	m_btnPlay->Enabled = !g_lstOpusStages.empty();
	m_btnPause->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
	if( Shift.Contains( ssAlt ) ){
		int iType = 0;

		switch( Key ){
		case 'F': 	iType = MENU_FILE; 	break;
		case 'E': 	iType = MENU_EDIT; 	break;
		case 'V':	iType = MENU_VIEW;	break;
 		case 'K':	iType = MENU_TRACK;	break;
		case 'T':	iType = MENU_TOOL;	break;
		case 'H':	iType = MENU_HELP;	break;
		}

		if( iType>0 ){
			m_pMenuBar->ShowMenu( iType );
		}
	}
	else{
		switch (Key) {
		case VK_ESCAPE:
			if( !m_btnRecord->Down ){
				m_pContentPanel->DoCancelAll(NULL);
				if( Screen->Cursor>=crBrush && Screen->Cursor<=crBrushNo ){
					Screen->Cursor = crDefault;
				}
			}

			if( m_KeyBoard->Visible ){
				m_KeyBoard->ShowKeyboard( false );
				if( m_btnKeyboard->Down )
					m_btnKeyboard->Down = false;
			}
			break;

		case VK_TAB:
			if( Shift.Contains( ssCtrl ) && !m_btnRecord->Down && g_iViewMode!=VIEW_INIT ){
            	OnViewMode((TObject*)3);
			}
			break;

		case ' ':
			if (m_btnPause->Visible && m_btnPause->Enabled) {
				PauseClick(NULL);
			}
			else if (m_btnPlay->Visible && m_btnPlay->Enabled) {
				PlayClick(NULL);
			}
			else if (m_btnStop->Enabled) {
				StopClick(NULL);
			}

			break;

		case 'W':
			if( !m_btnRecord->Down ){
				if( m_btnStop->Enabled ){
					StopClick(NULL);
				}

				m_iStartBar = m_iLastStartBar = 0;
				m_dblStartPoint = m_dblLastStartPoint = 0;
				m_pContentPanel->SetPlayPoint(0, 0);
				ShowPlayTime();
			}

			break;

		case 'R':
			if( m_btnRecord->Enabled && !m_btnRecord->Down ){
				RecordClick(m_btnRecord);
			}

			break;

		case 'A':
			if( Shift.Contains( ssCtrl ) && !m_btnRecord->Down ){
				m_pContentPanel->DoSelectAll(NULL);
			}
			break;

		case 'C':
			if( Shift.Contains( ssCtrl ) && !m_btnRecord->Down ){
				if( g_iViewMode==VIEW_STYLE ) {
					m_pContentPanel->DoBarsCopy(NULL);
				}
				else if( g_iViewMode==VIEW_CHORD ){
					m_pContentPanel->DoChordCopy(NULL);
				}
				else if( g_iViewMode==VIEW_TRACK ){
					m_pContentPanel->DoAudioCopy(NULL);
				}
			}
			break;

		case 'X':
			if( Shift.Contains( ssCtrl ) && !m_btnRecord->Down ){
				if( g_iViewMode==VIEW_STYLE ) {
					m_pContentPanel->DoBarsCut(NULL);
				}
				else if( g_iViewMode==VIEW_TRACK ){
					m_pContentPanel->DoAudioCut(NULL);
				}
			}
			break;

		case 'V':
			if( Shift.Contains( ssCtrl ) && !m_btnRecord->Down ){
				if( g_iViewMode==VIEW_STYLE ) {
					m_pContentPanel->DoBarsInsert(NULL);
				}
				else if( g_iViewMode==VIEW_CHORD ){
					m_pContentPanel->DoChordPaste(NULL);
				}
				else if( g_iViewMode==VIEW_TRACK ){
					m_pContentPanel->DoAudioPaste(NULL);
				}
			}
			break;

		case 'Z':
			if( !m_btnRecord->Down ){
				if( Shift.Contains( ssCtrl ) ){
					if( Shift.Contains( ssShift ) ){
						Undo( false );
					}
					else{
						Undo( true );
					}
				}
			}
			break;

		case VK_DELETE:
			if( Shift.Contains( ssCtrl ) && !m_btnRecord->Down ){
				if( g_iViewMode==VIEW_STYLE ) {
					m_pContentPanel->DoBarsDelete(NULL);
				}
				else if( g_iViewMode==VIEW_CHORD ){
					m_pContentPanel->DoChordDelete(NULL);
				}
				else if( g_iViewMode==VIEW_TRACK ){
					if( g_iSelAudio>=0 )
						m_pContentPanel->DoAudioDelete(NULL);
					else if( g_iSelMidiTrack>=0 )
						m_pContentPanel->DoDeleteTexture(NULL);
				}
			}
			break;

		case VK_INSERT:
			if( Shift.Contains( ssCtrl ) && !m_btnRecord->Down ){
				if( g_iViewMode==VIEW_STYLE ) {
					m_pContentPanel->DoInsertBlankBar(NULL);
				}
				else if( g_iViewMode==VIEW_TRACK ){
					if( g_iSelAudio>=0 )
						m_pContentPanel->DoAudioLoad(NULL);
					else if( g_iSelMidiTrack>=0 )
						m_pContentPanel->DoInsertTexture(NULL);
				}
			}
			break;

		case VK_F1:
			if( !m_btnRecord->Down )
				OnUserHelp( NULL );
			break;

		case VK_F2:
			if( !m_btnRecord->Down )
				OnLoadProject( NULL );
			break;

		case VK_F3:
			if( g_lstOpusStages.size()>0 && !m_btnRecord->Down )
				OnSaveProject( NULL );
			break;

		case VK_F4:
			if( g_lstOpusStages.size()>0 && !m_btnRecord->Down )
				OnSaveAs( Sender );
			break;

		case VK_F5:
			if( !m_btnRecord->Down )
				OnCreateNewProject( NULL );
			break;

		case VK_F6:
			OnKeyBoard( NULL );
			break;

		case VK_F7:
			VolSetClick( NULL );
			break;

		case VK_F8:
			if( !m_btnRecord->Down )
				OnMicSetting( NULL );
			break;

		case VK_F9:
		case VK_F10:
		case VK_F11:
			if( !m_btnRecord->Down )
				OnViewMode( (TObject*)MAKELONG(0,(Key - VK_F9)) );
			break;

		case VK_F12:
			if( !m_btnRecord->Down )
				OnLoadMelody( NULL );
			break;

		case VK_CONTROL:
			if( w_bDraging && w_iDragMode==DM_ADJUSTSTAGE && Screen->Cursor==crDefault ){
				Screen->Cursor = crDrag;
			}
			break;

		default:
			break;
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
	switch (Key) {
	case VK_CONTROL:
		if( w_bDraging && w_iDragMode==DM_ADJUSTSTAGE && Screen->Cursor==crDrag ){
			Screen->Cursor = crDefault;
		}
		break;

	default:
		break;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMShowPlayTime(TMessage &Message)
{
	m_iLastStartBar = m_iStartBar = Message.WParam;
	m_dblLastStartPoint = m_dblStartPoint = Message.LParam;

	ShowPlayTime();

	if( m_pContentPanel->IsPlaying() ){
		double dblComposeStartPoint = m_iStartBar + m_dblStartPoint / POINTS_PER_BAR ;

		if( g_lstOpusStages.size()>0 ){
			SetPlayTimer(false, m_tTimer, m_tAccuracy);
			GenerateCompose();

			int iPlayMode = TYPE_COMPOSE | ( g_iPreStage==0 ? TYPE_AUDIO : TYPE_SONG );
			f_MM_Play( Handle, dblComposeStartPoint, iPlayMode );

			SetPlayTimer( true, m_tTimer, m_tAccuracy, Handle );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::PlayClick(TObject *Sender)
{
	if( g_lstOpusStages.size()==0 )
		return;

	Perform( UM_STOP, STOP_USESTYLE|STOP_PRESTYLE|STOP_AUDSTYLE, 0 );
	m_pContentPanel->SetFocus();
	GenerateCompose();

	double dblAudioStartPoint = m_iStartBar + m_dblStartPoint / POINTS_PER_BAR;

	if( g_bRecProtect && g_bShowProtectMsg ){
		MessageForm->ShowMessage( "使用收费风格，将可能听到随机杂音\n\n但不会影响保存的歌曲",
												MB_ICONINFORMATION|MB_OK|MB_UNCHECKED, "提示" );
		g_bShowProtectMsg = !MessageForm->m_pbCheck->Checked;
	}

	int iPlayMode = TYPE_COMPOSE | ( g_iPreStage==0 ? TYPE_AUDIO : TYPE_SONG );
	HRESULT hr = f_MM_Play( Handle, dblAudioStartPoint, iPlayMode );

	if( hr==S_OK && !m_pContentPanel->IsPlaying() ){
		SetPlayTimer( true, m_tTimer, m_tAccuracy, Handle );

		m_pContentPanel->Play(true);
		m_btnRecord->Enabled = false;
		m_btnPlay->Visible = false;
		m_btnPlay->Enabled = false;
		m_btnPause->Visible = true;
		m_btnStop->Enabled = true;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::PauseClick(TObject *Sender)
{
	if (m_pContentPanel->IsPlaying()) {
		SetPlayTimer(false, m_tTimer, m_tAccuracy);

		f_MM_Stop();

		m_nVolLevel = 0;
		m_pbVolLevel->Invalidate();

		m_pContentPanel->Play(false);
	}

	m_btnPlay->Visible = true;
	m_btnPlay->Enabled = !g_lstOpusStages.empty();
	m_btnPause->Visible = false;
}
//---------------------------------------------------------------------------

HRESULT __fastcall TMainForm::AutoRecognition( int iMode )
{
	int nOffsetBars, nValidBars;
	f_MM_GetMelodyBars( &nOffsetBars, &nValidBars );

	TOpusStageList *lstStagesBefore = NULL,
					*lstStagesAfter = NULL;
	UINT idLoc = -1, idStyle = -1;

	int iType = g_Undo.GetUndoType();

	if( iType>=UNDO_AUDIO_ERASE && iType<=UNDO_AUDIO_RECORD ){
		if( g_pUseStyle && g_pUseStyle->pStyle ){
			idLoc = g_pUseStyle->pStyle->idLoc;
			idStyle = g_pUseStyle->pStyle->idStyle;
		}

		g_Theme.Set( idLoc, idStyle, g_lstOpusStages );

		lstStagesBefore = new TOpusStageList;
		lstStagesAfter = new TOpusStageList;

		g_Theme.Get( idLoc, idStyle, *lstStagesBefore );
	}

	if( nValidBars==0 ){
		String msg = L"无效的主旋律输入";

		if( iMode==MODE_RECORD )
			msg += L"\n请调整录音设备音量后重新录音！";

		MessageForm->ShowMessage( msg, MB_OK | MB_ICONERROR);

		if( iType>=UNDO_AUDIO_ERASE && iType<=UNDO_AUDIO_RECORD ){
			if( g_lstOpusStages.empty() ){
				g_Undo.CancelUndo();
				f_MM_CancelAddUndo();
			}
			else{
				f_MM_AddUndoAfter( 1, &g_iSelAudio );
				g_Undo.SetUndoExtra( idLoc, idStyle, 0, lstStagesBefore, lstStagesAfter );
				g_Theme.Clear();
			}
		}

		m_btnPlay->Enabled = false;
//		g_bAudioLoaded = false;
		g_bWeakup = false;

		g_iMelodyKey = -1;

		for( int i=g_aAudioTracks[0]->lstBars.size()-1; i>=0; i-- ){
			delete g_aAudioTracks[0]->lstBars[i];
		}

		g_aAudioTracks[0]->lstBars.clear();
	}
	else{
		if( iMode==MODE_LOAD ){
			g_aAudioTracks[0]->Hide(false);

			for (int i = 0; i < nValidBars; i++) {
				TWaveBar* pBar = new TWaveBar;

				for( int j=0; j<POINTS_PER_BAR; j++ ){
					pBar->aVols[j] = f_MM_GetAudioVolume( 0, i + j/(double)POINTS_PER_BAR );
				}

				g_aAudioTracks[0]->lstBars.push_back(pBar);
			}

		}
		else{
			for (int i = 0; i < nOffsetBars; i++) {
				delete g_aAudioTracks[0]->lstBars.front();
				g_aAudioTracks[0]->lstBars.erase( g_aAudioTracks[0]->lstBars.begin() );
			}

			while( g_aAudioTracks[0]->lstBars.size()>nValidBars ){
				delete g_aAudioTracks[0]->lstBars.back();
				g_aAudioTracks[0]->lstBars.pop_back();
			}
		}

		AudioEffectsDefault( 0 );

		SetMelodyNotes( nValidBars );

		if( AutoChords()==S_OK ){
			if( iType>=UNDO_AUDIO_ERASE && iType<=UNDO_AUDIO_RECORD ){
				TAudioTrack* pAudio = CopyAudioTrack( 0, 0, nValidBars );
				g_Theme.Get( idLoc, idStyle, *lstStagesAfter );

				f_MM_AddUndoAfter( 1, &g_iSelAudio );
				TUndoLite* pUndo = g_Undo.GetLastLite();
				pUndo->pAfter = pAudio;
				pUndo->iEnd = g_iMelodyKey;
				g_Undo.SetUndoExtra( idLoc, idStyle, 0, lstStagesBefore, lstStagesAfter );
			}

			((TUseStylePanel*)m_pUseStylePanel)->InitOpus( g_pPreStyle,	g_iPreStage );

			m_UseStyleHeight = m_UseStyleHeight + m_PreStyleHeight - TOOLPAL_MINHEIGHT;
			m_PreStyleHeight = TOOLPAL_MINHEIGHT;

			m_pUseStylePanel->SetBounds( m_pUseStylePanel->Left,
										m_pUseStylePanel->Top,
										m_pUseStylePanel->Width,
										m_UseStyleHeight );
			m_pPreStylePanel->SetBounds( m_pPreStylePanel->Left,
										m_pUseStylePanel->Top + m_UseStyleHeight,
										m_pPreStylePanel->Width,
										m_PreStyleHeight );

			GenerateCompose();

			m_iStartBar = 0;
			m_dblStartPoint = 0;
			m_dwLastVol = 0;
			m_pContentPanel->SetPlayPoint( 0, 0 );
		}
	}

	if( nValidBars==0 )
		SetMode( VIEW_INIT, true );
	else if( g_iViewMode==VIEW_STYLE )
		m_pContentPanel->InvalidateShowBars();
	else
		SetMode( VIEW_STYLE );

	m_btnRecord->Down = false;
	m_btnPlay->Visible = true;
	m_btnPlay->Enabled = !g_lstOpusStages.empty();
	m_btnRecord->Enabled = RecordEnabled();
	m_btnPause->Visible = false;
	m_btnStop->Enabled = false;
	m_btnSave->Enabled = !g_lstOpusStages.empty();
	m_btnUpload->Enabled = !g_bUpdateMandatory && !g_lstOpusStages.empty();
	//g_bSongSaved = false;
	m_bFromFile = false;
	m_cbKey->DefItemIndex = g_iMelodyKey;
	m_cbKey->Enabled = g_iMelodyKey>=0;
}
//---------------------------------------------------------------------------

HRESULT __fastcall TMainForm::AutoChords()
{
	HRESULT hRet = S_OK;

	int nStageNum = 0,//g_lstRawStages.size(),
		nBarNum = g_aAudioTracks[0]->lstBars.size(),
		nChordNum = 0;
	TBarChords *aChords = new TBarChords[nBarNum];

	int *aStages = NULL;

	DebugPrint("//////////////////分段输出/////////////////////");
	if( nStageNum>0 ){
		aStages = new int[nStageNum];
	}
	else {
		aStages = new int[nBarNum];
	}

	DebugPrint("CM_AutoChords");
	hRet = f_CM_AutoChords( g_iMelodyKey, &nChordNum, aChords,
											&nStageNum,	aStages );

	if( hRet==0 ) {
		vector<int> lstStages;
		TBarList lstBars;

		DebugPrint("//////////////////分段输入/////////////////////");
		for (int i = 0; i < nStageNum; i++) {
			lstStages.push_back(aStages[i]);
			DebugPrint( " %d ", aStages[i] );
		}

		DebugPrint("//////////////////和弦输入/////////////////////");
		for( int i=0; i<nBarNum; i++ ){
			TBar* pBar = new TBar;
			pBar->iBarKey = g_iMelodyKey;
			memcpy( &pBar->aChords, &aChords[i], sizeof(TBarChords) );
			DebugPrint( " %d-%d %d-%d %d-%d %d-%d",
							pBar->aChords.iKey[0],
							pBar->aChords.iType[0],
							pBar->aChords.iKey[1],
							pBar->aChords.iType[1],
							pBar->aChords.iKey[2],
							pBar->aChords.iType[2],
							pBar->aChords.iKey[3],
							pBar->aChords.iType[3] );
			lstBars.push_back( pBar );
		}

		g_Theme.Build( lstBars, lstStages );
	}
	else {
		DebugPrint("AutoChords error.\n");
	}

 	SAFE_DELETE_ARRAY(aChords);
	SAFE_DELETE_ARRAY(aStages);

	return hRet;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnLoadMelody(TObject *Sender)
{
	if( !g_pPreStyle || g_pPreStyle->nSegNum[SEGTYPE_VAR]==0 ){
		MessageForm->ShowMessage( "请为预编风格添加伴奏片段！", MB_ICONERROR|MB_OK );

		return;
	}

	OnCreateNewProject( NULL );

	if( !g_Theme.Empty() )
		return;

	// 指定文件名
	wstring strFileName;

	int iTS = g_iMelodyTimeSignature, iTempo = g_nMelodyTempo;

	TImportForm *imF = new TImportForm(NULL, g_strLastImportFile.c_str(), iTS, iTempo, 0);
	if(imF->ShowModal() == mrOk)
	{
		strFileName = imF->MediaFilePath.c_str();
		iTS = imF->TS;
		iTempo = imF->Tempo;
	}
	delete imF;

	if( strFileName.length() > 0 ){
		SetMode( VIEW_INIT );
//		g_bAudioLoaded = false;

		m_bFromFile = true;
		int iFileType = FILETYPE_MIDI;
		if( ExtractFileExt( strFileName.c_str() ).CompareIC(".mid")==0 ){
			g_bMidiMelody = true;
		}
		else{
			g_bMidiMelody = false;

			ChangeTT( true, iTS );
			ChangeTT( false, iTempo );

			if( ExtractFileExt( strFileName.c_str() ).CompareIC(".wav")==0){
				iFileType = FILETYPE_WAVE;
			}
			else if( ExtractFileExt( strFileName.c_str() ).CompareIC(".mp3")==0){
				iFileType = FILETYPE_MP3;
			}
		}

		TProgressForm *frmProgress = new TProgressForm(NULL);

		int ret = frmProgress->MM_Load( strFileName.c_str(), iFileType );
		int extra = frmProgress->GetOpertaionResult();
		//TMessage msgReturn = frmProgress->m_MsgTransparent;

		delete frmProgress;

		if( ret==mrOk ){
			g_strLastImportFile = strFileName.c_str();

			if( g_bMidiMelody ){
				f_MM_GetMelodyInfo( &iTS, &iTempo );
				ChangeTT( true, iTS );
				ChangeTT( false, iTempo );
			}

			AutoRecognition( MODE_LOAD );

			//PostMessage( Handle, msgReturn.Msg, msgReturn.WParam, msgReturn.LParam );
		}
		else{
			if( extra!=e_UserCanceled )
				ShowErrorMessage( ret, "导入旋律失败！" );

			g_bMidiMelody = false;
		}
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::PanelMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
	if( m_btnRecord->Down )
		return;

	if( w_bDraging ){
		TWinControl* pSender = (TWinControl*)Sender;
		TPoint pt( X, Y );
		pt = pSender->ClientToScreen( pt );

		if( w_iDragMode==DM_ADJUSTHEIGHT ){
			int yMin = Top + PANEL_TOP + TOOLPAL_MINHEIGHT,
				yMax = Top + Height - STATE_HEIGHT - TOOLPAL_MINHEIGHT;

			if( pSender==m_pPreStylePanel ){
				yMax -= TOOLPAL_MINHEIGHT;
			}
			else{
				yMin += TOOLPAL_MINHEIGHT;
			}

			w_yImgDrag = pt.Y - w_yOffDrag;

			if( w_yImgDrag<yMin ){
				w_yImgDrag = yMin;
				w_yOffDrag = 0;
				SetCursorPos( pt.X, yMin );
			}
			else if( w_yImgDrag>yMax ){
				w_yImgDrag = yMax;
				w_yOffDrag = 0;
				SetCursorPos( pt.X, yMax );
			}

			if( w_yImgDrag!=w_yOldDrag ){
				m_pUseStylePanel->ShowDragImg();
				m_pPreStylePanel->ShowDragImg();
				m_pAudStylePanel->ShowDragImg();
			}

			w_yOldDrag = w_yImgDrag;
		}
		else if( w_iDragMode==DM_ADJUSTWIDTH ){
			int xMin = Left + PANEL_BOUND,
				xMax = Left + Width - PANEL_BOUND;

			if( g_iToolPanelShow==0 ){
				xMin += CONTENT_MINWIDTH;
				xMax -= TOOLPAL_MINWIDTH;
			}
			else{
				xMin += TOOLPAL_MINWIDTH;
				xMax -= CONTENT_MINWIDTH;
			}

			w_xImgDrag = pt.X - w_xOffDrag;

			if( w_xImgDrag<xMin ){
				w_xImgDrag = xMin;
				w_xOffDrag = 0;
				SetCursorPos( xMin, pt.Y );
			}
			else if( w_xImgDrag>xMax ){
				w_xImgDrag = xMax;
				w_xOffDrag = 0;
				SetCursorPos( xMax, pt.Y );
			}

			if( w_xImgDrag!=w_xOldDrag ){
				if( m_pUseStylePanel->Visible ){
					m_pUseStylePanel->ShowDragImg();
					m_pPreStylePanel->ShowDragImg();
					m_pAudStylePanel->ShowDragImg();
				}
				else if( m_pChordPanel->Visible )
					m_pChordPanel->ShowDragImg();
				else
					m_pTrackPanel->ShowDragImg();

				m_pContentPanel->ShowDragImg();
			}

			w_yOldDrag = w_yImgDrag;
			w_xOldDrag = w_xImgDrag;
		}
		else if( w_iDragMode==DM_ADJUSTHEADER ){
			int xMin = Left + m_pContentPanel->Left + MIN_HDR_WIDTH,
				xMax = Left + m_pContentPanel->Left + MAX_HDR_WIDTH;

			w_xImgDrag = pt.X - w_xOffDrag;

			if( w_xImgDrag<xMin ){
				w_xImgDrag = xMin;
				w_xOffDrag = 0;
				SetCursorPos( xMin, pt.Y );
			}
			else if( w_xImgDrag>xMax ){
				w_xImgDrag = xMax;
				w_xOffDrag = 0;
				SetCursorPos( xMax, pt.Y );
			}

			if( w_xImgDrag!=w_xOldDrag ){
				m_pContentPanel->ShowDragImg();
			}

			w_yOldDrag = w_yImgDrag;
			w_xOldDrag = w_xImgDrag;
		}
		else if( w_iDragMode==DM_ADJUSTSTYLE ){
			TCommonItem* pDragItem = ((TStylePanel*)Sender)->GetDragItem();
			if( !((TStylePanel*)m_pUseStylePanel)->GetDropItem() )
				((TStylePanel*)m_pUseStylePanel)->SetDropItem( pDragItem );
			if( !((TStylePanel*)m_pPreStylePanel)->GetDropItem() )
				((TStylePanel*)m_pPreStylePanel)->SetDropItem( pDragItem );
			if( !m_pContentPanel->GetDropItem() )
				m_pContentPanel->SetDropItem( pDragItem );

			w_xImgDrag = pt.x - w_xOffDrag;
			w_yImgDrag = pt.Y - w_yOffDrag;

			if( w_yImgDrag!=w_yOldDrag || w_xImgDrag!=w_xOldDrag ){
				bool bContentDrop = m_pContentPanel->ShowDragImg();
				bool bUseDrop = m_pUseStylePanel->ShowDragImg();
				bool bPreDrop = m_pPreStylePanel->ShowDragImg();
				bool bAudDrop = m_pAudStylePanel->ShowDragImg();

				if( bContentDrop || bUseDrop || bPreDrop || bAudDrop ){
					if( Screen->Cursor!=crDefault )
						Screen->Cursor = crDefault;//crDrag;
				}
				else{
					if( Screen->Cursor!=crNoDrop )
						Screen->Cursor = crNoDrop;
				}
			}

			w_xOldDrag = w_xImgDrag;
			w_yOldDrag = w_yImgDrag;
		}
		else if( w_iDragMode==DM_ADJUSTSTAGE || w_iDragMode==DM_ADJUSTAUDIO ){
			w_xImgDrag = pt.x - w_xOffDrag;
			w_yImgDrag = pt.Y - w_yOffDrag;

			if( w_yImgDrag!=w_yOldDrag || w_xImgDrag!=w_xOldDrag ){
				bool bContentDrop = m_pContentPanel->ShowDragImg();

				if( bContentDrop ){
					if( Shift.Contains( ssCtrl ) ){
						if( Screen->Cursor!=crDrag )
							Screen->Cursor = crDrag;
					}
					else{
						if( Screen->Cursor!=crDefault )
							Screen->Cursor = crDefault;//crDrag;
					}
				}
				else{
					if( Screen->Cursor!=crNoDrop )
						Screen->Cursor = crNoDrop;
				}
			}

			w_xOldDrag = w_xImgDrag;
			w_yOldDrag = w_yImgDrag;
		}
	}
	else{
		if( Shift.Empty() ){
			if( Sender!=m_pUseStylePanel )
				((TStylePanel*)m_pUseStylePanel)->SetFocusedItem( NULL, -1, 0 );

			if( Sender!=m_pPreStylePanel )
				((TStylePanel*)m_pPreStylePanel)->SetFocusedItem( NULL, -1, 0 );

			if( Sender!=m_pAudStylePanel )
				((TStylePanel*)m_pAudStylePanel)->SetFocusedItem( NULL, -1, 0 );
		}

		((TPanel*)Sender)->Perform( UM_MOUSEMOVE, Shift.ToInt(), MAKELONG( X, Y ) );
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::PanelMouseUp(TObject *Sender, TMouseButton Button,
												TShiftState Shift, int X, int Y)
{
	if( m_btnRecord->Down )
		return;

	if( w_bDraging ){
		ReleaseCapture();
		w_bDraging = false;

		TWinControl* pSender = (TWinControl*)Sender;
		TPoint pt( w_xImgDrag, w_yImgDrag );
		pt = ScreenToClient( pt );

		if( w_iDragMode==DM_ADJUSTHEIGHT ){
			int hStyle = m_pContentPanel->Height,
				hUse = m_UseStyleHeight,
				hPre = m_PreStyleHeight,
				hAud = hStyle - hUse - hPre;

			if( pSender==m_pPreStylePanel ){
				hUse = pt.Y - m_pUseStylePanel->Top;
				if( hUse<TOOLPAL_MINHEIGHT )
					hUse = TOOLPAL_MINHEIGHT;

				if( pt.Y > m_pAudStylePanel->Top - TOOLPAL_MINHEIGHT ){
					hPre = TOOLPAL_MINHEIGHT;
					hAud = hStyle - hUse - hPre;
					if( hAud<TOOLPAL_MINHEIGHT ){
						hUse -= TOOLPAL_MINHEIGHT - hAud;
						hAud = TOOLPAL_MINHEIGHT;
					}
				}
				else
					hPre = hStyle  - hUse - hAud;

				((TStylePanel*)m_pPreStylePanel)->ShowDragImg(false);
			}
			else{
				hAud = m_pContentPanel->Top + hStyle - pt.Y;
				if( hAud<TOOLPAL_MINHEIGHT )
					hAud = TOOLPAL_MINHEIGHT;

				if( pt.Y<m_pPreStylePanel->Top+TOOLPAL_MINHEIGHT ){
					hPre = TOOLPAL_MINHEIGHT;
					hUse = hStyle - hAud - hPre;
					if( hUse<TOOLPAL_MINHEIGHT ){
						hAud -= TOOLPAL_MINHEIGHT - hUse;
						hUse = TOOLPAL_MINHEIGHT;
					}
				}
				else
					hPre = hStyle - hAud - hUse;
			}

			((TStylePanel*)m_pUseStylePanel)->ShowDragImg(false);
			((TStylePanel*)m_pPreStylePanel)->ShowDragImg(false);
			((TStylePanel*)m_pAudStylePanel)->ShowDragImg(false);

			int l = m_pUseStylePanel->Left,
				t = m_pUseStylePanel->Top,
				w = m_pUseStylePanel->Width;

			m_pUseStylePanel->SetBounds( l, t, w, hUse );
			m_pPreStylePanel->SetBounds( l, t+hUse, w, hPre );
			m_pAudStylePanel->SetBounds( l, t+hUse+hPre, w, hAud );

			m_UseStyleHeight = hUse;
			m_PreStyleHeight = hPre;
		}
		else if( w_iDragMode==DM_ADJUSTWIDTH ){
			if( m_pUseStylePanel->Visible ){
				m_pUseStylePanel->ShowDragImg(false);
				m_pPreStylePanel->ShowDragImg(false);
				m_pAudStylePanel->ShowDragImg(false);
			}
			else if( m_pChordPanel->Visible )
				m_pChordPanel->ShowDragImg(false);
			else
				m_pTrackPanel->ShowDragImg(false);

			m_pContentPanel->ShowDragImg( false );

			if( pSender==m_pContentPanel ){
				m_ToolpalWidth = pt.x - PANEL_BOUND;
			}
			else{
				m_ToolpalWidth = Width - pt.X - PANEL_BOUND;
			}

			ViewLayout();
		}
		else if( w_iDragMode==DM_ADJUSTHEADER ){
			m_pContentPanel->ShowDragImg( false );
		}
		else if( w_iDragMode==DM_ADJUSTSTYLE ){
			int iKeyState = Shift.ToInt();
			((TStylePanel*)m_pUseStylePanel)->ShowDragImg( false, iKeyState );
			((TStylePanel*)m_pPreStylePanel)->ShowDragImg( false, iKeyState );
			((TStylePanel*)m_pAudStylePanel)->ShowDragImg( false, iKeyState );
			m_pContentPanel->ShowDragImg( false, iKeyState );
		}
		else if( w_iDragMode==DM_ADJUSTSTAGE || w_iDragMode==DM_ADJUSTAUDIO ){
			m_pContentPanel->ShowDragImg( false, Shift.ToInt() );
		}

		delete w_imgDrag;
		w_imgDrag = NULL;
	}
	else{
		if( Button==mbLeft )
			Shift << ssLeft;
		else if( Button==mbRight )
			Shift << ssRight;

		((TPanel*)Sender)->Perform( UM_MOUSEUP, Shift.ToInt(), MAKELONG( X, Y ) );
	}

	if( !m_pContentPanel->IsStyleBrush() && Screen->Cursor!=crDefault ){
		if( Screen->Cursor>=crBrush && Screen->Cursor<=crBrushNo ){
			m_pContentPanel->CancelBrush();
		}

		Screen->Cursor = crDefault;
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::UMStop(TMessage &msg)
{
	DWORD dwSpec = msg.WParam;

	if( ( dwSpec & STOP_CONTENT ) && m_pContentPanel->IsPlaying() )
		StopClick(NULL);
	if( dwSpec & STOP_USESTYLE )
		((TStylePanel*)m_pUseStylePanel)->Stop();
	if( dwSpec & STOP_PRESTYLE )
		((TStylePanel*)m_pPreStylePanel)->Stop();
	if( dwSpec & STOP_AUDSTYLE )
		((TStylePanel*)m_pAudStylePanel)->Stop();
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::UMShowBrush(TMessage &msg)
{
	if( g_lstOpusStages.size()>0 ){
		if( g_iViewMode==VIEW_STYLE ){
			TCommonItem* pItem = (TCommonItem*)msg.LParam;
			m_pContentPanel->BeginBrush( pItem );
			Screen->Cursor = crBrushNo;
		}
	}
}
// ---------------------------------------------------------------------------

void __fastcall TMainForm::TabClick(TObject *Sender)
{
	if( g_iViewMode!=VIEW_INIT ){
		TPNGButton* pBtn = (TPNGButton*)Sender;
		if( pBtn==m_tabAudio && !m_tabAudio->Down ){
			SetMode( VIEW_TRACK );
		}
		else if( pBtn==m_tabChord && !m_tabChord->Down ){
			SetMode( VIEW_CHORD );
		}
		else if( pBtn==m_tabStyle && !m_tabStyle->Down ){
			SetMode( VIEW_STYLE );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::TTClick(TObject* Sender)
{
	if( !g_Theme.Empty() ){// g_lstRawBars.size()>0 ){
		if( Sender==m_btnTS ){
			String strMsg = "新建工程才可以改变节拍！";
			MessageForm->ShowMessage( strMsg, MB_ICONERROR|MB_OK );
			return;
		}
		else{
			String strMsg = "警告：改变速度将清空支付记录";

			if( g_aAudioTracks.size()>1 || g_aAudioTracks[0]->lstBars.size()>0 ){
				strMsg += "\n以及音频数据";
			}

			strMsg += ",且不可撤销！";
			MessageForm->ShowMessage( strMsg, MB_ICONINFORMATION|MB_OK );
		}
	}

	PostMessage( Handle, UM_TTSETUP, 0, 0 );
}
//---------------------------------------------------------------------------

//add by tj 2013/12/24 17:47
void __fastcall TMainForm::UMTTSetup(TMessage &Message)
{
/*	if( g_bAudioLoaded ) {
		String strMsg = "新建工程才可以改变节拍或速度！";
		MessageForm->ShowMessage( strMsg, MB_ICONERROR|MB_OK );
		return;
	}
*/
	Perform( UM_STOP, STOP_ALL, 0 );

	if( m_KeyBoard->Visible ){
		m_KeyBoard->ShowKeyboard( false );
		if( m_btnKeyboard->Down )
			m_btnKeyboard->Down = false;
	}

	TSetUpForm *SetUpForm = new TSetUpForm(this);

	if(SetUpForm->ShowModal()==mrOk)
	{
		if( SetUpForm->m_nTempo!=g_iMelodyTimeSignature ||
					 SetUpForm->m_iTS!=g_iMelodyTimeSignature ) {
			ChangeTT( true, SetUpForm->m_iTS );
			ChangeTT( false, SetUpForm->m_nTempo );
		}
	}else {
		f_MM_SetTempo( g_nMelodyTempo );
		f_MM_SetTimeSignature( g_iMelodyTimeSignature );
	}

	delete SetUpForm;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMChangeTT(TMessage &Message)
{
	ChangeTT( Message.WParam, Message.LParam );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ChangeTT( bool bTS, int iValue )
{
	if( bTS && iValue!=g_iMelodyTimeSignature ){
		if( iValue>=0 ){
			SetMelodyTS( iValue );
			g_infoSong.iTS = iValue;
			SetMode( VIEW_INIT );
			SelectStyle();
		}

		m_btnTS->Caption = g_strTimeSignature[g_iMelodyTimeSignature];
		m_btnTS->Invalidate();

		((TStylePanel*)m_pAudStylePanel)->InitItems();
		if( iValue>=0 )
			((TStylePanel*)m_pPreStylePanel)->InitItems();
	}

	if( !bTS && iValue!=g_nMelodyTempo ){
		SetMelodyTempo( iValue );
		g_infoSong.iTempo = iValue;
		m_btnTempo->Caption = IntToStr(g_nMelodyTempo);
		m_btnTempo->Invalidate();

//		if( g_iViewMode==VIEW_TRACK )
		m_pContentPanel->InitialVars();
//		m_pContentPanel->Invalidate();
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::PreStageChange(TComboBoxItem *Sender, int Index)
{
	if( m_cbPreStage->DefItemIndex!=Index )
		m_cbPreStage->DefItemIndex = Index;

	if( Index!=g_iPreStage ){
		if( g_Theme.Empty() ){
			g_iPreStage = Index;
			return;
		}

		StopClick( NULL );

		//检查预设风格片段
		if ( Sender!=NULL && !g_lstOpusStages.empty() ){
			TOpusStageList* lstStages = NULL;
			TAudioTrackList* lstAudio = NULL;

			if( g_iPreStage>0 && Index<3 ){
				lstStages = new TOpusStageList;
				lstAudio = new TAudioTrackList;

				((TUseStylePanel*)m_pUseStylePanel)->CopyUndoBars( 0, GetBarCount()-1, lstStages, lstAudio, true );

				if( g_aAudioTracks.size()>1 ){
//					int iTracks = g_Audio.GetTrackBit();
					f_MM_AddUndoBefore( -1, NULL );
				}
			}

			g_Undo.AddUndo( UNDO_PRESET, 0, g_iPreStage, Index, (void*)lstStages, NULL );
			g_Undo.SetUndoExtra( 0, 0, 0, (void*)lstAudio, NULL );
		}

		if( Index==0 )
			g_aAudioTracks[0]->Hide(false);
		else if( Index==3 && g_iPreStage==0 )
			DuplicateRawBars();

		g_iPreStage = Index;

		if( !g_Theme.Empty() && g_iPreStage<3 ){
			if( g_Theme.GetKey()!=g_iMelodyKey ){
				g_iMelodyKey = g_Theme.GetKey();
				m_cbKey->DefItemIndex = g_iMelodyKey;
			}

			((TUseStylePanel*)m_pUseStylePanel)->InitOpus( g_pPreStyle,	g_iPreStage );

			SetMode( VIEW_STYLE, true );
			GenerateCompose();
		}

        m_btnPlay->Enabled = !g_lstOpusStages.empty();
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMStageChanged(TMessage &Message)
{
	int iPreset = Message.WParam;

	if( m_cbPreStage->DefItemIndex!=iPreset ){
		m_cbPreStage->DefItemIndex = iPreset;
		g_iPreStage = iPreset;
	}

	bool bEnable = !g_lstOpusStages.empty();
	m_btnPlay->Enabled = bEnable;
	m_btnSave->Enabled = bEnable;
	m_btnUpload->Enabled = bEnable && !g_bUpdateMandatory;
	m_btnRecord->Enabled = bEnable ? RecordEnabled() : false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::VolLevelPaint(TObject *Sender)
{
	int xPos = 0;
	for (int i = 0; i < m_nVolLevel; i++) {
		if (i < 22) {
			m_pbVolLevel->Canvas->Brush->Color = RGB(70, 154, 8);
			m_pbVolLevel->Canvas->Pen->Color = RGB(70, 154, 8);
		}
		else if (i < 32) {
			m_pbVolLevel->Canvas->Brush->Color = RGB(221, 241, 2);
			m_pbVolLevel->Canvas->Pen->Color = RGB(221, 241, 2);
		}
		else if (i < 42) {
			m_pbVolLevel->Canvas->Brush->Color = RGB(221, 122, 0);
			m_pbVolLevel->Canvas->Pen->Color = RGB(221, 122, 0);
		}
		else if (i < 52) {
			m_pbVolLevel->Canvas->Brush->Color = RGB(215, 78, 2);
			m_pbVolLevel->Canvas->Pen->Color = RGB(215, 78, 2);
		}
		else {
			m_pbVolLevel->Canvas->Brush->Color = RGB(255, 0, 0);
			m_pbVolLevel->Canvas->Pen->Color = RGB(255, 0, 0);
		}

		m_pbVolLevel->Canvas->Rectangle(xPos, 0, xPos + 2,
			m_pbVolLevel->Height);

		xPos += 3;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnSaveAs(TObject *Sender)
{
	SaveAs( SAVE_ALL );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SaveAs( int iComb ){
	int iSaveType = iComb & 0x0F00,
		iSaveTrack = iComb & 0xFF;
	TSaveForm *saveForm = new TSaveForm( NULL, iSaveType );

	if( saveForm->ShowModal()==mrOk ){
		String strFileName = saveForm->FilePath;
		g_iLastSaveType = saveForm->SaveType;

		AnsiString strTitle = TPath::GetFileNameWithoutExtension( strFileName );
		strcpy( g_infoSong.strSongName, strTitle.c_str() );

		if( saveForm->SaveType==FILETYPE_CPJ ){
			if( CanSaveProj()==E_PROJ_UNSAVEDTEMPSTYLE ){ //自制风格尚未保存，提示保存
				if( mrOk==MessageForm->ShowMessage( "请先保存正在编辑的自制风格！",
														MB_ICONQUESTION | MB_OKCANCEL, "保存工程" )){
					Application->MainForm->Perform( UM_SAVELOCALSTYLE, 0, 0 );
				}
				else{
					goto Cleanup_Line;
				}
			}

			// 保存工程
			// 工程路径：
			TProgressForm *frmProgress = new TProgressForm(NULL);
			int ret = frmProgress->Project_Save(strFileName.c_str());
			int eExtra = frmProgress->GetOpertaionResult();
			if( ret==mrOk && eExtra==0 ){
				MessageForm->ShowMessage("工程文件保存成功。", MB_OK | MB_ICONINFORMATION);
				m_lblTitle->Caption = strTitle;

				g_strProjectName = strFileName.c_str();
				g_strLastProjSavePath = ExtractFilePath( strFileName.c_str() ).c_str();
				g_bAutoOpenProjectEnable = true;  //add by tj 2014/05/15
				SetInitVar();
			}
			else if( eExtra!=0 && eExtra!=e_UserCanceled ){
				MessageForm->ShowMessage( "工程文件保存失败!", MB_ICONERROR|MB_OK );
			}

			delete frmProgress;
		}
		else{
			Perform( UM_STOP, STOP_CONTENT | STOP_USESTYLE, 0 );
			//先编曲，防止用户修改风格后不播放直接保存
			GenerateCompose();

			// 保存媒体文件
			int iOperation = e_PO_Pay4Basic;

			if( saveForm->MediaOption & SAVE_COMPOSE )
				iOperation |= e_PO_Pay4Compose;

			if( saveForm->SaveType==FILETYPE_MIDI )
				iOperation |= e_PO_Pay4Midi;
			else{
				if( iSaveType==SAVE_AUDIO && g_iSelAudio>1 || iSaveType!=SAVE_AUDIO
														&& (saveForm->MediaOption & SAVE_AUDIO)
														&& g_aAudioTracks.size()>2  )
					iOperation |= e_PO_Pay4Audios;

				if( (saveForm->MediaOption & SAVE_COMPOSE) && ( g_bExtFont
									|| ((TUseStylePanel*)m_pUseStylePanel)->Charge4Fonts()) )
					iOperation |= e_PO_Pay4Fonts;
			}

			int iSaveOption = saveForm->MediaOption;
			int iFileType = saveForm->SaveType;

			if( iSaveType==SAVE_AUDIO || iSaveType==SAVE_COMPOSE )
				iSaveOption += iSaveTrack;

			//先检查文件名有效性
			int iFileHandle = FileOpen( strFileName, fmOpenReadWrite );
			bool bCreate = false;

			if( iFileHandle<0 ){
				iFileHandle = FileCreate( strFileName );
				bCreate = true;
			}

			if( iFileHandle<0 ){
				ShowErrorMessage( e_OpenFileFailed, L"保存失败!" );
				goto Cleanup_Line;
			}
			else{
				FileClose( iFileHandle );

				if( bCreate )
					DeleteFile( strFileName );
			}

			// 检查是否可复制
			if( iFileType==FILETYPE_MP3 && ( iSaveOption==(SAVE_COMPOSE|SAVE_AUDIO)
											|| iSaveOption==SAVE_COMPOSE && g_aAudioTracks.size()==1 )
										&& !m_strUploadFile.IsEmpty() && FileExists(m_strUploadFile, false)
										&& g_Undo.GetLastLite()==u_pUploadLite ){
				if( m_strUploadFile.CompareIC( strFileName )){
					CopyFile( m_strUploadFile.c_str(), strFileName.c_str(), false );
				}

				g_strLastSavePath = ExtractFilePath( strFileName.c_str() ).c_str();
				g_iLastSaveOption = iSaveOption & 0x0F00;

				String strMessage = "媒体文件导出成功。";
				MessageForm->ShowMessage( strMessage, MB_OK|MB_ICONINFORMATION, "导出" );
			}
			else{
				SaveMedia( iOperation, iSaveOption, iFileType, strFileName );
			}
		}
	}

Cleanup_Line:
	delete saveForm;
}
//---------------------------------------------------------------------------

int __fastcall TMainForm::SaveMedia( int iOperation, int iSaveOption, int iFileType, String strFileName, bool bUpload )
{
	if( SOFTWARE_ID!=e_Pro_Lite ){
		if( !g_bLogon )
			Perform( UM_LOGIN, true, 0 );

		if( !g_bLogon )
			return -1;
	}

	bool bConfirm = false;
	UINT nIdCount = 0, aIdStyle[MAX_STYLE_NUM];

	for( int i=0; i<g_lstOpusStages.size(); i++ ){
		TOpusStage* pStage = g_lstOpusStages[i];
		for( int j=0; j<pStage->aTracks.size(); j++ ){
			if( pStage->aTracks[j]->iStyleLoc==0 ){
				int id = pStage->aTracks[j]->iStyleId;

				bool bExist = false;
				for( int j=0; j<nIdCount; j++ ){
					if( id==aIdStyle[j] ){
						bExist = true;
						break;
					}
				}
				if( !bExist ){
					if( nIdCount>=MAX_STYLE_NUM ){
						char buf[200];
						sprintf( buf, "歌曲使用的风格数超过%d个只能保存为工程！", MAX_STYLE_NUM );
						MessageForm->ShowMessage( buf, MB_ICONERROR|MB_OK );

						return -1;
					}
					else{
						aIdStyle[nIdCount++] = id;
					}
				}
			}
		}
	}

	int nUserBalance = g_infoUser.accountInfo.balance,
		nCost = 0,
		arrCost[MAX_STYLE_NUM];

	TProgressForm * dlgProgress = new TProgressForm(NULL);
	int ret = dlgProgress->User_CheckPayment( iOperation, nIdCount, aIdStyle, arrCost,
																&nCost, &nUserBalance );
	int eExtra = dlgProgress->GetOpertaionResult();
	delete dlgProgress;

	if( ret==mrOk ){
		g_infoUser.accountInfo.balance = nUserBalance;

		if( eExtra==0 || eExtra==e_VerifyInsufficient ){
			if( nCost==0 ){
				bConfirm = true;
//                ShowMessage("balance=" + IntToStr(nUserBalance) + ", cost=" + IntToStr(nCost) + ", eExtra=" + IntToStr(eExtra));
			}
			else{
				TPayMentForm *payMentForm = new TPayMentForm(NULL, iOperation, nIdCount, aIdStyle,
																   arrCost, nCost, nUserBalance);
				bConfirm = ( mrYes==payMentForm->ShowModal() );
				delete payMentForm;

				if( !bConfirm )
					eExtra = e_UserCanceled;
			}
		}
	}

	if( bConfirm ){
		TProgressForm * dlgProgress = new TProgressForm(NULL);

		int ret = dlgProgress->MM_SaveMedia( iSaveOption, iFileType, strFileName.c_str(),
												iOperation, nIdCount, aIdStyle );
		eExtra = dlgProgress->GetOpertaionResult();
		delete dlgProgress;

		if( ret==mrOk ){
			bool bTip = false;
			for( int i=0; i<nIdCount; i++ ){
				if( arrCost[i]>0 ){
					bTip = true;
					break;
				}
			}

			if( bTip ){
				//保存风格支付记录
				g_bRecProtect = IsProtected();
				f_MM_SetRecordProtect( g_bRecProtect );
				AnsiString strProjectName = g_strAutoProjName.c_str();
				SaveProject( strProjectName.c_str() );
				g_bProjStylePaid = true;
			}

			if( bUpload ){
				m_strUploadFile = strFileName;
				u_pUploadLite = g_Undo.GetLastLite();
			}
			else{
				g_strLastSavePath = ExtractFilePath( strFileName.c_str() ).c_str();
				g_iLastSaveOption = iSaveOption & 0x0F00;

				if( iFileType==FILETYPE_MP3 && ( iSaveOption==(SAVE_COMPOSE|SAVE_AUDIO)
												|| iSaveOption==SAVE_COMPOSE && g_aAudioTracks.size()==1 )){
					m_strUploadFile = strFileName;
					u_pUploadLite = g_Undo.GetLastLite();
				}

				MessageForm->ShowMessage( "媒体文件导出成功。", MB_OK|MB_ICONINFORMATION, "导出" );

				if( bTip ){
					String strMessage = "风格已支付，请及时保存工程。\n\n是否立即保存？";
					if( mrYes==MessageForm->ShowMessage( strMessage, MB_YESNO|MB_ICONQUESTION, "保存" ) ){
						PostMessage( Handle, UM_SAVEPROJECT, SAVE_PROJECT, 0 );
					}
				}
			}
		}
		else if( !bUpload && eExtra!=0 && eExtra!=e_UserCanceled ){
			ShowErrorMessage( eExtra, L" 保存失败!" );
		}
	}
	else if( !bUpload && eExtra!=0 && eExtra!=e_UserCanceled ){
		ShowErrorMessage( eExtra, L"鉴权失败!" );
	}

//	Update();

	return eExtra;
}
//---------------------------------------------------------------------------

// add by lm 14.1.17
void __fastcall TMainForm::UserNameClick(TObject *Sender)
{
	if(m_lblLogon->Tag == 0){
        // 未登录
		PostMessage(Handle, UM_LOGIN, 0, 0);
    }
    else if(m_lblLogon->Tag == 1){
        // 正在登录时，取消登录
		Logout();
    }
	else if(m_lblLogon->Tag == 2){
    	TShowUserInfo *showUI = new TShowUserInfo(NULL);
		TPoint p = ClientToScreen(TPoint(m_lblLogon->BoundsRect.Right - 250,
        	                             m_lblLogon->BoundsRect.Bottom));
		showUI->Top = p.Y - 5;
        showUI->Left = p.X;

        if(int ret = showUI->ShowModal()){
        	if(ret == 1)
            	Logout();
			else{
                int iOp = -1;

            	if(ret == 2)
                    iOp = URL_USERCENTER;
                else if(ret == 3)
                    iOp = URL_VIPMEMBER;
                else if(ret == 4)
                    iOp = URL_RECHARGE;

                if( iOp>=0 ){
                    char strURL[256];
                    f_CS_GetWebPageURL( iOp, strURL );

                    if( strlen(strURL)>0 )
                        ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);
                }
            }
        }

		delete showUI;
    }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Logout()
{
	f_CS_Logoff();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMStartCDTimer(TMessage &Message)
{
	if(m_pCDTimer==NULL){
		m_pCDTimer = new TTimer(this);
		m_pCDTimer->Interval = 1000;
		m_pCDTimer->OnTimer = CDTimerProc;
		m_pCDTimer->Tag = CODE_INTERVAL;
		m_pCDTimer->Enabled = true;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CDTimerProc(TObject* Sender)
{
	if(LoginForm!=NULL){
		LoginForm->OnCDTimer(m_pCDTimer->Tag);
	}

	if( m_pCDTimer->Tag==0 ){
		ClearCDTimer();
	}
	else{
		m_pCDTimer->Tag--;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ClearCDTimer()
{
	if( m_pCDTimer ){
		m_pCDTimer->Enabled = false;
		delete m_pCDTimer;
		m_pCDTimer = NULL;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnLogin(TMessage &msg)
{
	if( g_bUpdateMandatory )
		return;

	bool bSync = msg.WParam;
 	AnsiString strUsernameBk = g_infoUser.strUserName,
			strPasswordBk = g_infoUser.strPassword;

	LoginForm = new TLoginForm(NULL);
	LoginForm->IsAntoLogin = g_bAutoLogin;
	LoginForm->UserName = strUsernameBk;
	LoginForm->PassWord = strPasswordBk;

	bool var_Repeat = false;

    do{
		if(LoginForm->ShowModal() == mrOk){
        	g_bAutoLogin = LoginForm->IsAntoLogin;
			AnsiString aStr = LoginForm->UserName;
			strncpy(g_infoUser.strUserName, aStr.c_str(), aStr.Length() + 1);

			aStr = LoginForm->PassWord;
			strncpy(g_infoUser.strPassword, aStr.c_str(), aStr.Length() + 1);

			if(LoginForm->IsLogin && !bSync){
				m_lblLogon->Caption = L"正在登录...";
				m_lblLogon->Tag = 1;
				m_lblLogon->Hint = L"点击取消登录";
				f_CS_Login(&g_infoUser, false);
			}
			else{
				TProgressForm *dlgProgress = new TProgressForm(NULL);
				int ret = 0;
				if(LoginForm->IsLogin)
					ret = dlgProgress->User_Login();
				else
					ret = dlgProgress->User_Register(LoginForm->isEmailOrMobile);

				int eExtra = dlgProgress->GetOpertaionResult();
				delete dlgProgress;

				var_Repeat = false;
				if( ret==mrOk && eExtra==0 ){
					if( g_infoUser.accountInfo.ID==0 ){
						DebugPrint( "Invalid user ID.\n" );
					}

					g_bLogon = true;

					g_bRecProtect = IsProtected();
					f_MM_SetRecordProtect( g_bRecProtect );

				}
				else if( eExtra!=0 && eExtra!=e_UserCanceled ){
					ShowErrorMessage( eExtra, LoginForm->IsLogin ? "登录失败!" : "注册失败!");

					g_infoUser.strPassword[0] = 0;
					LoginForm->PassWord = "";
					LoginForm->Confirm = "";
					if( eExtra==e_LoginPasswordError
								|| eExtra==e_LoginUserNotExist
								|| eExtra==e_UsernameExist){
						var_Repeat = TRUE;
					}
				}
            }
		}
		else {
			var_Repeat = false;
			// 取消登录
			strncpy(g_infoUser.strUserName, strUsernameBk.c_str(), strUsernameBk.Length() + 1);
			strncpy(g_infoUser.strPassword, strPasswordBk.c_str(), strPasswordBk.Length() + 1);

            if( !LoginForm->IsAntoLogin && g_bAutoLogin ){
                g_bAutoLogin = false;
                SetAutoLogin(false, g_infoUser.strUserName, NULL);
            }
		}
    }while(var_Repeat);

    delete LoginForm;
    LoginForm = NULL;
}
//----------------------------------------------------------------------------

void __fastcall TMainForm::OnKeyBoard(TObject *Sender)
{
//	m_KeyBoard->ShowKeyboard( !m_KeyBoard->Visible );
	Application->MainForm->Perform(	UM_SHOW_KB, NULL, NULL );
}
//----------------------------------------------------------------------------

bool __fastcall TMainForm::CheckPayment( int iOperation )
{
	bool bPaid = false;

	if( !g_bLogon ){
		Perform( UM_LOGIN, true, 0 );
	}

	if( g_bLogon ){
		UINT nIdCount = 0, aIdStyle[MAX_STYLE_NUM];

		for( int i=0; i<g_lstOpusStages.size(); i++ ){
			TOpusStage* pStage = g_lstOpusStages[i];
			for( int j=0; j<pStage->aTracks.size(); j++ ){
				if( pStage->aTracks[j]->iStyleLoc==0 ){
					int id = pStage->aTracks[j]->iStyleId;

					bool bExist = false;
					for( int j=0; j<nIdCount; j++ ){
						if( id==aIdStyle[j] ){
							bExist = true;
							break;
						}
					}
					if( !bExist ){
						if( nIdCount>=MAX_STYLE_NUM ){
							char buf[200];
							sprintf( buf, "歌曲使用的风格数超过%d个只能保存为工程！", MAX_STYLE_NUM );
							MessageForm->ShowMessage( buf, MB_ICONERROR|MB_OK );

							return false;
						}
						else{
							aIdStyle[nIdCount++] = id;
						}
					}
				}
			}
		}

		int nUserBalance = g_infoUser.accountInfo.balance,
			nCost = 0,
			arrCost[MAX_STYLE_NUM];

		TProgressForm * dlgProgress = new TProgressForm(NULL);
		int ret = dlgProgress->User_CheckPayment( iOperation, nIdCount, aIdStyle, arrCost,
																	&nCost, &nUserBalance );

		int eExtra = dlgProgress->GetOpertaionResult();
		delete dlgProgress;

		if( ret==mrOk ){
			g_infoUser.accountInfo.balance = nUserBalance;

			if( eExtra==0 || eExtra==e_VerifyInsufficient){
				bool bConfirm = true;

				if( nCost!=0 ){
					TPayMentForm *payMentForm = new TPayMentForm(NULL, iOperation, nIdCount, aIdStyle,
																	   arrCost, nCost, nUserBalance);
					bConfirm = ( mrYes==payMentForm->ShowModal() );
					delete payMentForm;
				}

				if( bConfirm ){
					TProgressForm * dlgProgress = new TProgressForm(NULL);

					int ret = dlgProgress->User_ConfirmPayment( iOperation, nIdCount,
																aIdStyle, &nUserBalance );
					int eExtra = dlgProgress->GetOpertaionResult();
					delete dlgProgress;

					if( ret==mrOk ){
						if( eExtra==0 ){
							bPaid = true;
							g_infoUser.accountInfo.balance = nUserBalance;

							bool bTip = false;
							for( int i=0; i<nIdCount; i++ ){
								if( arrCost[i]>0 ){
									bTip = true;
									break;
								}
							}

							if( bTip ){
								g_bProjStylePaid = true;
								String msg = "风格支付成功！\n\n为避免重复支付，请记住保存工程。";
								MessageForm->ShowMessage( msg, MB_ICONINFORMATION|MB_OK, "提示" );
							}
						}
						else{
							ShowErrorMessage( eExtra, L"支付失败!" );
						}
					}
				}
			}
			else if( eExtra==e_InvalidStyleID ){ //风格失效，待进一步提示
				ShowErrorMessage( eExtra, L"鉴权失败!" );
			}
			else{
				ShowErrorMessage( eExtra, L"鉴权失败!" );
			}
		}
	}

	Update();

	return bPaid;
}
//----------------------------------------------------------------------------
void __fastcall TMainForm::SetFont( int idFont, bool bExtFont, bool bAddUndo )
{
	int idOld = g_idFont, idNew = idFont;
	bool bOld = g_bExtFont, bNew = bExtFont,
		bSet = false;

	if( bExtFont!=g_bExtFont ){
		char aFiles[17][256];
		int num = 0;
		if( bExtFont ){
			for( int i=0; i<17; i++ ){
				strcpy( aFiles[i], g_lstCZFonts[i]->strFileName );
			}
			num = 17;
		}
		else{
			num = 1;
			strcpy( aFiles[0], g_lstFonts[g_idFont]->strFileName );
		}

		if( f_MM_SetDefaultFont( num, aFiles )==S_OK ){
			g_bExtFont = bExtFont;
			bSet = true;
		}
		else{

        }

		m_btnExtFontOn->Visible = g_bExtFont;
		m_btnExtFontOff->Visible = !g_bExtFont;
		m_cbFontSelect->Enabled = !g_bExtFont;
	}
	else if( idFont!=g_idFont ){
		char strFile[1][256];
		strcpy( strFile[0], g_lstFonts[idFont]->strFileName );

		int ret = f_MM_SetDefaultFont( 1, strFile );
		if( ret>=0 ){
			g_idFont = idFont;
			strcpy( g_strSoundFont, g_lstFonts[idFont]->strFontName );

			TComboBoxItem* pItem = m_cbFontSelect->GetItem( m_cbFontSelect->DefItemIndex );
			if( pItem->Tag != idFont ){
				for( int i=0; i<m_cbFontSelect->ItemsCount; i++ ){
					pItem = m_cbFontSelect->GetItem( i );

					if( pItem->Tag==idFont ){
						m_cbFontSelect->DefItemIndex = i;
						break;
					}
				}
			}

			bSet = true;
		}
		else{
			m_cbFontSelect->OnChange = NULL;
			m_cbFontSelect->DefItemIndex = g_idFont;
			m_cbFontSelect->OnChange = FontSelectChange;
		}
	}

	if( bAddUndo && bSet ){
		TUndoLite* pLite = g_Undo.GetLastLite();

		if( pLite && pLite->iType==UNDO_FONT_SET
						&& ( bOld==bNew && pLite->iBegin==idNew	&& pLite->iEnd==idOld
						|| idOld==idNew && (bool)pLite->pBefore==bNew && (bool)pLite->pAfter==bOld) )
			g_Undo.CancelUndo();
		else
			g_Undo.AddUndo( UNDO_FONT_SET, 0, idOld, idNew, (void*)bOld, (void*)bNew );
	}
}
//----------------------------------------------------------------------------

void __fastcall TMainForm::FontSelectChange(TComboBoxItem *Sender, int Index)
{
	int iFont = Sender->Tag;

	if( iFont!=g_idFont )
		SetFont( iFont, g_bExtFont );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::KeyChange(TComboBoxItem *Sender, int Index)
{
	if( Index<0 || Index==g_iMelodyKey )
		return;

	StopClick( NULL );

	if( g_iPreStage==0 ){
		UINT idLoc, idStyle;
		int	iOrigKey = g_iMelodyKey;
		TOpusStageList* lstStagesBefore = new TOpusStageList;
		g_Theme.Get( idLoc, idStyle, *lstStagesBefore );

		g_iMelodyKey = Index;

		SetMelodyNotes( g_Theme.BarCount() );

		if( AutoChords()==S_OK ){
			TOpusStageList* lstStagesAfter = new TOpusStageList;
			g_Theme.Get( idLoc, idStyle, *lstStagesAfter );

			g_Undo.AddUndo( UNDO_KEY_MELODY, 0, iOrigKey, Index, (void*)lstStagesBefore, (void*)lstStagesAfter );

			((TUseStylePanel*)m_pUseStylePanel)->InitOpus( g_pPreStyle,	g_iPreStage );
		}
		else{
			while( !lstStagesBefore->empty() ){
				delete lstStagesBefore->back();
				lstStagesBefore->pop_back();
			}
			delete lstStagesBefore;
        }
	}
	else{
		m_pContentPanel->OnChangeMelodyKey( Index );
	}

	m_iStartBar = 0;
	m_dblStartPoint = 0;
	m_dwLastVol = 0;
	m_pContentPanel->SetPlayPoint( 0, 0 );
	ShowPlayTime();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OpenClick(TObject *Sender)
{
	PostMessage( Handle, UM_LOADPROJECT, 0, 0 );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SaveClick(TObject *Sender)
{
	PostMessage( Handle, UM_SAVEPROJECT, SAVE_ALL, 0 );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UploadClick(TObject *Sender)
{
//	PostMessage( Handle, UM_UPLOADMUSIC, 0, 0 );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnUploadMusic(TMessage & Msg)
{
	//必须登录后才能进入上传界面
	if( !g_bLogon )
		Perform( UM_LOGIN, true, 0 );

	if( !g_bLogon )
		return;

	Perform( UM_STOP, STOP_CONTENT | STOP_USESTYLE, 0 );
	//先编曲，防止用户修改风格后不播放直接上传
	GenerateCompose();

	if( !m_strUploadFile.IsEmpty() && (!FileExists(m_strUploadFile, false)
										|| g_Undo.GetLastLite()!=u_pUploadLite )){
		m_strUploadFile = "";
		u_pUploadLite = NULL;
	}

	//首先检测上传许可
	TProgressForm *frmProgress = new TProgressForm(NULL);
	int ret = frmProgress->User_UploadSong( NULL, NULL );
	int eExtra = frmProgress->GetOpertaionResult();
	delete frmProgress;

	if( ret==mrCancel ){
		return;
	}
	else if( ret==mrOk && eExtra!=0 ){
		if( eExtra==e_InvalidAuthority ){
			TManageSongForm * frmManage = new TManageSongForm(NULL, false);
			ret = frmManage->ShowModal();
			delete frmManage;
		}
		else{
			ShowErrorMessage( eExtra, "验证失败!" );
		}

		return;
	}

	//先保存后上传

	//填写歌曲信息
	TUploadForm * pUpload = new TUploadForm( NULL );

	wstring strFileName;
	while( pUpload->ShowModal()==mrOk ){ //显示对话框直到上传成功或用户取消
		eExtra = 0;
		strFileName = m_strUploadFile.c_str();

		//如此前未保存，则保存到Upload目录下
		if( strFileName.empty() ){
			strFileName = g_strUserPath;
			strFileName += L"Save\\";

			MkDir( strFileName.c_str() );

			strFileName += pUpload->m_editSongName->Text.c_str();
			strFileName += L".mp3";

			int iOperation = e_PO_Pay4Compose;
			if( g_bExtFont || ((TUseStylePanel*)m_pUseStylePanel)->Charge4Fonts() )
				iOperation |= e_PO_Pay4Fonts;
			if( g_aAudioTracks.size()>2  )
				iOperation |= e_PO_Pay4Audios;

			eExtra = SaveMedia( iOperation, SAVE_ALL, FILETYPE_MP3, strFileName.c_str(), true );
		}

		//得到文件名，开始上传
		if( eExtra==0 ){
			//保存伴奏工程
			if( g_infoSong.strCpjName && strlen( g_infoSong.strCpjName )>0 ){
				SaveProject( g_infoSong.strCpjName, PROJ_MODE_UPLOAD );
			}

			TSHAREINFO infoShare;
			frmProgress = new TProgressForm(NULL);
			ret = frmProgress->User_UploadSong( strFileName.c_str(), &infoShare );
			eExtra = frmProgress->GetOpertaionResult();
			delete frmProgress;

			//删除伴奏工程
			if( g_infoSong.strCpjName && strlen( g_infoSong.strCpjName )>0 && FileExists( g_infoSong.strCpjName ) ){
				DeleteFile( g_infoSong.strCpjName );
			}

			if( ret==mrOk && eExtra==0 ){
				TManageSongForm * frmManage = new TManageSongForm(NULL, true, infoShare.idSong);
				frmManage->ShowModal();
				delete frmManage;

				break;
			}
		}

		//统一处理错误返回值
		if( eExtra!=0 ){
			if( eExtra==e_InvalidAuthority ){
				TManageSongForm * frmManage = new TManageSongForm(NULL, false);
				ret = frmManage->ShowModal();
				delete frmManage;

				if( ret!=mrOk ){
					break;
				}
			}
			else if( eExtra!=-1 && eExtra!=e_UserCanceled ){
				ShowErrorMessage( eExtra, "上传失败!" );
				break;
			}
		}
	}

	delete pUpload;

	Update();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::VolSetClick(TObject *Sender)
{
	if( m_KeyBoard->Visible ){
		m_KeyBoard->ShowKeyboard( false );
		if( m_btnKeyboard->Down )
			m_btnKeyboard->Down = false;
	}

	Perform( UM_SHOW_VOLSET, 1, 0 );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMShowVolSet(TMessage &Message)
{
	int iShow = Message.WParam;

	if( iShow>0 && !m_pVolumeForm ){
		m_pVolumeForm = new TVolumeForm(NULL);

		int x = m_btnVolSet->Left;
		int y = m_btnVolSet->Top - 245;
		TPoint volumePos = ClientToScreen(TPoint(x, y));
		m_pVolumeForm->Top = volumePos.Y;
		m_pVolumeForm->Left = volumePos.X;
		m_btnVolSet->Down = true;

		if( iShow==1 ){
			m_pVolumeForm->OnRecord( m_btnRecord->Down );
			m_pVolumeForm->ShowModal();
		}
		else{
			bool bUndo = Message.LParam;
			m_pVolumeForm->ShowUndo( bUndo );
		}
	}
	else if( iShow==0 && m_pVolumeForm ){
		delete m_pVolumeForm;
		m_pVolumeForm = NULL;
		m_btnVolSet->Down = false;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMAudioVolChanged(TMessage &Message)
{
	int iTrack = Message.WParam,
		iState = Message.LParamLo;
	bool bUnset = Message.LParamHi;

	if( iState>0 && !m_pContentPanel->IsVertical() )
		m_pContentPanel->OnTrackStateChanged( ST_AUDIO, iTrack, iState, bUnset );

	if( g_iSelAudio==iTrack )
		((TTrackPanel*)m_pTrackPanel)->RefreshTrackState( iState, bUnset );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMShowKeyBoard(TMessage &Message)
{
	if( m_KeyBoard->Visible ){
		m_KeyBoard->ShowKeyboard( false );
		if( m_btnKeyboard->Down )
			m_btnKeyboard->Down = false;
	}
	else{
		m_KeyBoard->ShowKeyboard( true );
		if( !m_btnKeyboard->Down )
			m_btnKeyboard->Down = true;
	}
}
//---------------------------------------------------------------------------

bool __fastcall TMainForm::RecordEnabled()
{
	bool bRec = true;

	if( g_iViewMode!=VIEW_INIT ){
		bRec = false;

		if( g_Opus.BarCount()>0 ){
			for( int i=0; i<g_aAudioTracks.size(); i++ ){
				if( !g_aAudioTracks[i]->IsHide() && !g_aAudioTracks[i]->lstBars.empty() ){
					bRec = true;
					break;
				}
			}
		}
	}

	return bRec;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SetRecordState( bool bRecord )
{
	bool bEnable = !bRecord;

	m_btnTS->Enabled = bEnable;
	m_btnTempo->Enabled = bEnable;
	m_cbPreStage->Enabled = bEnable;

	m_btnOpen->Enabled = bEnable;
	m_btnSave->Enabled = bEnable;
	m_btnUpload->Enabled = bEnable && !g_bUpdateMandatory;

	m_tabStyle->Enabled = bEnable;
	m_tabChord->Enabled = bEnable;
	m_tabAudio->Enabled = bEnable;

	m_pContentPanel->Enabled = bEnable;
	m_pUseStylePanel->Enabled = bEnable;
	m_pAudStylePanel->Enabled = bEnable;
	m_pPreStylePanel->Enabled = bEnable;
	m_pTrackPanel->Enabled = bEnable;
	m_pChordPanel->Enabled = bEnable;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShowToolPanels( int iShow )
{
	if( g_iToolPanelShow==iShow )
		return;

	g_iToolPanelShow = iShow;

	bool bShow = !( iShow & 0x2 );

	if( bShow ){
		if( g_iToolPanelShow & 0x01 ){
			m_tabStyle->PngImg->LoadFromResourceName( int(HInstance), "btnViewStyleLeft" );
			m_tabChord->PngImg->LoadFromResourceName( int(HInstance), "btnViewChordLeft" );
			m_tabAudio->PngImg->LoadFromResourceName( int(HInstance), "btnViewTrackLeft" );
		}
		else{
			m_tabStyle->PngImg->LoadFromResourceName( int(HInstance), "btnViewStyleRight" );
			m_tabChord->PngImg->LoadFromResourceName( int(HInstance), "btnViewChordRight" );
			m_tabAudio->PngImg->LoadFromResourceName( int(HInstance), "btnViewTrackRight" );
		}
	}

	m_tabStyle->Visible = bShow;
	m_tabChord->Visible = bShow;
	m_tabAudio->Visible = bShow;

	if(g_iViewMode == VIEW_TRACK)
		m_pTrackPanel->Visible = bShow;
	else if(g_iViewMode == VIEW_CHORD)
		m_pChordPanel->Visible = bShow;
	else{
		m_pUseStylePanel->Visible = bShow;
		m_pAudStylePanel->Visible = bShow;
		m_pPreStylePanel->Visible = bShow;
	}

	ViewLayout();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnShowToolPanels(TObject *Sender)
{
	int index = (int)Sender;

	if( index<0 )
		ShowToolPanels( g_iToolPanelShow ^ 0x2 );
	else if( g_iToolPanelShow==0 )
		ShowToolPanels( 1 );
	else
        ShowToolPanels( 0 );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::PlayTimeClick(TObject *Sender)
{
	g_bShowPlayTick = !g_bShowPlayTick;

	ShowPlayTime();

	if( g_bShowPlayTick ){
		m_pPlayTimePanel->Hint = "当前位置(节拍)";
	}
	else{
		m_pPlayTimePanel->Hint = "当前位置(时间)";
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnOpenAutoProj(TMessage & Msg) //add by tj 2013/12/31
{
	GetAutoSaveReg();
	SetAutoSaveReg( false );

	if( !FileExists( g_strAutoProjName.c_str() ) )
		return;

	if( g_aOriginStyles.empty() ) //还未加载风格
		return;

	String strMsg = L"将恢复上次未保存的工程。\n是否恢复工程?";
	MessageForm->m_btnYes->Hint = L"恢复工程";
	MessageForm->m_btnNo->Hint = L"放弃恢复工程";

	int mrRet = MessageForm->ShowMessage( strMsg, MB_ICONQUESTION|MB_YESNO );

	MessageForm->m_btnYes->Hint = "";
	MessageForm->m_btnNo->Hint = "";

	if( mrRet==mrYes ) {
		//MessageForm->ShowMessage( strProjectName.c_str(), MB_ICONINFORMATION|MB_OK );
		mrRet = LoadProject(((AnsiString)g_strAutoProjName.c_str()).c_str(), NULL);

		if (mrRet) {
			DebugPrint("open auto Save project....");
			AfterLoadProject();

			return;
		}
		else {
			DebugPrint("open auto Save project invalidate....");
			String strErr = L"恢复工程失败";
			MessageForm->ShowMessage(strErr, MB_ICONERROR | MB_OK);

			NewProject();
		}

		Update();
	}
	else{
		g_strProjectName.clear();
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMShowHelp(TMessage &Message)
{
	bool bShow = Message.WParamHi;

	if( !bShow && m_HelpForm ){
		delete m_HelpForm;
		m_HelpForm = NULL;
	}
	else if( bShow && !m_HelpForm ){
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::DoShowNoticeNumPaint(TObject *Sender)
{
	TPngImage* img = new TPngImage();
	img->LoadFromResourceName( int(HInstance), L"NoticeBk" );
	m_pbUserNoticeNum->Canvas->Draw(0, 0, img);
	SetBkMode(m_pbUserNoticeNum->Canvas->Handle, TRANSPARENT);

	String num;
	num.sprintf(L"%d", m_pbUserNoticeNum->Tag);

	TSize size = m_pbUserNoticeNum->Canvas->TextExtent(num);
	m_pbUserNoticeNum->Canvas->TextOutW((21 - size.Width) / 2, (21 - size.Height) / 2, num);

	delete img;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UserNoticeNumClick(TObject *Sender)
{
	char strURL[256];
	f_CS_GetWebPageURL( URL_USERNOTICE, strURL );
	ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);

//    int num = 0;
//    f_CS_GetNotice( num, NULL, 0 );
//    f_CS_GetNotice( num, NULL, g_infoUser.accountInfo.ID );

//	if(g_bLogon) {
		// 登录
//		if(!m_HelpForm) {
//			m_HelpForm = new THelpForm(NULL);
//		}

//		int zoneNum = f_CS_GetNewNoticeNum( g_infoUser.accountInfo.ID );
//		int noticeNum = f_CS_GetNewNoticeNum( 0 );

//		m_HelpForm->SetNoticeNum(noticeNum, 0);
//		m_HelpForm->SetNoticeNum(zoneNum, 1);

//		if(noticeNum == 0)
//			m_HelpForm->SetPage(3);
//		else
//			m_HelpForm->SetPage(TAB_NT);
//	}
/*	else {
		// 未登录
		if(!m_HelpForm) {
			m_HelpForm = new THelpForm(NULL);
		}

		int noticeNum = f_CS_GetNewNoticeNum( 0 );
		m_HelpForm->SetNoticeNum(noticeNum, 0);
		m_HelpForm->SetPage(2);
	}
*/

//	if( m_HelpForm && m_HelpForm->Window_state==HLP_WINDOW_MIN ){
//		m_HelpForm->SetSize( HLP_WINDOW_NORMAL );
//	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMStyleScore(TMessage &Message)
{
	if( !g_bLogon ){
		Perform( UM_LOGIN, true, 0 );
	}

	if( g_bLogon ){
		//获取用户以前评分及当前平均分
		TPROSTYLE* pStyle = (TPROSTYLE*)Message.LParam;
		int iType = pStyle->idLoc==0 ? e_ST_Origin : e_ST_Share,
			scrUser = -1,
			scrAverage = iType==e_ST_Origin ? pStyle->pOrigin->score : pStyle->pShare->score;

		TProgressForm *frmProgress = new TProgressForm(NULL);
		int ret = frmProgress->User_StyleScore( pStyle->idStyle, iType, &scrUser, &scrAverage );
		int eExtra = frmProgress->GetOpertaionResult();
		delete frmProgress;

		int oldMyScore = scrUser;
		if( ret==mrOk ){
			if( eExtra!=0){
				ShowErrorMessage( eExtra, L"获取评分失败!" );
				return;
			}
			else{
				if( iType==e_ST_Origin )
					pStyle->pOrigin->score = scrAverage;
				else
					pStyle->pShare->score = scrAverage;
            }

			//显示评分面板
			int iTop = Message.WParamLo,
				iRight = Message.WParamHi;

			TScoreForm *pScoreForm = new TScoreForm(NULL);              //评分面板
			pScoreForm->Top = Top + iTop;
			pScoreForm->Left = Left + iRight - pScoreForm->Width;

			if( iTop + pScoreForm->Height > ClientHeight - 42 ){
				pScoreForm->SetScoreWindow(false);
				pScoreForm->Top -= pScoreForm->Height + OPTION_HEIGHT + 2;
			}
			else{
				pScoreForm->SetScoreWindow(true);
			}

			string strStyleName;
			if( iType==e_ST_Origin )
				strStyleName = UTF8ToMBCS(pStyle->pOrigin->detail.strStyleName);
			else
				strStyleName = UTF8ToMBCS(pStyle->pShare->strStyleName);

			pScoreForm->SetNetScore( scrAverage, strStyleName.c_str());
			pScoreForm->SetMyScore( scrUser );

			bool bSumit = ( pScoreForm->ShowModal()==mrOk );
			scrUser = pScoreForm->MyScore;
			delete pScoreForm;

			if( bSumit ){
				if( scrUser==oldMyScore ){ //如果评分与之前评分相同返回
					MessageForm->ShowMessage( "成功修改评分。", MB_OK|MB_ICONINFORMATION );
					return;
				}

				//显示评分进度条
				TProgressForm *frmProgress = new TProgressForm(NULL);
				int ret = frmProgress->User_StyleScore( pStyle->idStyle, iType, &scrUser, &scrAverage );
				int eExtra = frmProgress->GetOpertaionResult();
				delete frmProgress;

				if( ret==mrOk ){
					if( eExtra==0){
						if( iType==e_ST_Origin )
							pStyle->pOrigin->score = scrAverage;
						else
							pStyle->pShare->score = scrAverage;

						if( oldMyScore==-1 )
							MessageForm->ShowMessage( "成功提交评分。", MB_OK|MB_ICONINFORMATION );
						else
							MessageForm->ShowMessage( "成功修改评分。", MB_OK|MB_ICONINFORMATION );
					}
					else{
						ShowErrorMessage( eExtra, L"提交评分失败!" );
						return;
					}
				}
			}
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMNotification(TMessage & Msg)
{
	if( !m_pNotificationGetTimer )
		return;

	static bool bAutoShowHappened = false;
	static bool bMenuShowHappened = false;
	if( Msg.WParam == NOTIFICATION_SHOW_CLOSED ){

		bAutoShowHappened = true;
		m_pNotificationGetTimer->Enabled = false;

		if( m_pNotificationForm ) {

			delete m_pNotificationForm;
			m_pNotificationForm = NULL;
		}

	}else if( Msg.WParam == NOTIFICATION_NO_JSONDATA ){

		if( m_pNotificationForm ) {

			delete m_pNotificationForm;
			m_pNotificationForm = NULL;
		}

		if( !bAutoShowHappened ) {
			m_pNotificationGetTimer->Enabled = true;
		}

		if( bMenuShowHappened ) {
			bMenuShowHappened = false;
			MessageForm->ShowMessage("暂不能获取唱作网动态，请稍后再试！", MB_ICONERROR | MB_OK);
		}

	}else if( Msg.WParam == NOTIFICATION_MENU_JSONDATA ){
		m_pNotificationGetTimer->Enabled = false;
		if( m_pNotificationForm== NULL) {
			NotificationTimerProc(m_pNotificationGetTimer);
			bMenuShowHappened = true;
		}
	}else if( Msg.WParam == NOTIFICATION_SHOW_FORM ){
		if( m_pNotificationForm ){
			m_pNotificationForm->setPANEL();
			m_pNotificationForm->Show();
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::NotificationTimerProc(TObject* Sender)
{
	TTimer *notiTimer = (TTimer *)Sender;

	if( notiTimer == m_pNotificationGetTimer ) {

		m_pNotificationGetTimer->Enabled = false;
		if( m_pNotificationForm == NULL ) {
			m_pNotificationForm = new TNotificationForm(NULL);
			//m_pNotificationForm->ParentWindow = GetDesktopWindow();
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnNotification(TObject *Sender)
{
	PostMessage(Handle, UM_NOTIFICATION,
				NOTIFICATION_MENU_JSONDATA, 0 );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnCustomerSetting(TObject *Sender)
{
	TCustomerSettingForm *csForm = new TCustomerSettingForm(NULL);
	int ret = csForm->ShowModal();
	if( mrYes==ret ){
		g_bAutoOpenProject = csForm->m_pCSPanel->m_bAutoOpenProject;
		g_iPreStageDefault = csForm->m_pCSPanel->m_cPreStage;
		g_bPrebeat = csForm->m_pCSPanel->m_bPreBeat;

		bool bAutoDownload = csForm->m_pCSPanel->m_bDownloadStyle;
		if( bAutoDownload!=g_bAutoDownloadStyle ){
			g_bAutoDownloadStyle = bAutoDownload;
			f_CS_AutoDownloadStyle(	bAutoDownload );
		}
	}
	else{
		bool bAlphaKey = csForm->m_bAlphaKeyOrig;
		if( g_bAlphaKey!=bAlphaKey )
			((TChordPanel*)m_pChordPanel)->SetKeyMode( bAlphaKey );

		int iColorMode = csForm->m_iSegColorOrig;
		if( iColorMode!=g_iSegColorMode ){
			g_iSegColorMode = iColorMode;

			InitSegmentColor();
			m_pContentPanel->Invalidate();
			m_pUseStylePanel->Invalidate();
			m_pPreStylePanel->Invalidate();
			m_pAudStylePanel->Invalidate();
		}
	}

	delete csForm;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMPreferChanged(TMessage &Message)
{
	int iParam = Message.WParam;

	if( iParam==0 ){ //段落颜色模式
		int iColorMode = Message.LParam;
		if( iColorMode!=g_iSegColorMode ){
			g_iSegColorMode = iColorMode;

			InitSegmentColor();
			m_pContentPanel->Invalidate();
			m_pUseStylePanel->Invalidate();
			m_pPreStylePanel->Invalidate();
			m_pAudStylePanel->Invalidate();
		}
	}
	else if( iParam==1 ){ //和弦显示模式
		bool bAlphaKey = Message.LParam;
		if( g_bAlphaKey!=bAlphaKey )
			((TChordPanel*)m_pChordPanel)->SetKeyMode( bAlphaKey );
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMApplyStyle(TMessage &Message)
{
	TStyleItem* pStyItem = (TStyleItem*)Message.LParam;
	if( Message.WParam==0 ){ //替换预设风格
		((TStylePanel*)m_pPreStylePanel)->Stop();
		((TPreStylePanel*)m_pPreStylePanel)->SetPreStyle( pStyItem->pStyle->idLoc,
															pStyItem->pStyle->idStyle );
	}
	else if( Message.WParam==1 ){ //替换使用风格
		if( ( g_pUseStyle->nSegNum[SEGTYPE_VAR]>0 || g_pUseStyle->nSegNum[SEGTYPE_FILL]>0 )
					&& pStyItem->nSegNum[SEGTYPE_VAR]==0 && pStyItem->nSegNum[SEGTYPE_FILL]==0 ){
			MessageForm->ShowMessage( "所选风格缺少伴奏或加花片段！", MB_ICONERROR|MB_OK );
		}
		else{
			((TStylePanel*)m_pUseStylePanel)->Stop();
			((TUseStylePanel*)m_pUseStylePanel)->ApplyStyle( pStyItem );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMChangeMelodyKey(TMessage &Message)
{
	if( m_cbKey->DefItemIndex != g_iMelodyKey ){
		m_cbKey->DefItemIndex = g_iMelodyKey;
		m_cbKey->Enabled = g_iMelodyKey>=0;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMSaveLocalStyle(TMessage &Message)
{
	if( !g_pPreStyle || g_pPreStyle->aItems->Count==0 )
		return;

	TSaveLocalStyleForm * frmSave = new TSaveLocalStyleForm( NULL, g_pPreStyle );

	while( frmSave->ShowModal()==mrOk ){
		String editText = frmSave->m_editName->Text.Trim();
		string strName = GBToUTF8(AnsiString(editText.c_str()).c_str()).c_str();
		TPROSTYLE * pStyle = NULL;
		bool bNewStyle = true;

		for( int i=0; i<g_aLocalStyles.size(); i++ ){
			if( strName.compare( g_aLocalStyles[i]->pLocal->strStyleName )==0 ){
				pStyle = g_aLocalStyles[i];
				break;
			}
		}

		if( pStyle ){
			String strMsg = "本地风格[" + editText + "]已存在，";

			if( pStyle!=g_pPreStyle->pStyle ){
				bool bUsed = false;

				if( g_pUseStyle ){
					TStyleItem* pStyItem = (TStyleItem*)g_pUseStyle;
					if( pStyItem->pStyle==pStyle )
						bUsed = true;

					for( int i=0; !bUsed && i<pStyItem->aItems->Count; i++ ){
						TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
						for( int j=0; !bUsed && j<pSeg->aItems->Count; j++ ){
							TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
							if( pTrk->pStyle==pStyle ){
								bUsed = true;
							}
						}
					}
				}

				if( !bUsed && g_pPreStyle ){
					TStyleItem* pStyItem = (TStyleItem*)g_pPreStyle;
					if( pStyItem->pStyle==pStyle )
						bUsed = true;

					for( int i=0; !bUsed && i<pStyItem->aItems->Count; i++ ){
						TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
						for( int j=0; !bUsed && j<pSeg->aItems->Count; j++ ){
							TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
							if( pTrk->pStyle==pStyle ){
								bUsed = true;
							}
						}
					}
				}

				if( bUsed ){
					strMsg += "\n且正在使用或编辑中，不可覆盖！";
					MessageForm->ShowMessage( strMsg, MB_ICONERROR | MB_OK, "保存风格" );

					continue;
				}
			}

			strMsg += "是否覆盖？";
			if( mrNo==MessageForm->ShowMessage( strMsg, MB_ICONQUESTION | MB_YESNO, "保存风格" ) ){
				continue;
			}

			if( pStyle!=g_pPreStyle->pStyle ){
				UINT idStyle = pStyle->idStyle;
				f_CM_DeleteLocalStyle( pStyle->idLoc, idStyle );
				DeleteStyleInfo( pStyle->idLoc, idStyle );

				pStyle = new TPROSTYLE;
				pStyle->idLoc = -1;
				pStyle->idStyle = idStyle;
				pStyle->pLocal = new TSTYLELOCAL;
				pStyle->pLocal->iTimesignature = g_iMelodyTimeSignature;
				strcpy( pStyle->pLocal->strStyleName, strName.c_str() );
			}
			else{
				bNewStyle = false;
				memset( pStyle->pLocal->nSegNum, 0, 4 );
				memset( pStyle->pLocal->aIEBars, 0, 2*8 );
				memset( pStyle->pLocal->trkRef, 0, sizeof(TTRACKREF)*4*8*16 );
            }
		}
		else{
			pStyle = new TPROSTYLE;
			pStyle->idLoc = -1;
			pStyle->pLocal = new TSTYLELOCAL;
			pStyle->pLocal->iTimesignature = g_iMelodyTimeSignature;
			strcpy( pStyle->pLocal->strStyleName, strName.c_str() );

		}

		Perform( UM_STOP, STOP_CONTENT|STOP_USESTYLE|STOP_PRESTYLE, 0 );

		pStyle->pLocal->iTempo = g_nMelodyTempo;

		//保存本地风格
		frmSave->Save( pStyle );


		if( bNewStyle ){
			//添加新风格到本地列表
			int index = 0;
			for( int i=g_aLocalStyles.size()-1; i>=0; i-- ){
				if( LOWORD(pStyle->idStyle) > LOWORD(g_aLocalStyles[i]->idStyle) ){
					index = i+1;
					break;
				}
			}

			if( index>=g_aLocalStyles.size() )
				g_aLocalStyles.push_back( pStyle );
			else
				g_aLocalStyles.insert( g_aLocalStyles.begin() + index, pStyle );
		}

		((TAudStylePanel*)m_pAudStylePanel)->ReloadLocalStyle();

		//刷新预设风格
		m_pPreStylePanel->Invalidate();
		m_pUseStylePanel->Invalidate();

		break;
	}

	delete frmSave;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMImportSegment(TMessage &Message)
{
	bool bAuthor = false;

	if( SOFTWARE_ID!=e_Pro_Lite ){
		if( !g_bLogon ){
			Perform( UM_LOGIN, true, 0 );
		}

		if( g_bLogon && g_infoUser.accountInfo.authority & 0x1000 ){
			bAuthor = true;
		}
	}
	else{
		bAuthor = true;
    }

	if( bAuthor ){
		TImportSegmentForm * frmIS = new TImportSegmentForm( NULL, (TPreStylePanel*)m_pPreStylePanel );//, pStyItem, Message.WParam );
		frmIS->ShowModal();
		delete frmIS;
	}
	else{
		String txt = "该功能仅向风格制作人开放\n\n请立即更新软件并申请制作人资格";
		MessageForm->ShowMessage(txt, MB_ICONINFORMATION | MB_OK);
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMUploadStyle(TMessage &Message)
{
	if( !g_bLogon ){
		Perform( UM_LOGIN, true, 0 );
	}

	if( g_bLogon ){
		TStyleItem* pStyItem = (TStyleItem*)Message.LParam;
		TSTYLELOCAL* pLocal = pStyItem->pStyle->pLocal;
		UINT idLoc = pStyItem->pStyle->idLoc,
			idStyle = pStyItem->pStyle->idStyle;

		//检验风格规范
		DWORD dwError = 0;
		if( pLocal->nSegNum[0]<4 )
			dwError |= 1;
		if( pLocal->nSegNum[1]<2 )
			dwError |= 2;
		if( ( pLocal->nSegNum[2] & 0x0F )<2 )
			dwError |= 4;
		if( ( pLocal->nSegNum[2] & 0xF0 )<0x20 )
			dwError |= 8;
		if( ( pLocal->nSegNum[3] & 0x0F )<2 )
			dwError |= 0x10;
		if( ( pLocal->nSegNum[3] & 0xF0 )<0x20 )
			dwError |= 0x20;

		bool bShare = true, bPublish = true;
		for( int i=0; i<4; i++ ){
			for( int j=0; j<8; j++ ){
				for( int k=0; k<16; k++ ){
					if( pLocal->trkRef[i][j][k].idLoc==0
									&& pLocal->trkRef[i][j][k].idStyle==0 )
						break;

					if( pLocal->trkRef[i][j][k].idLoc==0 ){
						bPublish = false;

						if( !bShare ){
							dwError |= 0x80;
							goto END_STATEMENT;
						}
					}
					else{
						bShare = false;

						if( !bPublish ){
							dwError |= 0x40;
							goto END_STATEMENT;
						}
					}
				}
			}
		}

END_STATEMENT:
		if( dwError!=0 ){
			TStyleSpecsForm * frm = new TStyleSpecsForm( NULL, dwError );
			frm->ShowModal();
			delete frm;
		}
		else{
			TSTYLESHARE* pShare = NULL;
			TMAKESTYLEINFO* pMake = NULL;

			TStyleUploadForm * frm = new TStyleUploadForm(NULL, pStyItem->pStyle, bShare);
			if( frm->ShowModal()==mrOk ){
				if( bShare ){
					pShare = new TSTYLESHARE;

					frm->GetShareInfo( pShare );

					pShare->idAuthor = g_infoUser.accountInfo.ID;
					pShare->iTempo = pLocal->iTempo;
					pShare->iTimesignature = pLocal->iTimesignature;
					memcpy( pShare->nSegNum, pLocal->nSegNum, 4 );
					memcpy( pShare->aIEBars, pLocal->aIEBars, 2*8 );
					memcpy( pShare->nSegVol, pLocal->nSegVol, 4*8 );

					for( int s=0; s<4; s++ ){
						for( int i=0; i<8; i++ ){
							for( int j=0; j<16 && pLocal->trkRef[s][i][j].idStyle>0; j++ ){
								pShare->trkRef[s][i][j].idStyle = pLocal->trkRef[s][i][j].idStyle;
								pShare->trkRef[s][i][j].segNo = pLocal->trkRef[s][i][j].segNo;
								pShare->trkRef[s][i][j].chan = pLocal->trkRef[s][i][j].chan;
								pShare->trkRef[s][i][j].prog = pLocal->trkRef[s][i][j].prog;
								pShare->trkRef[s][i][j].vol = pLocal->trkRef[s][i][j].vol;
							}
						}
					}
				}
				else{
					pMake = new TMAKESTYLEINFO;

					frm->GetMakeInfo( pMake );

					pMake->detail.idAuthor = g_infoUser.accountInfo.ID;
					pMake->detail.iTempo = pLocal->iTempo;
					pMake->detail.iTimesignature = pLocal->iTimesignature;
				}
			}

			delete frm;

			if( pShare || pMake ){
				int ret = 0;

				TProgressForm * frmProgress = new TProgressForm(NULL);
				if( bShare ){
					ret = frmProgress->User_StyleUpload( e_ST_Share, sizeof(TSTYLESHARE), (char*)pShare );
				}
				else{
					int len = 1000000;
					BYTE* buff = new BYTE[len];
					ret = f_CM_MakeStyle( idLoc, idStyle, pMake, len, buff);

					ret = frmProgress->User_StyleUpload( e_ST_Temp, len, (char*)buff );

					delete buff;
				}

				int eExtra = frmProgress->GetOpertaionResult();
				delete frmProgress;

				if( pShare )
					delete pShare;
				if( pMake )
					delete pMake;

				if( ret==mrOk ){
					if( eExtra==0 ){
						String strMsg = bShare ? "风格分享成功!" : "风格提交成功!";
						MessageForm->ShowMessage( strMsg, MB_ICONINFORMATION | MB_OK);
					}
					else{
						String strMsg = bShare ? "风格分享失败!" : "风格提交失败!";
						ShowErrorMessage( eExtra, strMsg );
					}
				}
			}
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMShowMore(TMessage &Message)
{
    OnShowMore();
}

void __fastcall TMainForm::UMEnableRecord(TMessage &Message)
{
	m_btnRecord->Enabled = RecordEnabled();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMAudioLoad(TMessage &Message)
{
	// 指定文件名
	String strFileName;
	TImportForm *imF = new TImportForm(NULL, g_strLastImportFile.c_str());

	if( imF->ShowModal()==mrOk ){
		strFileName = imF->MediaFilePath;
	}
	delete imF;

	if( strFileName.Length()==0 )
		return;

	int iSelAudioBar = Message.WParam,
		iSelAudioPoint = Message.LParam;

	if( iSelAudioBar<0 ){
		iSelAudioBar = 0;
		iSelAudioPoint = 0;
	}

	if( iSelAudioPoint<0 )
		iSelAudioPoint = 0;

	double dblStart = iSelAudioBar + (double)iSelAudioPoint / POINTS_PER_BAR,
		dblEnd = 0;

	int iModifyBeginBar, iModifyBeginPoint, iModifyEndBar, iModifyEndPoint;
	m_pContentPanel->GetSelectRange(iModifyBeginBar, iModifyBeginPoint,
										iModifyEndBar,	iModifyEndPoint);

	DWORD *aBefore = NULL, *aAfter = NULL;

	if( g_iSelAudio>0 ){
		if( iModifyEndBar<0 ){
			iModifyEndBar = g_Opus.BarCount();
			iModifyEndPoint = 0;
		}

		CopyWave( g_iSelAudio, iSelAudioBar, iSelAudioPoint,
										iModifyEndBar, iModifyEndPoint, &aBefore );
	}
	else{
		TAudioTrack* pAudio = CopyAudioTrack( 0, 0, GetBarCount() );
		g_Undo.AddUndo( UNDO_AUDIO_LOAD, 0, g_iMelodyKey, -1, (void*)pAudio, NULL );
    }

	f_MM_AddUndoBefore( 1, &g_iSelAudio );

	if( iModifyEndBar>=0 )
		dblEnd = iModifyEndBar + (double)iModifyEndPoint / POINTS_PER_BAR;

	double dblLen = f_MM_AudioLoad( g_iSelAudio, dblStart, dblEnd, ((AnsiString)strFileName).c_str() );

	if( dblLen<=0 ){
		if( aBefore )
			delete[] aBefore;

		if( g_iSelAudio==0 ){
			g_Undo.CancelUndo();
		}

		f_MM_CancelAddUndo();

		return;
	}

	int iVolBar = iSelAudioBar,
		iVolPoint = iSelAudioPoint,
		nPoints = dblLen * POINTS_PER_BAR,
		iPoint = 0;

	if( g_iSelAudio>0 ){
		int lenOrig = ( iModifyEndBar * POINTS_PER_BAR + iModifyEndPoint )
							- ( iSelAudioBar * POINTS_PER_BAR + iSelAudioPoint );

		if( lenOrig > nPoints ){
			DWORD* aNew = new DWORD[nPoints];
			memcpy( aNew, aBefore, sizeof(DWORD)*nPoints );
			delete[] aBefore;
			aBefore = aNew ;
		}

		aAfter = new DWORD[nPoints];
	}

	dblEnd = dblStart + dblLen;
	if( dblEnd > g_aAudioTracks[g_iSelAudio]->lstBars.size() ){
		int nAddBar = (int)( dblEnd - g_aAudioTracks[g_iSelAudio]->lstBars.size() ) + 1;
		for( int i=0; i<nAddBar; i++ ){
			TWaveBar* pNewBar = new TWaveBar;
            g_aAudioTracks[g_iSelAudio]->lstBars.push_back( pNewBar );
		}
	}

	while( iPoint<nPoints ){
		int iSP = 0, iEP = POINTS_PER_BAR;

		if( iVolPoint>0 ){
			iSP = iVolPoint;

			if( iSP + nPoints - iPoint < POINTS_PER_BAR )
				iEP = iSP + nPoints - iPoint;
		}
		else if( nPoints-iPoint < POINTS_PER_BAR ){
			iEP = nPoints - iPoint;
		}

		if( iEP > iSP ){
			TWaveBar* pBar = g_aAudioTracks[g_iSelAudio]->lstBars[iVolBar];

			for( int i=iSP; i<iEP; i++ ){
				pBar->aVols[i] = f_MM_GetAudioVolume( g_iSelAudio, iVolBar + i/(double)POINTS_PER_BAR );
			}

			if( aAfter ){
				memcpy( aAfter + iPoint, pBar->aVols + iSP, sizeof(DWORD)*(iEP-iSP) );
			}

			iVolPoint = 0;
			iVolBar++;
			iPoint += iEP - iSP;
		}
		else{
			break;
		}
	}

	if( g_iSelAudio>0 ){
		int ind = m_pContentPanel->GetShowTrackId( ST_AUDIO, g_iSelAudio );
		m_pContentPanel->InvalidateBars( iSelAudioBar, (int)(dblEnd)+1, BAR_TRACK | ind );

		int nPointsEnd = ( iSelAudioBar * POINTS_PER_BAR + iSelAudioPoint ) + nPoints,
			iBarEnd = nPointsEnd / POINTS_PER_BAR,
			iPointEnd = nPointsEnd % POINTS_PER_BAR,
			iBegin = MAKELONG( iSelAudioPoint, iSelAudioBar ),
			iEnd = MAKELONG( iPointEnd, iBarEnd );

		g_Undo.AddUndo( UNDO_AUDIO_LOAD, g_iSelAudio, iBegin, iEnd, (void*)aBefore, (void*)aAfter );
		f_MM_AddUndoAfter( 1, &g_iSelAudio );

		m_pContentPanel->SetSelectRange( iSelAudioBar, iSelAudioPoint, iBarEnd, iPointEnd );
	}
	else{
		AutoRecognition( MODE_RELOAD );
	}

	g_strLastImportFile = strFileName.c_str();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnUndo(TObject *Sender)
{
	Undo( true );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::OnRedo(TObject *Sender)
{
	Undo( false );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Undo( bool bUndo )
{
	if( w_bDraging )
		return;

	int iOp = bUndo ? g_Undo.GetUndoType() : g_Undo.GetRedoType();

	if( iOp<0 )
		return;

	if( iOp>=UNDO_KEY_MELODY && iOp<=UNDO_CHORD
			|| iOp>=UNDO_TRKAUD_ADD && iOp<=UNDO_TRKAUD_HIDEALL
			|| iOp>=UNDO_TRKMID_SHOW && iOp<=UNDO_TRKMID_HIDEALL ) {
		 m_pContentPanel->Undo( bUndo );
	}
	else if( iOp>=UNDO_BAR_INSERT && iOp<=UNDO_PROG_VOL
			|| iOp>=UNDO_TRKMID_ADD && iOp<=UNDO_TRKMID_DELALL ){
		((TUseStylePanel*)m_pUseStylePanel)->Undo( bUndo );
	}
	else if( iOp>=UNDO_FX_ADD && iOp<=UNDO_TRACK_CHNO ){
		((TTrackPanel*)m_pTrackPanel)->Undo( bUndo );
	}
	else if( iOp>=UNDO_AUDIO_ERASE && iOp<=UNDO_AUDIO_FX ){
		int iTrack = bUndo ? g_Undo.GetUndoCode() : g_Undo.GetRedoCode();
		if( iTrack>0 )
			m_pContentPanel->Undo( bUndo );
		else{
			TUndoLite * pLite = bUndo ? g_Undo.Undo() : g_Undo.Redo();
			TAudioTrack* pAudio = (TAudioTrack*)( bUndo ? pLite->pBefore
														: pLite->pAfter );
			TOpusStageList* lstStages = (TOpusStageList*)( bUndo ? pLite->pExt1
														: pLite->pExt2 );
			g_iMelodyKey = bUndo ? pLite->iBegin : pLite->iEnd;

			TAudioTrack* pAT = g_aAudioTracks[0];
			RemoveWaveBars( 0, 0, pAT->lstBars.size() );

			if( pAudio ){
				for( int i=0; i<pAudio->lstBars.size(); i++ ){
					TWaveBar* pWvBar = new TWaveBar;
					memcpy( pWvBar->aVols, pAudio->lstBars[i], sizeof(DWORD)*POINTS_PER_BAR );
					pAT->lstBars.push_back( pWvBar );
				}
			}

			g_Theme.Set( pLite->iExt1, pLite->iExt2, *lstStages );
			g_Opus.Set( pLite->iExt1, pLite->iExt2, *lstStages );
			g_Opus.BuildStyleItem();
			g_Midi.ClearMidiTracks();

			f_MM_Undo( bUndo );

			((TStylePanel*)m_pUseStylePanel)->SetStyleItem( g_pUseStyle );

			m_iStartBar = 0;
			m_dblStartPoint = 0;
			m_dwLastVol = 0;
			m_pContentPanel->SetPlayPoint( 0, 0 );
			ShowPlayTime();

			m_pContentPanel->OnStageChanged( 0, MODE_INIT );

			if( g_pUseStyle ){
				SetMode( VIEW_TRACK, true );
//				GenerateCompose();
			}
			else
				SetMode( VIEW_INIT, true );

			m_cbKey->DefItemIndex = g_iMelodyKey;
			m_cbKey->Enabled = g_iMelodyKey>=0;
			m_btnPlay->Enabled = !g_lstOpusStages.empty();
			m_btnSave->Enabled = !g_lstOpusStages.empty();
			m_btnUpload->Enabled = !g_bUpdateMandatory && !g_lstOpusStages.empty();
        }
	}
	else if( iOp==UNDO_VOLUME ){
		if( m_KeyBoard->Visible ){
			m_KeyBoard->ShowKeyboard( false );
			if( m_btnKeyboard->Down )
				m_btnKeyboard->Down = false;
		}

		Perform( UM_SHOW_VOLSET, 2, bUndo );
	}
	else if( iOp==UNDO_PRESET ){
		TUndoLite * pLite = bUndo ? g_Undo.Undo() : g_Undo.Redo();
		TOpusStageList* lstStages = (TOpusStageList*)pLite->pBefore;
		TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1;
		int iPreset = bUndo ? pLite->iBegin : pLite->iEnd,
			iPreOther = bUndo ? pLite->iEnd : pLite->iBegin;
		bool bSetMM = lstAudio!=NULL;

		if( iPreset>0 )
			g_aAudioTracks[0]->Hide();

		if( bSetMM ){
			if( lstAudio->size()>0 )
				f_MM_Undo( bUndo );

			if( bUndo ){
				g_Audio.ResetTracks( lstAudio );
				int idLoc = g_pUseStyle->pStyle ? g_pUseStyle->pStyle->idLoc : -1,
					idStyle = g_pUseStyle->pStyle ? g_pUseStyle->pStyle->idStyle : -1;
				g_Opus.Set( idLoc, idStyle, *lstStages );
				g_Opus.BuildStyleItem();
				g_Midi.ClearMidiTracks();

				((TUseStylePanel*)m_pUseStylePanel)->SetStyleItem( g_pUseStyle );
				m_pContentPanel->OnStageChanged( 0, MODE_INIT );
			}
		}

		if( pLite->iBegin==0 && pLite->iEnd==3 ){
			if( bUndo ){
				DeleteAudioTrack( 1, false );
				g_aAudioTracks[0]->Hide(false);
			}
			else{
				DuplicateRawBars();
			}
		}

		if( pLite->iBegin==0 && pLite->iEnd==3 || bUndo && bSetMM ){
			Perform( UM_STAGECHANGED, iPreset, 0 );
		}
		else{
			PreStageChange( NULL, iPreset );
		}
	}
	else if( iOp==UNDO_FONT_SET ){
		TUndoLite* pLite = bUndo ? g_Undo.Undo() : g_Undo.Redo();
		int idNew = bUndo ? pLite->iBegin : pLite->iEnd;
		bool bNew = bUndo ? (bool)pLite->pBefore : (bool)pLite->pAfter;

		SetFont( idNew, bNew, false );
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ExtFontClick(TObject *Sender)
{
	bool bExtFont = Sender==m_btnExtFontOff;

	if( bExtFont!=g_bExtFont )
		SetFont( g_idFont, bExtFont );
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::URLClick(TObject *Sender)
{
	char strURL[256];
	if( Sender==m_lblExtFont )
		f_CS_GetWebPageURL( URL_EXTFONT, strURL );
	else if( Sender==m_lblWebsite )
		strcpy( strURL, "http://www.iChangzuo.com" );

	ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::URLMouseEnter(TObject *Sender)
{
	if( Sender==m_lblExtFont )
		m_lblExtFont->Font->Color = 0x00FFC090;
	else if( Sender==m_lblWebsite )
		m_lblWebsite->Font->Color = 0x0000D0FF;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::URLMouseLeave(TObject *Sender)
{
	if( Sender==m_lblExtFont )
		m_lblExtFont->Font->Color = clHighlight;
	else if( Sender==m_lblWebsite )
		m_lblWebsite->Font->Color = 0x001D84F6;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMVSTPath(TMessage &Message)
{
	bool bShowCheck = Message.WParam;

	TVSTPathForm *VST = new TVSTPathForm(this, bShowCheck);
	if( VST->ShowModal()==mrOk ) {
		g_strVSTPath  = VST->m_lpSelectVSTDir;
		g_strVSTiPath = VST->m_lpSelectVSTiDir;

		if( bShowCheck ){
			Screen->Cursor = crHourGlass;
			InitVSTList();
			Screen->Cursor = crDefault;
		}
	}
	else if( bShowCheck && VST->IsChecked() ){
		g_bShowVSTPath = false;
	}

	SAFE_DELETE(VST);

	if( bShowCheck ){
		if( !m_strLoadProjectName.IsEmpty() )
			PostMessage(Handle, UM_LOADPROJECT, 0, 0);
		else if( g_bAutoSave )
			PostMessage(Handle, UM_OPENAUTOPROJ, 0, 0);
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMSetContentView(TMessage &Message)
{
	if( g_iViewMode!=VIEW_INIT ){
		int iView = Message.WParam;

		m_pContentPanel->SetScrollMode( iView );
    }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::UMGetContentView(TMessage &Message)
{
	int* iView = (int*)Message.WParam;
	*iView = m_pContentPanel->IsVertical();
}
//---------------------------------------------------------------------------


