Files
AC_Pro/Component/SkinTrackBar/SkinTrackBar.cpp
T
2026-06-13 00:05:19 +08:00

468 lines
10 KiB
C++

//---------------------------------------------------------------------------
#pragma hdrstop
#include "SkinTrackBar.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#define trHorizontal 1 //横向滑块
#define trVertical 0 //纵向滑块
#define SLIDER_MAX_H 25 //滑块长度
#define SLIDER_MIN_H 10
#define SLIDER_W 10 //滑块宽度
#define PANEL_MIN_W 30 //Panel最小宽度
#define CHANNEL_LEFT 5
#define CHANNEL_W 2 //滑槽宽度
static const COLORREF
CLR_BACK_ENABLE = RGB(22,33,44), //d5dde8
CLR_BACK_DISABLE = RGB(112,130,154), //d5dde8
CLR_SLIDER_DOWN = RGB(77,88,99), //d5dde8
CLR_SLIDER_HOVER = RGB(55,66,77), //d5dde8
CLR_SLIDER_NORMAL = RGB(44,55,77); //d5dde8
static inline void ValidCtrCheck(TSkinTrackBar *)
{
new TSkinTrackBar(NULL);
}
namespace Skintrackbar
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TSkinTrackBar)};
RegisterComponents(L"Samples", classes, 0);
}
}
__fastcall TSkinTrackBar::TSkinTrackBar(System::Classes::TComponent* AOwner)
: TPanel(AOwner)
{
bDown = false;
bMouse = false;
FEnabled = true;
FOrientation = 1; //默认横向滑块
FMax = 100;
FMin = 0;
FPosition = 0;
FPageSize = 1;
Hint = IntToStr(FPosition);
ParentBackground = true;
Slider = new TPaintBox(this);
Slider->Parent = this;
Slider->ParentShowHint = false;
Slider->ShowHint = false;
Slider->OnMouseEnter = CMMouseEnter;
Slider->OnMouseLeave = CMMouseLeave;
Slider->OnMouseDown = CMMouseDown;
Slider->OnPaint = SliderPaint;
ParentColor = true;
}
//-----------------------------------------------------------------------------
__fastcall TSkinTrackBar::~TSkinTrackBar()
{
delete Slider;
Slider = NULL;
}
void __fastcall TSkinTrackBar::SetMax(int Value)
{
if(Value <= FMin)
{
// if(ComponentState.Contains(csDesigning))
// {
// MessageBox(Handle, "Max:必须大于Min!!!", "错误", MB_OK | MB_ICONERROR);
// }
}
else
{
if(FMax != Value)
{
FMax = Value;
if(FPosition > FMax){
FPosition = FMax;
if(FOnChange)
FOnChange(this);
}
if( FOrientation ){
Slider->Left = CHANNEL_LEFT+(double)(FPosition-FMin)*(Width-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin);
}
else{
Slider->Top = Height-CHANNEL_LEFT-(double)(FPosition-FMin)*(Height-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin)-SLIDER_W;
}
}
}
}
void __fastcall TSkinTrackBar::SetMin(int Value)
{
if(Value >= FMax)
{
// if(ComponentState.Contains(csDesigning))
// {
// MessageBox(Handle, "Min:必须小于Max!!!", "错误", MB_OK | MB_ICONERROR);
// }
}
else
{
if(FMin != Value)
{
FMin = Value;
if(FPosition < FMin){
FPosition = FMin;
if(FOnChange)
FOnChange(this);
}
if( FOrientation ){
Slider->Left = CHANNEL_LEFT+(double)(FPosition-FMin)*(Width-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin);
}
else{
Slider->Top = Height-CHANNEL_LEFT-(double)(FPosition-FMin)*(Height-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin)-SLIDER_W;
}
}
}
}
void __fastcall TSkinTrackBar::SetPosition(int iPosition)
{
if(iPosition>FMax)
iPosition = FMax;
if(iPosition<FMin)
iPosition = FMin;
if(FPosition!=iPosition){
FPosition = iPosition;
Hint = IntToStr(FPosition);
if( FOrientation ){
Slider->Left = CHANNEL_LEFT+(double)(FPosition-FMin)*(Width-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin);
}
else{
Slider->Top = Height-CHANNEL_LEFT-(double)(FPosition-FMin)*(Height-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin)-SLIDER_W;
}
if(FOnChange)
FOnChange(this);
Invalidate();
// Slider->Invalidate();
}
}
void __fastcall TSkinTrackBar::SetOrientation(bool bOrientation)
{
if(FOrientation != bOrientation)
{
FOrientation = bOrientation;
TWMSize msg;
WMSize(msg);
Invalidate();
// Slider->Invalidate();
}
}
void __fastcall TSkinTrackBar::SetEnabled(bool bEnabled)
{
if( FEnabled!=bEnabled ){
FEnabled = bEnabled;
Invalidate();
}
}
void __fastcall TSkinTrackBar::CMMouseEnter(System::TObject* Sender)
{
if( FEnabled ){
bMouse = true;
Slider->Invalidate();
}
}
void __fastcall TSkinTrackBar::CMMouseLeave(System::TObject* Sender)
{
if( FEnabled ){
bMouse = false;
Slider->Invalidate();
}
}
void __fastcall TSkinTrackBar::CMMouseDown(System::TObject* Sender, System::Uitypes::TMouseButton Button,
System::Classes::TShiftState Shift, int X, int Y)
{
if( FEnabled && Button==mbLeft ){
bDown = true;
MouseCapture = true;
Slider->Invalidate();
SetFocus();
}
}
void __fastcall TSkinTrackBar::WMMouseMove(TWMMouse &Message)
{
if( FEnabled && bDown ){
if( FOrientation ){ // trHorizontal 1 //横向滑块
DrawH(Message);
}
else{
DrawV(Message);
}
}
TPanel::Dispatch(&Message);
}
void __fastcall TSkinTrackBar::WMLButtonDown(TWMLButtonDown &Message)
{
if( FEnabled ){
if( FOrientation && Message.YPos>Slider->Top
&& Message.YPos<Slider->Top+Slider->Height
&& Message.XPos>0 && Message.XPos<Width){
//横向
DrawH(Message);
bDown = true;
MouseCapture = true;
}
else if( !FOrientation && Message.XPos>Slider->Left
&& Message.XPos<Slider->Left + Slider->Width
&& Message.YPos>0 && Message.YPos<Height){
//纵向
DrawV(Message);
bDown = true;
MouseCapture = true;
}
SetFocus();
}
TPanel::Dispatch(&Message);
}
void __fastcall TSkinTrackBar::WMLButtonUp(TWMLButtonUp &Message)
{
if( FEnabled ){
bDown = false;
bMouse = false;
MouseCapture = false;
Slider->Invalidate();
}
TPanel::Dispatch(&Message);
}
void __fastcall TSkinTrackBar::WMMouseWheel(TWMMouseWheel &Message)
{
if( FEnabled ){
int iPos = FPosition;
if( Message.WheelDelta>0 ){
iPos += FPageSize;
if( iPos>FMax )
iPos = FMax;
}
else{
iPos -= FPageSize;
if( iPos<FMin )
iPos = FMin;
}
Position = iPos;
}
}
void __fastcall TSkinTrackBar::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
TPanel::Dispatch(&Message);
TRect Channel;
if( Orientation )
Channel.init( CHANNEL_LEFT,
Height/2-CHANNEL_W,
Width-CHANNEL_LEFT,
Height/2+CHANNEL_W);
else
Channel.init(
Width/2-CHANNEL_W,
CHANNEL_LEFT,
Width/2+CHANNEL_W,
Height-CHANNEL_LEFT
);
TCanvas* tempCanvas = new TCanvas;
tempCanvas->Handle = Message.DC;
if( Enabled ){
tempCanvas->Brush->Color = CLR_BACK_ENABLE;
tempCanvas->FillRect(Channel);
}
else{
tempCanvas->Brush->Color = CLR_BACK_DISABLE;
tempCanvas->FillRect(Channel);
}
delete tempCanvas;
}
void __fastcall TSkinTrackBar::SliderPaint(System::TObject* Sender)
{
TRect rect = Slider->ClientRect;
if ( !FEnabled ) {
Slider->Canvas->Brush->Color = CLR_BACK_DISABLE;
Slider->Canvas->FillRect(rect);
// TRect rct(rect);
// Frame3D( Slider->Canvas, rect, clBlack,clGray,1 );
// rect = rct;
}
else if(bDown){//鼠标按下
Slider->Canvas->Brush->Color = CLR_SLIDER_DOWN;
Slider->Canvas->FillRect(rect);
// TRect rct(rect);
Frame3D( Slider->Canvas, rect, clBlack,clGray,1 );
// rect = rct;
}
else if(bMouse){//鼠标移动到滑块上
Slider->Canvas->Brush->Color = CLR_SLIDER_HOVER;
Slider->Canvas->FillRect(rect);
// TRect rct(rect);
Frame3D( Slider->Canvas, rect, clGray,clBlack, 1 );
// rect = rct;
}
else{ //平常
Slider->Canvas->Brush->Color = CLR_SLIDER_NORMAL;
Slider->Canvas->FillRect(rect);
// TRect rct(rect);
Frame3D( Slider->Canvas, rect, clGray,clBlack, 1 );
// rect = rct;
}
}
void __fastcall TSkinTrackBar::DrawH(TWMMouse &Message) // 横向
{
int oldPosition = FPosition;
if(Message.XPos<CHANNEL_LEFT+SLIDER_W/2){
if(Slider->Left==CHANNEL_LEFT)
return;
Slider->Left = CHANNEL_LEFT;
FPosition = FMin;
}
else if(Message.XPos>Width-CHANNEL_LEFT-SLIDER_W/2){
if(Slider->Left==Width-CHANNEL_LEFT - SLIDER_W)
return;
Slider->Left = Width-CHANNEL_LEFT - SLIDER_W;
FPosition = FMax;
}
else{
FPosition = FMin+(double)(Message.XPos - CHANNEL_LEFT - SLIDER_W/2)/(Width-2*CHANNEL_LEFT-SLIDER_W)*(FMax-FMin) +0.5;
Slider->Left = CHANNEL_LEFT+(double)(FPosition-FMin)*(Width-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin);
}
Hint = IntToStr(FPosition);
if( oldPosition!=FPosition && FOnChange )
FOnChange(this);
}
void __fastcall TSkinTrackBar::DrawV(TWMMouse &Message)
{
int oldPosition = FPosition;
if(Message.YPos<CHANNEL_LEFT+SLIDER_W/2){
if(Slider->Top==CHANNEL_LEFT)
return;
Slider->Top = CHANNEL_LEFT;
FPosition = FMax;
}
else if(Message.YPos>Height-CHANNEL_LEFT-SLIDER_W/2){
if(Slider->Top==Height-CHANNEL_LEFT - SLIDER_W)
return;
Slider->Top = Height-CHANNEL_LEFT - SLIDER_W;
FPosition = FMin;
}
else{
FPosition = FMax-(double)(Message.YPos - CHANNEL_LEFT - SLIDER_W/2)/(Height-2*CHANNEL_LEFT-SLIDER_W)*(FMax-FMin);
Slider->Top = Height-CHANNEL_LEFT-(double)(FPosition-FMin)*(Height-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin)-SLIDER_W;
}
if( oldPosition!=FPosition && FOnChange )
FOnChange(this);
}
void __fastcall TSkinTrackBar::WMSize(TWMSize &Message)
{
if(FOrientation){
//确定横向滑块区域
if( Width<PANEL_MIN_W )
Width = PANEL_MIN_W; //20
if( Height<SLIDER_MIN_H )
Height = SLIDER_MIN_H;
if( Height>=SLIDER_MAX_H ){
Slider->Left = CHANNEL_LEFT+(double)(FPosition-FMin)* (Width-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin);
Slider->Top = Height/2-SLIDER_MAX_H/2;
Slider->Width = SLIDER_W;
Slider->Height = SLIDER_MAX_H;
}
else{
Slider->Left = CHANNEL_LEFT+(double)(FPosition-FMin)*(Width-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin);
Slider->Top = 1;
Slider->Width = SLIDER_W;
Slider->Height = Height-2;
}
}
else
{
//确定纵向滑块区域
if( Height<PANEL_MIN_W )
Height = PANEL_MIN_W; //20
if( Width<SLIDER_MIN_H )
Width = SLIDER_MIN_H;
if( Width>=SLIDER_MAX_H ){
Slider->Left = Width/2-SLIDER_MAX_H/2;
Slider->Top = Height-CHANNEL_LEFT-(double)(FPosition-FMin)*(Height-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin)-SLIDER_W;
Slider->Width = SLIDER_MAX_H;
Slider->Height = SLIDER_W;
}
else{
Slider->Left = 1;
Slider->Top = Height-CHANNEL_LEFT-(double)(FPosition-FMin)*(Height-2*CHANNEL_LEFT-SLIDER_W)/(FMax-FMin)-SLIDER_W;
Slider->Width = Width-2;
Slider->Height = SLIDER_W;
}
}
}