Files
2026-06-13 00:05:19 +08:00

282 lines
7.4 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MessageDef.h"
#include "MenuBar.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define STATE_NOR 0
#define STATE_HOT 1
#define STATE_DOWN 2
#define CLR_NOR RGB( 74, 80, 88 )
#define CLR_HOT RGB( 87, 94, 104 )
#define CLR_DOWN RGB( 39, 42, 47 )
#define CLR_BOARD_OUT RGB( 100, 108, 119 )
#define CLR_BOARD_IN RGB( 44, 46, 48 )
#define CLR_BOARD_FILL RGB( 70, 73, 76 )
#define OFFSET_X 10
#define OFFSET_Y 3
int u_Height = 0;
//---------------------------------------------------------------------------
// TTextMenu
__fastcall TTextMenu::TTextMenu( String caption, String shortcut, int type )
{
m_strCaption = caption;
m_strShortCut = shortcut;
iType = type;
iState = STATE_NOR;
}
//---------------------------------------------------------------------------
void __fastcall TTextMenu::ShowMenu( bool bShow )
{
TMessage msg;
msg.WParamLo = iType;
msg.WParamHi = bShow;
msg.LParamLo = Left;
msg.LParamHi = MENUBAR_TOP+u_Height;
Application->MainForm->Perform( UM_SHOWMENU, msg.WParam, msg.LParam );
}
//---------------------------------------------------------------------------
void __fastcall TTextMenu::Draw( TCanvas* pCanvas )
{
TColor clrOldPen = pCanvas->Pen->Color,
clrOldBrush = pCanvas->Brush->Color;
//刷新背景
TRect rect( Left+1, MENUBAR_TOP+1, Left+Width, MENUBAR_TOP+u_Height );
pCanvas->Brush->Color = iState==STATE_HOT ? CLR_HOT :
(iState==STATE_DOWN ? CLR_DOWN : CLR_NOR );
pCanvas->FillRect( rect );
if( iState!=STATE_NOR ){
//绘制内边框
TRect rtFrame( Left+1, MENUBAR_TOP+1, Left+Width, MENUBAR_TOP+u_Height );
pCanvas->Brush->Color = CLR_BOARD_IN;
pCanvas->FrameRect( rtFrame );
pCanvas->Pixels[Left+1][MENUBAR_TOP+1] = CLR_BOARD_FILL;
pCanvas->Pixels[Left+Width-1][MENUBAR_TOP+1] = CLR_BOARD_FILL;
pCanvas->Pixels[Left+Width-1][MENUBAR_TOP+u_Height-1] = CLR_BOARD_FILL;
pCanvas->Pixels[Left+1][MENUBAR_TOP+u_Height-1] = CLR_BOARD_FILL;
pCanvas->Pen->Color = CLR_BOARD_OUT;
pCanvas->Font->Color = CLR_TEXT_HOT;
}
else{
pCanvas->Pen->Color = CLR_NOR;
pCanvas->Font->Color = CLR_TEXT_NOR;
}
//绘制外边框
//上边线
pCanvas->MoveTo( Left+3, MENUBAR_TOP );
pCanvas->LineTo( Left+Width-2, MENUBAR_TOP );
//左边线
pCanvas->MoveTo( Left, MENUBAR_TOP+3 );
pCanvas->LineTo( Left, MENUBAR_TOP+u_Height-2 );
//下边线
pCanvas->MoveTo( Left+3, MENUBAR_TOP+u_Height );
pCanvas->LineTo( Left+Width-2, MENUBAR_TOP+u_Height );
//右边线
pCanvas->MoveTo( Left+Width, MENUBAR_TOP+3 );
pCanvas->LineTo( Left+Width, MENUBAR_TOP+u_Height-2 );
pCanvas->Pen->Color = clrOldPen;
pCanvas->Brush->Color = clrOldBrush;
TBrushStyle oldBS = pCanvas->Brush->Style;
pCanvas->Brush->Style = bsClear;
//输出文字
// String strText = m_strCaption;
String strText = m_strCaption + "(" + m_strShortCut + ")";
int txtLeft = Left + OFFSET_X,
txtTop = MENUBAR_TOP + OFFSET_Y;
pCanvas->TextOut( txtLeft, txtTop, strText );
pCanvas->Brush->Style = oldBS;
}
//---------------------------------------------------------------------------
void __fastcall TTextMenu::Invalidate()
{
TRect rect( Left, MENUBAR_TOP, Left+Width, MENUBAR_TOP+u_Height );
InvalidateRect( Application->MainForm->Handle, &rect, false );
}
//---------------------------------------------------------------------------
// TMenuBar
__fastcall TMenuBar::TMenuBar( TComponent* Owner,TCanvas* pCanvas )
{
m_pCanvas = pCanvas;
m_nMenuCount = 0;
Width = 0;
m_bMenuShow = false;
m_iSelMenu = -1;
}
//---------------------------------------------------------------------------
__fastcall TMenuBar::~TMenuBar()
{
while( m_nMenuCount>0 ){
delete m_aTextMenu[--m_nMenuCount];
}
}
//---------------------------------------------------------------------------
int TMenuBar::GetHeight()
{
return u_Height;
}
//---------------------------------------------------------------------------
void TMenuBar::AddMenu( String caption, String shortcut, int iType )
{
String strText = caption;
strText += "(" + shortcut + ")";
TSize size = m_pCanvas->TextExtent( strText );
int w = size.Width + OFFSET_X * 2,
h = size.Height + OFFSET_Y * 2;
m_aTextMenu[m_nMenuCount] = new TTextMenu( caption, shortcut, iType );
m_aTextMenu[m_nMenuCount]->Left = MENUBAR_LEFT + Width;
m_aTextMenu[m_nMenuCount]->Width = w;
if( u_Height<h ) u_Height = h;
Width += m_aTextMenu[m_nMenuCount]->Width + 2;
m_nMenuCount++;
}
//---------------------------------------------------------------------------
bool __fastcall TMenuBar::HitTest( int XPos, int YPos, bool bLBDown )
{
bool bHit(false), bRet(false);
if( YPos > MENUBAR_TOP && YPos < MENUBAR_TOP + u_Height
&& XPos > MENUBAR_LEFT && XPos < MENUBAR_LEFT + Width + OFFSET_BR + 3 ){
for( int i=0; i<m_nMenuCount; i++ ){
if( XPos < m_aTextMenu[i]->Left + m_aTextMenu[i]->Width
&& XPos > m_aTextMenu[i]->Left ){
if( bLBDown ){
m_bMenuShow = !m_bMenuShow;
}
if( m_bMenuShow ){
if( m_aTextMenu[i]->iState!=STATE_DOWN ){
m_aTextMenu[i]->iState = STATE_DOWN;
m_aTextMenu[i]->Draw( m_pCanvas );
m_aTextMenu[i]->ShowMenu( true );
}
}
else if( m_aTextMenu[i]->iState!=STATE_HOT ){
if( m_aTextMenu[i]->iState==STATE_DOWN ){
m_aTextMenu[m_iSelMenu]->ShowMenu( false );
}
m_aTextMenu[i]->iState = STATE_HOT;
m_aTextMenu[i]->Draw( m_pCanvas );
}
if( m_iSelMenu!=i ){
if( m_iSelMenu>=0 ){
m_aTextMenu[m_iSelMenu]->iState = STATE_NOR;
m_aTextMenu[m_iSelMenu]->Draw( m_pCanvas );
m_aTextMenu[m_iSelMenu]->ShowMenu( false );
}
m_iSelMenu = i;
}
bHit = true;
break;
}
}
bRet = true;
}
if( !bHit && m_iSelMenu>=0 && ( !m_bMenuShow || bLBDown ) ){
m_aTextMenu[m_iSelMenu]->iState = STATE_NOR;
m_aTextMenu[m_iSelMenu]->Draw( m_pCanvas );
m_aTextMenu[m_iSelMenu]->ShowMenu( false );
m_iSelMenu = -1;
if( m_bMenuShow )
m_bMenuShow = false;
}
return bRet;
}
//---------------------------------------------------------------------------
void __fastcall TMenuBar::DrawMenuBar()
{
for( int i=0; i<m_nMenuCount; i++ ){
m_aTextMenu[i]->Draw( m_pCanvas );
}
}
//---------------------------------------------------------------------------
void __fastcall TMenuBar::Reset()
{
if( m_iSelMenu>=0 && m_bMenuShow ){
m_aTextMenu[m_iSelMenu]->iState = STATE_NOR;
m_aTextMenu[m_iSelMenu]->Draw( m_pCanvas );
m_aTextMenu[m_iSelMenu]->ShowMenu( false );
m_iSelMenu = -1;
m_bMenuShow = false;
}
}
//---------------------------------------------------------------------------
void TMenuBar::ShowMenu( int iType )
{
TPoint point;
GetCursorPos( &point );
point = Application->MainForm->ScreenToClient( point );
if( m_bMenuShow && point.Y > MENUBAR_TOP && point.Y < MENUBAR_TOP + u_Height
&& point.X > MENUBAR_LEFT && point.X < MENUBAR_LEFT + Width + OFFSET_BR + 3 ){
return;
}
for( int i=0; i<m_nMenuCount; i++ ){
if( m_aTextMenu[i]->iType==iType ){
if( m_aTextMenu[i]->iState!=STATE_DOWN ){
m_aTextMenu[i]->iState = STATE_DOWN;
m_aTextMenu[i]->Draw( m_pCanvas );
m_aTextMenu[i]->ShowMenu( true );
m_iSelMenu = i;
m_bMenuShow = true;
}
}
else{
if( m_aTextMenu[i]->iState==STATE_DOWN ){
m_aTextMenu[i]->iState = STATE_NOR;
m_aTextMenu[i]->Draw( m_pCanvas );
}
}
}
}
//---------------------------------------------------------------------------