//--------------------------------------------------------------------------- #include #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 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;iTextWidth( DStr[i] ); } for( int i=0;itemPos[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;iTextWidth(temstrText)>nWidth ){ if(iPos>DStr.Length-2) break; temstrText = strText; if(iPos==0 ) DStr[iPos] = "..."; else DStr[iPos] = ""; iPos++; for( int i=0;iAssign(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; iCount; 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; iCount; 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; iCount; 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; iCount; 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= 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 && indexCount ){ ((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; iCount; 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( tPen->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; iCount; 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; iCount; 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 && XHeight; bool bRedraw = false; if( m_iUpState==STATE_HOVER && Y>0 && YItems[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 && YHeight - 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 && X0 && Y0 && XHeight-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; } } } //-----------------------------------------------------------------------------