Files
AccompanyCube/SystemMenuUnit.cpp
2026-06-13 00:10:11 +08:00

252 lines
5.9 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "GlobalUnit.h"
#include "SystemMenuUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define SYSMENU_MINWIDTH 192
#define SYSMENU_MAXWIDTH 400
#define BREAK_HEIGHT 5
#define CLR_DISABLE RGB(163,153,143)
__fastcall TSystemMenu::TSystemMenu(TComponent* Owner)
: TPopupMenu( Owner )
{
m_pPicSide = m_pPicTop = m_pPicBottom = m_pPicNormal = m_pPicHover = NULL;
OwnerDraw = TRUE;
AutoHotkeys = maManual;
m_pFntText = new TFont();
m_pFntText->Name = "黑体";
m_pFntText->Size = int(10 * 96.0 / g_yDpi + 0.5);
m_clrNormal = RGB(60,43,23);
m_clrHover = RGB(232,212,191);
m_clrBreak = RGB(150,118,80);
m_pPicSide = new TBitmap;
m_pPicSide->LoadFromResourceName(int(HInstance), "MenuSide");
m_pPicTop = new TBitmap;
m_pPicTop->LoadFromResourceName(int(HInstance), "MenuTop");
m_pPicBottom = new TBitmap;
m_pPicBottom->LoadFromResourceName(int(HInstance), "MenuBottom");
m_pPicNormal = new TBitmap;
m_pPicNormal->LoadFromResourceName(int(HInstance), "MenuNormalBar");
m_pPicHover = new TBitmap;
m_pPicHover->LoadFromResourceName(int(HInstance), "MenuHoverBar");
}
__fastcall TSystemMenu::~TSystemMenu()
{
if( m_pPicNormal )
delete m_pPicNormal;
if( m_pPicSide )
delete m_pPicSide;
if( m_pPicTop )
delete m_pPicTop;
if( m_pPicBottom )
delete m_pPicBottom;
if( m_pPicHover )
delete m_pPicHover;
if( m_pFntText )
delete m_pFntText;
}
void TSystemMenu::CreateCustomMenuItem( String strCaption, TNotifyEvent aClickEvent, int subIndex )
{
TMenuItem * pItem = new TMenuItem( this );
pItem->Caption = strCaption;
pItem->OnAdvancedDrawItem = OwnerDrawItem;
pItem->OnMeasureItem = OwnerMeasureItem;
pItem->OnClick = aClickEvent;
pItem->Tag = subIndex;
if( subIndex==-1 ){
Items->Add( pItem );
}
else{
Items->Items[subIndex]->Add( pItem );
}
}
#include <string>
using namespace std;
void __fastcall TSystemMenu::OwnerDrawItem(TObject* Sender, TCanvas* ACanvas, const TRect &ARect, TOwnerDrawState State)
{
TMenuItem *pItem = (TMenuItem*)Sender;
TFont *oldFont = ACanvas->Font;
TRect rectDraw(0, 0, 0, 0);
int xPos=0, yPos=0;
if( m_pPicTop && pItem->MenuIndex==0 ){ //第一个菜单项
rectDraw.right = ARect.right;
rectDraw.bottom = m_pPicTop->Height;
ACanvas->StretchDraw( rectDraw, m_pPicTop );
}
yPos += m_pPicTop->Height;
TMenuItem * pItemParent = pItem->Parent;
for( int i=0; i<pItem->MenuIndex; i++ ){
if( pItemParent->Items[i]->IsLine() )
yPos += BREAK_HEIGHT;
else
yPos += m_pPicSide->Height;
}
if( m_pPicBottom && pItem->MenuIndex==pItemParent->Count-1 ){ //最后一个菜单项
rectDraw.right = ARect.right;
rectDraw.top = yPos+m_pPicSide->Height;
rectDraw.bottom = rectDraw.top + m_pPicBottom->Height;
ACanvas->StretchDraw( rectDraw, m_pPicBottom );
}
int nBodyWidth = ARect.Width() - 2 * m_pPicSide->Width;
ACanvas->Draw( xPos, yPos, m_pPicSide ); //绘制左边框
xPos += m_pPicSide->Width;
rectDraw.left = xPos;
rectDraw.right = xPos + nBodyWidth;
rectDraw.top = yPos;
rectDraw.bottom = yPos + m_pPicNormal->Height;
if( State.Contains(odSelected) && !State.Contains(odDisabled)){
//绘制选中项
m_pFntText->Color = m_clrHover;
ACanvas->StretchDraw( rectDraw, m_pPicHover );
}
else{
if( State.Contains(odDisabled) ){
//禁用项
m_pFntText->Color = CLR_DISABLE;
}
else{
//常规项
m_pFntText->Color = m_clrNormal;
}
ACanvas->StretchDraw( rectDraw, m_pPicNormal );
}
xPos += nBodyWidth;
ACanvas->Draw( xPos, yPos, m_pPicSide ); //绘制右边框
if( pItem->IsLine() ){
ACanvas->Pen->Color = m_clrBreak;
ACanvas->MoveTo( m_pPicSide->Width+12, ARect.Top+2 );
ACanvas->LineTo( ARect.Right-m_pPicSide->Width-12, ARect.Top+2 );
}
else{
ACanvas->Font = m_pFntText;
ACanvas->Brush->Style = bsClear;
int nWidth = ARect.Right - 2 * (m_pPicSide->Width + 8);
AnsiString strText;
if( ACanvas->TextWidth( pItem->Caption )>nWidth ){
strText = pItem->Caption.SubString(1, 3);
strText += "...";
nWidth -= ACanvas->TextWidth( strText );
UnicodeString strShorty = pItem->Caption.SubString(8, pItem->Caption.Length());
while( ACanvas->TextWidth( strShorty )>nWidth ){
strShorty = strShorty.SubString( 2, strShorty.Length() );
}
int iPos = strShorty.Pos( "\\" );
if( iPos>1 ){
strShorty = strShorty.SubString( iPos, strShorty.Length() );
}
strText += strShorty;
}
else{
strText = pItem->Caption.c_str();
}
ACanvas->TextRect( ARect, m_pPicSide->Width+8, yPos+6, strText ); //输出菜单文字
ACanvas->Font = oldFont;
}
}
void __fastcall TSystemMenu::OwnerMeasureItem(TObject* Sender, TCanvas* ACanvas, int &Width, int &Height)
{
TMenuItem *pItem = (TMenuItem*)Sender;
TFont *oldFont = ACanvas->Font;
ACanvas->Font = m_pFntText;
Width = ACanvas->TextWidth( pItem->Caption ) + 26;
ACanvas->Font = oldFont;
if( Width<SYSMENU_MINWIDTH )
Width = SYSMENU_MINWIDTH;
else if( Width>SYSMENU_MAXWIDTH )
Width = SYSMENU_MAXWIDTH;
if( pItem->IsLine() )
Height = BREAK_HEIGHT;
else{
Height = m_pPicSide->Height;
if( m_pPicTop && pItem->MenuIndex==0 ) //第一个菜单项
Height += m_pPicTop->Height;
TMenuItem * pItemParent = pItem->Parent;
if( m_pPicBottom && pItem->MenuIndex==pItemParent->Count-1) //最后一个菜单项
Height += m_pPicBottom->Height;
}
}
int TSystemMenu::GetMenuItemIndex( String strCaption )
{
int index = -1;
for( int i=0; i<Items->Count; i++ ){
if( Items->Items[i]->Caption.Compare(strCaption)==0 ){
index = i;
break;
}
}
return index;
}
TMenuItem* TSystemMenu::GetMainMenuItem( int index )
{
if( index>=0 && index<Items->Count ){
return Items->Items[index];
}
return NULL;
}
void TSystemMenu::DeleteSubMenu( int index )
{
if( index>=0 ){
for( int i=Items->Items[index]->Count-1; i>=0; i-- ){
Items->Items[index]->Delete(i);
}
}
}
void TSystemMenu::EnabledMenuItem(int index, bool bEnabled)
{
Items->Items[index]->Enabled = bEnabled;
}