//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "MenuUnit.h"
#include "MessageDef.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#include "GlobalUnit.h"
//---------------------------------------------------------------------------
#define CLR_BORDER 		RGB( 100, 108, 119 )
#define CLR_BORDER_HOT	RGB( 30, 32, 36 )
#define CLR_BKGRND_NOR	RGB( 39, 42, 47 )
#define CLR_BKGRND_HOT	RGB( 67, 73, 80 )
#define CLR_TXT_NOR 	RGB( 213, 221, 232 )
#define CLR_TXT_DISABLE RGB( 100, 108, 119 )
#define CLR_BREAK		RGB( 100, 108, 119 )
#define CLR_BOARD_FILL  RGB( 76, 82, 91 )

#define WIDTH_MIN		65
#define WIDTH_MAX		525

#define TOP_HEIGHT		5
#define HEIGHT_BREAK    5
#define IMG_WIDTH		32
#define TRI_WIDTH		16
#define OFFSET_X		6
#define OFFSET_Y        5
#define OFFSET_SEL		3
//---------------------------------------------------------------------------

String __fastcall CutDirString(TCanvas *ACanvas, String strDir, int nWidth)
{
	String str = strDir;
	AnsiString strText;

	if( ACanvas->TextWidth( str ) > nWidth ){    //超出宽
		strText = str.SubString(1, 3);
		nWidth -= ACanvas->TextWidth(strText);

		//-----------------取出文件夹与文件名字-----------------------------
		int istart=1,iend=1;
		UnicodeString strShorty = str.SubString(4, str.Length());
		System::DynamicArray<UnicodeString> DStr;

		for( int i=1;i<=strShorty.Length();i++ ){
			if( strShorty[i]== '\\' ){
			iend = i;
			DStr.Length++;
			DStr[DStr.Length-1] = strShorty.SubString(istart,iend-istart);
			istart = iend+1;
			}
		}
		DStr.Length++;
		DStr[DStr.Length-1] = strShorty.SubString(istart,str.Length()-istart);

		//如果 C:/ + 文件名大于最大宽度 或者 C:/ + ... + 文件名大于最大宽度
		if( ACanvas->TextWidth( strText+DStr[DStr.Length-1] ) > nWidth
			||( DStr.Length>1 && ACanvas->TextWidth( strText+"...\\"+DStr[DStr.Length-1] )>nWidth ) )
		{
			strText = strText + "...";

			while( ACanvas->TextWidth( strShorty )>nWidth ){
				strShorty = strShorty.SubString( 2, strShorty.Length() );
			}
			strText += strShorty;
		}
		else{
			struct Pos{
				int id;
				int Length;
			};
			Pos temPos[20];                       //*********里面个数表示最大支持文件数
			for( int i=0;i<DStr.Length-1;i++ ){
				temPos[i].id=i;
				temPos[i].Length = ACanvas->TextWidth( DStr[i] );
			}

			for( int i=0;i<DStr.Length-1;i++ ){
				for(int j=0;j<DStr.Length-1;j++){
					if( temPos[i].Length>temPos[j].Length ){
					   Pos temp = temPos[i];
					   temPos[i] = temPos[j];
					   temPos[j] = temp;
					}
				}
			}

			int iPos=0;
			AnsiString temstrText = str;
			while( ACanvas->TextWidth(temstrText)>nWidth ){
				if(iPos>DStr.Length-2)
					break;
				temstrText = strText;

				if(ACanvas->TextWidth(DStr[temPos[iPos].id])>ACanvas->TextWidth(DStr[temPos[iPos].id].SubString( 1,2 ) + "..."))
					DStr[temPos[iPos].id] = DStr[temPos[iPos].id].SubString( 1,2 ) + "...";
				iPos++;

				for( int i=0;i<DStr.Length-1;i++ ){
					temstrText += DStr[i];
					temstrText +="\\";
				}
				temstrText +=DStr[DStr.Length-1];
			}

			iPos=0;
			while( ACanvas->TextWidth(temstrText)>nWidth ){
				if(iPos>DStr.Length-2)
					break;
				temstrText = strText;

				if(iPos==0 )
					DStr[iPos] = "...";
				else
					DStr[iPos] = "";
				iPos++;

				for( int i=0;i<DStr.Length-1;i++ ){
					temstrText += DStr[i];
					if(DStr[i]!="")
						temstrText +="\\";
				}
				temstrText +=DStr[DStr.Length-1];
			}

			strText = temstrText;
		}
		DStr.Length=0;
	}
	else
		strText = str;

	return strText;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * *CMenuItem * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//---------------------------------------------------------------------------

__fastcall CMenuItem::CMenuItem(String strCaption, String strHotkey, TNotifyEvent aClickEvent,
								int idMenu, TPngImage *pPic )
{
	Caption     = strCaption;
	Hotkey      = strHotkey;
	OnClick     = aClickEvent;

	if( pPic ) {
		FIcon  = new TPngImage();
		FIcon->Assign(pPic);
	}

	FSubItems    = new System::Classes::TList();
	Parent      = NULL;

	FEnabled    = true;
	FSelected   = false;
	FBreak      = !Caption.Compare("-");
	FMenuID     = idMenu;
}
//---------------------------------------------------------------------------

__fastcall CMenuItem::~CMenuItem()
{
	ClearSubItems();
	SAFE_DELETE(FSubItems);
	SAFE_DELETE(FIcon)
}
//---------------------------------------------------------------------------

void __fastcall CMenuItem::AddItem( CMenuItem *Item )
{
	FSubItems->Add( Item );
	Item->Parent = this;
//	HasSubItem   = true;
//	FCaption->
}
//---------------------------------------------------------------------------

void __fastcall CMenuItem::ClearSubItems()
{
	for( int i=0; i<FSubItems->Count; i++ ){
		CMenuItem *pItem = (CMenuItem *)FSubItems->Items[i];
		SAFE_DELETE(pItem)
	}
	FSubItems->Clear();
}
//---------------------------------------------------------------------------

CMenuItem* __fastcall CMenuItem::AppendMenu( String strCaption, String strHotkey,
									TNotifyEvent aClickEvent, int idMenu, TPngImage *pPic )
{
	CMenuItem * pItem = new CMenuItem(strCaption, strHotkey, aClickEvent, idMenu, pPic);
	pItem->OnDrawItem = FDrawItem;

	FSubItems->Add( pItem );

	return pItem;
}
//---------------------------------------------------------------------------

void __fastcall CMenuItem::CreateSubMenu( TMenuPanel* pSubMenu )
{
	for( int i=0; i<FSubItems->Count; i++ )
		((CMenuItem*)FSubItems->Items[i])->Selected = false;

	pSubMenu->SetMenuItems( FSubItems );
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * *TMenuPanel * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//---------------------------------------------------------------------------

#define STATE_NONE		-1
#define STATE_NORMAL	0
#define STATE_HOVER		1
#define STATE_DOWN		2
#define STATE_DISABLE	3

TPngImage *u_imgSubMenu = NULL,
		*u_imgUp = NULL,
		*u_imgDown = NULL;
TApplicationEvents *u_AppEvent = NULL;
TTimer *u_pTimer = NULL;	//自动滚屏定时器


__fastcall TMenuPanel::TMenuPanel(TComponent* Owner, int iType )
: Vcl::Extctrls::TPanel(Owner)
{
	Visible       = false;

	m_iType       = iType;
	Width		  = 90;
	Height        = 2*TOP_HEIGHT;

	m_Items       = NULL;
	m_ItemHeight  = 20;
	m_iSelected   = -1;
	m_iFirst      = 0;
	m_iUpState	  = m_iDownState = STATE_NONE;

	m_SubMenu     = m_SupMenu = NULL;
//	m_AppEvent 	  = NULL;
//	m_pTimer      = NULL;
}
//---------------------------------------------------------------------------

__fastcall TMenuPanel::~TMenuPanel()
{
	ClearAll();

	if( m_iType==0 )
		ReleaseCapture();

	if( !m_SupMenu )
		SAFE_DELETE(m_Items);

	if( u_AppEvent )
		u_AppEvent->OnMessage = NULL;
}
//---------------------------------------------------------------------------

void TMenuPanel::LoadResources()
{
	if( !u_imgSubMenu ){
		u_imgSubMenu = new TPngImage();
		u_imgSubMenu->LoadFromResourceName(int(HInstance), L"ImgSubMenu");
	}

	if( !u_imgUp ){
		u_imgUp = new TPngImage();
		u_imgUp->LoadFromResourceName(int(HInstance), L"ImgUpMenu");
	}

	if( !u_imgDown ){
		u_imgDown = new TPngImage();
		u_imgDown->LoadFromResourceName(int(HInstance), L"ImgDownMenu");
	}

	u_AppEvent = new TApplicationEvents(Application->MainForm);
}
//---------------------------------------------------------------------------

void TMenuPanel::FreeResources()
{
	SAFE_DELETE( u_imgSubMenu );
	SAFE_DELETE( u_imgUp );
	SAFE_DELETE( u_imgDown );

	SAFE_DELETE( u_AppEvent );
	SAFE_DELETE( u_pTimer );
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::ClearAll()
{
	m_ItemHeight  = 20;
	m_iSelected   = -1;
	m_iFirst      = 0;
	m_iUpState	  = m_iDownState = STATE_NONE;

	if( !m_SupMenu && m_Items ){
		for( int i=0; i<m_Items->Count; i++ ){
			CMenuItem *pItem = (CMenuItem *)m_Items->Items[i];
			SAFE_DELETE(pItem)
		}
		m_Items->Clear();
	}

	SAFE_DELETE(m_SubMenu)
}
//---------------------------------------------------------------------------

CMenuItem*  __fastcall TMenuPanel::CreateMenu( String strCaption, String strHotkey,
											TNotifyEvent aClickEvent, int idMenu, TPngImage *pPic )
{
	CMenuItem * pItem = new CMenuItem(strCaption, strHotkey, aClickEvent, idMenu, pPic);
	pItem->OnDrawItem = DrawItem;

	if( !m_Items )
		m_Items = new System::Classes::TList();

	m_Items->Add( pItem );

	return pItem;
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::ShowSubMenu(CMenuItem *pItem, int iTop)
{
	if( !m_SubMenu ){
		m_SubMenu = new TMenuPanel( NULL, m_iType );

		m_SubMenu->Parent    = Parent;
		m_SubMenu->m_SupMenu = this;

		pItem->CreateSubMenu( m_SubMenu );
	}

	TPoint pt(Left+Width, Top+iTop);

	if( m_iType==0 )
		pt = Parent->ScreenToClient(pt);

	m_SubMenu->Show( pt.x, pt.y );
//    m_SubMenu->Repaint();
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::Show( int X, int Y )
{
	CalRect(X, Y);
	u_AppEvent->OnMessage = DoHandleMessage;

	Extctrls::TPanel::Show();

	if( m_iType==0 )
		SetCapture(Handle);

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

void __fastcall TMenuPanel::CalRect(int X, int Y)
{
	RECT rc;
	if( m_iType==0 )
		SystemParametersInfo( SPI_GETWORKAREA, 0, &rc, 0 );
	else{
		rc.left = Application->MainForm->Left;
		rc.top = Application->MainForm->Top;
		rc.right = rc.left + Application->MainForm->Width;
		rc.bottom = rc.top + Application->MainForm->Height;
    }

	int maxHeight = rc.bottom - rc.top - 27,
		wid = WIDTH_MIN,
		hei = TOP_HEIGHT*2;

	for( int i=0; i<m_Items->Count; i++ ){
		CMenuItem *pItem = (CMenuItem *)(m_Items->Items[i]);

		if( pItem->Break ){
			hei += HEIGHT_BREAK;
		}
		else {
			String strText = pItem->Caption;
			strText += pItem->Hotkey;

			TSize size = Canvas->TextExtent( strText );
			int w = size.Width + OFFSET_X * 2 + OFFSET_SEL * 2 + 12,
				h = size.Height + OFFSET_Y * 2;

			if( m_iType!=0 )
				w += IMG_WIDTH;
			if( pItem->Hotkey.Length()>0 )
				w += 30;
			if( pItem->HasSubItem() )
				w += TRI_WIDTH + 10;

			if( w > WIDTH_MAX ) w = WIDTH_MAX;
			if( wid < w ) wid = w;
			if( m_ItemHeight<h ) m_ItemHeight = h;
			hei += h;
		}

		if( hei >= maxHeight ){
			int board = ( TOP_HEIGHT + u_imgUp->Height ) * 2;
//			hei = (maxHeight - board) / m_ItemHeight * m_ItemHeight + board;
			hei = maxHeight;

			m_iUpState = STATE_DISABLE;
			m_iDownState = STATE_NORMAL;

			break;
		}
	}

	Width = wid;
	Height = hei;

	TPoint point(X,Y);
	point = Parent->ClientToScreen(point);

	if( point.X + Width > rc.right ){
		if( m_SupMenu )
			point.X = m_SupMenu->Left - Width;
		else
			point.X = rc.right - Width - 2;
	}

	if( point.Y + Height > rc.bottom ){
		point.Y = rc.bottom - Height - 2;
	}

	if( m_iType!=0 )
		point = Parent->ScreenToClient(point);

	Left = point.X;
	Top  = point.Y;
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::DeleteMenuItem(int index)
{
	if( CLEAR_ALL==index ){
		ClearAll();
	}
	else if( index>=0 && index<m_Items->Count ){
		((CMenuItem*)m_Items->Items[index])->ClearSubItems();
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::CreateWnd()
{
	Vcl::Extctrls::TPanel::CreateWnd();

	Canvas->Font->Name = g_strTxtFontName;
	Canvas->Font->Quality = TFontQuality::fqClearTypeNatural;
	Canvas->Font->Size = g_szFont9;
//	Canvas->Font->Color = CLR_TXT_NOR;
//	Canvas->Font->Assign( Application->MainForm->Font );
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::CreateParams(TCreateParams &Params)
{
	TPanel::CreateParams(Params);

	if( m_iType==0 )
		Params.Style = WS_POPUP;
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::CloseMenu()
{
	if( m_iType!=0 && Parent )
		PostMessage( Parent->Handle, UM_MENUCLOSE, NULL, NULL );
}
//---------------------------------------------------------------------------

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

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

	//绘制底色
	tempCanvas->Brush->Color = CLR_BKGRND_NOR;
	tempCanvas->FillRect( rect );

	//绘制外边框
	tempCanvas->Brush->Color = CLR_BORDER;
	tempCanvas->FrameRect( rect );

	tempCanvas->Pixels[0][0]          = CLR_BOARD_FILL;
	tempCanvas->Pixels[Width][0]      = CLR_BOARD_FILL;
	tempCanvas->Pixels[Width][Height] = CLR_BOARD_FILL;
	tempCanvas->Pixels[0][Height]     = CLR_BOARD_FILL;

	delete tempCanvas;

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

void __fastcall TMenuPanel::Paint(void)
{
	int t = TOP_HEIGHT,
		b = Height - TOP_HEIGHT,
		h;

	if( m_iUpState!=STATE_NONE ){ //绘制上翻箭头
		h = u_imgUp->Height;

		TRect rect( OFFSET_SEL, 0, Width-OFFSET_SEL, t+h );
		DrawUpDown( Canvas, rect, true );

		t += h;
		b -= h;
	}

	bool bDisableDown = true;
	for( int i=m_iFirst; i<m_Items->Count; i++ ){
		CMenuItem *pItem = (CMenuItem*)m_Items->Items[i];
		if( pItem->Break )
			h = HEIGHT_BREAK;
		else
			h = m_ItemHeight;

		if( t+h > b ){
			bDisableDown = false;
			break;
		}

		TRect rect( OFFSET_SEL, t, Width-OFFSET_SEL, t+h );
		if( pItem->OnDrawItem )
			pItem->OnDrawItem( pItem, Canvas, rect );

		t += h;
	}

	//绘制竖线
	if( t<b && IsDrawImg() ){
		int X = OFFSET_SEL + IMG_WIDTH - 6,
			Y = t;
		Canvas->Pen->Color = CLR_BREAK;
		Canvas->MoveTo( X, Y );

		Y = b;
		Canvas->LineTo( X, Y );
	}

	if( m_iDownState!=STATE_NONE ){ //绘制向下箭头
		if( bDisableDown )
			m_iDownState = STATE_DISABLE;

		h = u_imgDown->Height;

		TRect rect( OFFSET_SEL, b, Width-OFFSET_SEL, Height );
		DrawUpDown( Canvas, rect, false );
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::WMMouseMove(TWMMouse &Message)
{
	if( !Visible )
		return;

	TShiftState Shift(Message.Keys);
	int t = TOP_HEIGHT,
		b = Height - TOP_HEIGHT,
		h;

	int iLastSel = m_iSelected;

	if( m_iUpState!=STATE_NONE ){ //绘制上翻箭头
		h = u_imgUp->Height;
		bool bRedraw = false;

		if( m_iUpState!=STATE_DISABLE ){
			if( Message.YPos > 0 && Message.YPos < t+h
						&& (Message.XPos >= 0 && Message.XPos <= Width ) ){
				if( Shift.Empty() && m_iUpState!=STATE_HOVER ){
					m_iUpState = STATE_HOVER;
					bRedraw = true;
				}
			}
			else{
				if( m_iUpState!=STATE_NORMAL ){
					m_iUpState = STATE_NORMAL;
					bRedraw = true;
					SAFE_DELETE(u_pTimer);
				}
			}

			if( bRedraw ){
				TRect rect( OFFSET_SEL, 0, Width-OFFSET_SEL, t+h );
				DrawUpDown( Canvas, rect, true );
			}
		}

		t += h;
		b -= h;
	}

	for( int i=m_iFirst; i<m_Items->Count; i++ ) {
		CMenuItem *pItem = (CMenuItem*)m_Items->Items[i];

		if( pItem->Break )
			h = HEIGHT_BREAK;
		else
			h= m_ItemHeight;

		if( t+h<=b ){
			if( !pItem->Break ){
				if( Message.YPos > t && Message.YPos < t+h
							&& (Message.XPos >= 0 && Message.XPos <= Width ) ){
					if( !pItem->Selected ){
						SAFE_DELETE(m_SubMenu) //子菜单

						if( pItem->Enabled ){
							pItem->Selected = true;

							m_iSelected = i;

							TRect rect( OFFSET_SEL, t, Width-OFFSET_SEL, t+h );
							if( pItem->OnDrawItem )
								pItem->OnDrawItem( pItem, Canvas, rect );

							if( pItem->HasSubItem() )
								ShowSubMenu(pItem, t);
						}
						else{
							m_iSelected = -1;
						}
					}
				}
				else if( iLastSel==i ){
					pItem->Selected = false;

					TRect rect( OFFSET_SEL, t, Width-OFFSET_SEL, t+h );
					if( pItem->OnDrawItem )
						pItem->OnDrawItem( pItem, Canvas, rect );

					if( m_iSelected==i )
						m_iSelected = -1;
				}
			}

			t += h;
		}
		else{
			t = b;
			break;
		}
	}

	if( m_iDownState!=STATE_NONE ){ //绘制下翻箭头
		h = u_imgUp->Height + TOP_HEIGHT;
		bool bRedraw = false;

		if( m_iDownState!=STATE_DISABLE ){
			if( Message.YPos > t && Message.YPos < t+h
						&& (Message.XPos >= 0 && Message.XPos <= Width ) ){
				if( Shift.Empty() && m_iDownState!=STATE_HOVER ){
					m_iDownState = STATE_HOVER;
					bRedraw = true;
				}
			}
			else{
				if( m_iDownState!=STATE_NORMAL ){
					m_iDownState = STATE_NORMAL;
					bRedraw = true;
					SAFE_DELETE(u_pTimer);
				}
			}

			if( bRedraw ){
				TRect rect( OFFSET_SEL, t, Width-OFFSET_SEL, t+h );
				DrawUpDown( Canvas, rect, false );
			}
		}
	}

	if( !m_SubMenu && u_AppEvent->OnMessage!=DoHandleMessage ) {
		u_AppEvent->OnMessage = DoHandleMessage;

		if( m_iType==0 && GetCapture()!=Handle){
			SetCapture( Handle );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::CMMouseLeave(TMessage &Message)
{
	SAFE_DELETE( u_pTimer );

	if( !Visible || m_SubMenu ) return;

	int t = TOP_HEIGHT,
		b = Height - TOP_HEIGHT,
		h;

	if( m_iUpState!=STATE_NONE ){ //绘制上翻箭头
		h = u_imgUp->Height;

		if( m_iUpState==STATE_HOVER || m_iUpState==STATE_DOWN ){
			m_iUpState = STATE_NORMAL;

			TRect rect( OFFSET_SEL, 0, Width-OFFSET_SEL, t+h );
			DrawUpDown( Canvas, rect, true );

			return;
		}

		t += h;
		b -= h;
	}

	for( int i=m_iFirst; i<m_Items->Count; i++ ){
		CMenuItem *pItem = (CMenuItem*)m_Items->Items[i];

		if( pItem->Break )
			h = HEIGHT_BREAK;
		else
			h = m_ItemHeight;

		if( t+h<=b ){
			if( pItem->Selected ){
				pItem->Selected = false;
				if( m_iSelected==i ){
					 m_iSelected = -1;
				}

				TRect rect( OFFSET_SEL, t, Width-OFFSET_SEL, t+h );
				if( pItem->OnDrawItem )
					pItem->OnDrawItem( pItem, Canvas, rect );
			}

			t += h;
		}
		else{
			t = b;
			break;
		}
	}

	if( m_iDownState!=STATE_NONE ){ //绘制下翻箭头
		h = u_imgUp->Height + TOP_HEIGHT;
		bool bRedraw = false;

		if( m_iDownState==STATE_HOVER || m_iDownState==STATE_DOWN ){
			m_iDownState = STATE_NORMAL;

			TRect rect( OFFSET_SEL, t, Width-OFFSET_SEL, t+h );
			DrawUpDown( Canvas, rect, false );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::MouseDown(System::Uitypes::TMouseButton Button,
								System::Classes::TShiftState Shift, int X, int Y)
{
	if( !Visible )
		return;

	if( m_iSelected<0 ){
		if( Button==mbLeft && m_iUpState!=STATE_NONE && X>0 && X<Width ){
			int h = TOP_HEIGHT+u_imgUp->Height;
			bool bRedraw = false;

			if( m_iUpState==STATE_HOVER && Y>0 && Y<h ){ //向上翻动
				m_iUpState = STATE_DOWN;
				m_iFirst--;
				if( ((CMenuItem*)m_Items->Items[m_iFirst])->Break )
					m_iFirst--;

				if( m_iDownState==STATE_DISABLE )
					m_iDownState = STATE_NORMAL;

				if( m_iFirst==0 )
					m_iUpState = STATE_DISABLE;

				bRedraw = true;
			}
			else if( m_iDownState==STATE_HOVER && Y<Height && Y>Height - h ){ //向下翻动
				m_iDownState = STATE_DOWN;
				m_iFirst++;
				if( ((CMenuItem*)m_Items->Items[m_iFirst])->Break )
					m_iFirst++;

				if( m_iUpState==STATE_DISABLE ){
					m_iUpState = STATE_NORMAL;
				}

				bRedraw = true;
			}

			if( bRedraw ){
				SAFE_DELETE( u_pTimer );

				u_pTimer = new TTimer(this);
				u_pTimer->OnTimer = TimerProc;
				u_pTimer->Tag = m_iUpState==STATE_DOWN ? -1 : 1;
				u_pTimer->Interval = 500;
				u_pTimer->Enabled = true;

				InvalidateRgn( Handle, NULL, false );
			}
		}

		return;
	}

	CMenuItem *pItemSel = (CMenuItem*)m_Items->Items[m_iSelected];
	if(  pItemSel->OnClick!=NULL &&
	   !(pItemSel->HasSubItem())   &&
	   !(pItemSel->Break)      &&
		 pItemSel->Enabled )
	{
		HideAll();
		pItemSel->OnClick((TObject*)pItemSel->MenuID);
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::MouseUp(System::Uitypes::TMouseButton Button,
								System::Classes::TShiftState Shift, int X, int Y)
{
	SAFE_DELETE( u_pTimer );

	if( !Visible )
		return;

	if( m_iSelected<0 ){
		int h = TOP_HEIGHT+u_imgUp->Height;

		if( m_iUpState==STATE_DOWN ){
			if( X>0 && X<Width && Y>0 && Y<h )
				m_iUpState = STATE_HOVER;
			else
				m_iUpState = STATE_NORMAL;

			TRect rect( OFFSET_SEL, 0, Width-OFFSET_SEL, h );
			DrawUpDown( Canvas, rect, true );
		}
		else if( m_iDownState==STATE_DOWN ){
			if( X>0 && X<Width && Y<Height && Y>Height-h )
				m_iDownState = STATE_HOVER;
			else
				m_iDownState = STATE_NORMAL;

			TRect rect( OFFSET_SEL, Height-h, Width-OFFSET_SEL, Height );
			DrawUpDown( Canvas, rect, false );
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::DoHandleMessage(MSG &Msg, bool &Handled)
{
	if( Visible ){
		if( Msg.message==WM_LBUTTONDOWN || Msg.message==WM_RBUTTONDOWN
							|| Msg.message==WM_NCLBUTTONDOWN || Msg.message==WM_NCRBUTTONDOWN ){
			TMenuPanel* pMenu = (TMenuPanel*)this;

			while( pMenu ){
				TPoint ptCusor = pMenu->ScreenToClient(TPoint(Msg.pt.x, Msg.pt.y));
				if( PtInRect( TRect(0, 0, pMenu->Width, pMenu->Height), ptCusor ) )
					return;

				pMenu = (TMenuPanel*)pMenu->m_SupMenu;
			}

			m_iSelected = -1;
			HideAll();
		}
		else if( m_iType==0 && Msg.message==WM_MOUSEMOVE && Msg.wParam==0 ){
			TPoint ptCusor = ScreenToClient(TPoint(Msg.pt.x, Msg.pt.y));
			if( PtInRect( TRect(0, 0, Width, Height), ptCusor ) )
				return;

			TMenuPanel* pSup = (TMenuPanel*)m_SupMenu;
			while( pSup ){
				ptCusor = pSup->ScreenToClient(TPoint(Msg.pt.x, Msg.pt.y));
				if( PtInRect( TRect(0, 0, pSup->Width, pSup->Height), ptCusor ) ){
					PostMessage( pSup->Handle, WM_MOUSEMOVE, 0, MAKELONG(ptCusor.x, ptCusor.y) );
					return;
				}

				pSup = (TMenuPanel*)pSup->m_SupMenu;
			}
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::HideAll()
{
	Hide();

	u_AppEvent->OnMessage = NULL;
	SAFE_DELETE(u_pTimer);

	if( m_iType==0 )
		ReleaseCapture();

	TMenuPanel* pSup = (TMenuPanel*)m_SupMenu;
	while( pSup ){
		pSup->Hide();
		pSup = (TMenuPanel*)pSup->m_SupMenu;
	}

	CloseMenu();
}//---------------------------------------------------------------------------

void __fastcall TMenuPanel::DrawItem( TObject *Sender, TCanvas* ACanvas, const TRect &ARect )
{
	CMenuItem *pItem = (CMenuItem *)Sender;
	bool bIsDrawImg  = IsDrawImg();
	bool bIsDrawDir  = pItem->IsDrawDir();

	//绘制底色
	ACanvas->Brush->Color = pItem->Selected ? CLR_BKGRND_HOT : CLR_BKGRND_NOR;
	ACanvas->FillRect( ARect );

	int X, Y;

	 //绘制选中框
	if( pItem->Selected ){
		ACanvas->Brush->Color = CLR_BORDER_HOT;
		ACanvas->FrameRect( ARect );
	}//绘制竖线
	else if( bIsDrawImg ) {
		X = ARect.Left + IMG_WIDTH - 6;
		Y = ARect.Top;
		ACanvas->Pen->Color = CLR_BREAK;
		ACanvas->MoveTo( X, Y );

		Y = ARect.Top + ARect.Height();
		ACanvas->LineTo( X, Y );
	}

	//绘制间隔线
	if( pItem->Break ){
		if( bIsDrawImg ) X = ARect.Left + IMG_WIDTH + OFFSET_X + 2;
		else 			 X = ARect.Left + OFFSET_X + 2;
		Y = ARect.Top + ( ARect.Bottom - ARect.Top )/2;
		ACanvas->Pen->Color = CLR_BREAK;
		ACanvas->MoveTo( X, Y );

		X = ARect.Left + ARect.Width()-2;
		ACanvas->LineTo( X, Y );

		return;
	}

	//输出图标
	if( bIsDrawImg && pItem->Icon ){
		TPngImage* pIcon = pItem->Icon;

		int w = pIcon->Width/2,
			h = pIcon->Height,
			l = pItem->Enabled ? 0 : w;

		X = ARect.Left + ( IMG_WIDTH - pIcon->Width / 2 ) / 2;
		Y = ARect.Top + ( ARect.Height() - pIcon->Height ) / 2;

		HRGN rgnClip;
		rgnClip = ::CreateRectRgn( X, Y, X+w, Y+h );
		::SelectClipRgn( ACanvas->Handle, rgnClip );

		ACanvas->Draw( X-l, Y, pIcon );

		::SelectClipRgn( ACanvas->Handle, NULL );
		::DeleteObject(rgnClip);
	}

	//输出Caption
	ACanvas->Brush->Style = bsClear;
	ACanvas->Font->Color = pItem->Enabled ? CLR_TXT_NOR : CLR_TXT_DISABLE;
	if( bIsDrawImg ) X = ARect.Left + IMG_WIDTH + OFFSET_X;
	else             X = ARect.Left + OFFSET_X*2;
	Y = ARect.Top + OFFSET_Y;

	//---------------------
	String strText = pItem->Caption;
	int wHotKey = ACanvas->TextWidth( pItem->Hotkey );
	int nWidth = ARect.Width() - TRI_WIDTH - IMG_WIDTH - 2*OFFSET_X - wHotKey;
	if( bIsDrawDir ) strText = CutDirString(ACanvas, strText, nWidth);
	ACanvas->TextOut( X, Y, strText );

	//输出Hotkey
	if( wHotKey>0 ){
		X = ARect.Left + ARect.Width() - TRI_WIDTH - OFFSET_X - wHotKey;
		ACanvas->TextOut( X, Y, pItem->Hotkey );
	}

	//输出子菜单提示
	if( pItem->HasSubItem() ){
		int w = u_imgSubMenu->Width/2,
			h = u_imgSubMenu->Height,
			l = pItem->Selected ? w : 0;

		X = ARect.Left + ARect.Width() - TRI_WIDTH;
		Y = ARect.Top + (ARect.Height() - h) / 2;

		HRGN rgnClip;
		rgnClip = ::CreateRectRgn( X, Y, X+w, Y+h );
		::SelectClipRgn( ACanvas->Handle, rgnClip );

		ACanvas->Draw( X-l, Y, u_imgSubMenu );

		::SelectClipRgn( ACanvas->Handle, NULL );
		::DeleteObject(rgnClip);
	}
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::DrawUpDown( TCanvas* ACanvas, const TRect &ARect, bool bUp )
{
	int s = bUp ? m_iUpState : m_iDownState,
		w = u_imgUp->Width/4,
		h = u_imgUp->Height,
		l = w * s;

	int X = ARect.Left + ( ARect.Width() - w ) / 2,
		Y = ARect.Top + (ARect.Height() - h) / 2 + ( bUp ? 1 : 2 );

	HRGN rgnClip;
	rgnClip = ::CreateRectRgn( X, Y, X+w, Y+h );
	::SelectClipRgn( ACanvas->Handle, rgnClip );

	ACanvas->Draw( X-l, Y, bUp ? u_imgUp : u_imgDown );

	::SelectClipRgn( ACanvas->Handle, NULL );
	::DeleteObject(rgnClip);

	//绘制上线或下线
	X = ARect.left + 2;
	Y = bUp ? ARect.bottom - 1 : ARect.top;
	ACanvas->Pen->Color = CLR_BREAK;
	ACanvas->MoveTo( X, Y );

	X = ARect.right - 2;
	ACanvas->LineTo( X, Y );
}
//---------------------------------------------------------------------------

void __fastcall TMenuPanel::TimerProc(TObject* Sender)
{
	if( u_pTimer && u_pTimer->Enabled ){
		int direct = u_pTimer->Tag;
		bool bRedraw = false,
			bStop = true;

		if( direct<0 && m_iUpState==STATE_DOWN ){
			m_iFirst--;
			if( ((CMenuItem*)m_Items->Items[m_iFirst])->Break )
				m_iFirst--;

			if( m_iFirst==0 )
				m_iUpState = STATE_DISABLE;
			else
				bStop = false;

			bRedraw = true;
		}
		else if( direct>0 && m_iDownState==STATE_DOWN ){
			m_iFirst++;

			if( ((CMenuItem*)m_Items->Items[m_iFirst])->Break )
				m_iFirst++;

			bStop = false;
			bRedraw = true;
		}

		if( bRedraw )
			InvalidateRgn( Handle, NULL, false );

		if( bStop ){
			SAFE_DELETE(u_pTimer);
//			delete u_pTimer;
//			u_pTimer = NULL;
		}
		else if( u_pTimer->Interval>200 ){
			u_pTimer->Interval = 200;
        }
	}
}
//-----------------------------------------------------------------------------


