Initial commit
This commit is contained in:
@@ -0,0 +1,527 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#include <vcl.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "BtnPanelUnit.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
VCTBtnPanel::iterator vc_pFindVCTBtnPanel;
|
||||
//---------------------------------------------------------------------------
|
||||
__fastcall TBtnPanel::TBtnPanel(TWinControl *pTWnCtl)
|
||||
: TComponent(pTWnCtl)
|
||||
{
|
||||
m_pTWnCtl = pTWnCtl;
|
||||
|
||||
m_pAppEvents = new TApplicationEvents(this);
|
||||
m_pAppEvents->OnMessage = OnAppEvents;
|
||||
|
||||
|
||||
m_bPalEn = false;
|
||||
m_bPalLD = false;
|
||||
m_bPalRD = false;
|
||||
|
||||
m_bBtnEn = m_bBtnLD = m_bBtnRD = false;
|
||||
m_pParentBtn = NULL;
|
||||
|
||||
FLeft = FTop = FWidth = FHeight = 0;
|
||||
FEnabled = true;
|
||||
FDown = false;
|
||||
FStateEnter = true;
|
||||
FStateCount = 3;
|
||||
FBtnCurState = Bs_NORMAL;
|
||||
FTransparent = false;
|
||||
FTransparentValue = 255;
|
||||
|
||||
m_BtnCurStateBac = Bs_NORMAL;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
__fastcall TBtnPanel::~TBtnPanel()
|
||||
{
|
||||
SAFE_DELETE(m_pAppEvents)
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TBtnPanel::IsPtInSubtn(int XPos, int YPos)
|
||||
{
|
||||
for(vc_pFindVCTBtnPanel =m_VCSubtn.begin();
|
||||
vc_pFindVCTBtnPanel!=m_VCSubtn.end();
|
||||
vc_pFindVCTBtnPanel++ )
|
||||
{
|
||||
TRect TRectTmpSubView
|
||||
= TRect((*vc_pFindVCTBtnPanel)->Left, (*vc_pFindVCTBtnPanel)->Top,
|
||||
(*vc_pFindVCTBtnPanel)->Left+(*vc_pFindVCTBtnPanel)->Width,
|
||||
(*vc_pFindVCTBtnPanel)->Top+(*vc_pFindVCTBtnPanel)->Height);
|
||||
if( PtInRect(TRectTmpSubView, TPoint(XPos, YPos) ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TBtnPanel::IsBtnHandleAppEvent(unsigned int message, int XPos, int YPos)
|
||||
{
|
||||
if( IsPtInSubtn(XPos, YPos) ) {
|
||||
|
||||
if( Bs_NORMAL==FBtnCurState )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::OnAppEvents(tagMSG &Msg, bool &Handled)
|
||||
{
|
||||
// -----
|
||||
if( false == FEnabled ||
|
||||
false == m_pTWnCtl->Enabled ||
|
||||
(false == m_bPalEn &&
|
||||
Msg.hwnd != m_pTWnCtl->Handle) )
|
||||
return;
|
||||
|
||||
if( WM_LBUTTONDOWN == Msg.message ||
|
||||
WM_LBUTTONUP == Msg.message ||
|
||||
WM_LBUTTONDBLCLK == Msg.message ||
|
||||
WM_RBUTTONDOWN == Msg.message ||
|
||||
WM_RBUTTONUP == Msg.message ||
|
||||
WM_MOUSEMOVE == Msg.message )
|
||||
{
|
||||
|
||||
}else return;
|
||||
|
||||
// -----
|
||||
TRect rtSelf = TRect(Left, Top, Left+Width, Top+Height);
|
||||
TPoint pt = m_pTWnCtl->ScreenToClient(TPoint(Msg.pt.x, Msg.pt.y));
|
||||
|
||||
TWMMouse Message;
|
||||
Message.Msg = Msg.message;
|
||||
Message.XPos = pt.x;
|
||||
Message.YPos = pt.y;
|
||||
|
||||
if( false==IsBtnHandleAppEvent(Message.Msg, Message.XPos, Message.YPos) ) return;
|
||||
|
||||
// -----
|
||||
MsState MsStatus = Ms_NONE;
|
||||
//刚离开区域
|
||||
if( m_bPalEn && !PtInRect( rtSelf, pt ) ) {
|
||||
|
||||
if( WM_MOUSEMOVE != Msg.message ) {
|
||||
|
||||
return;
|
||||
|
||||
}else if( WM_MOUSEMOVE==Msg.message ) {
|
||||
|
||||
m_bPalEn = false;
|
||||
MsStatus = Ms_LEAVE;
|
||||
BtnHandleAppEvent(MsStatus, Message.XPos, Message.YPos);
|
||||
|
||||
return;
|
||||
}
|
||||
//已经离开了区域
|
||||
} else if(!m_bPalEn && !PtInRect( rtSelf, pt ) ) {
|
||||
|
||||
if( m_bPalLD ) { //处理拖动事件
|
||||
MsStatus = Ms_DRAG;
|
||||
BtnHandleAppEvent(MsStatus, Message.XPos, Message.YPos);
|
||||
}
|
||||
|
||||
//除了 WM_LBUTTONUP WM_RBUTTONUP 都不再处理
|
||||
if((WM_LBUTTONUP != Msg.message && WM_RBUTTONUP != Msg.message) ||
|
||||
(false==m_bPalLD && WM_LBUTTONUP == Msg.message ) || //没有按下键 不再处理
|
||||
(false==m_bPalRD && WM_RBUTTONUP == Msg.message ) )
|
||||
return;
|
||||
}
|
||||
|
||||
// -----
|
||||
switch( Msg.message )
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
{
|
||||
MsStatus = Ms_LDOWN;
|
||||
m_bPalLD = true;
|
||||
|
||||
} break;
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
if( m_bPalLD ) {
|
||||
MsStatus = Ms_LUP;
|
||||
m_bPalLD = false;
|
||||
}
|
||||
|
||||
} break;
|
||||
case WM_LBUTTONDBLCLK:
|
||||
{
|
||||
MsStatus = Ms_LLDOWN;
|
||||
|
||||
} break;
|
||||
case WM_RBUTTONDOWN:
|
||||
{
|
||||
MsStatus = Ms_RDOWN;
|
||||
m_bPalRD = true;
|
||||
|
||||
} break;
|
||||
case WM_RBUTTONUP:
|
||||
{
|
||||
if(m_bPalRD) {
|
||||
|
||||
MsStatus = Ms_RUP;
|
||||
m_bPalRD = false;
|
||||
}
|
||||
|
||||
} break;
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if( m_bPalEn )
|
||||
{
|
||||
if(m_bPalLD)
|
||||
MsStatus = Ms_DRAG;
|
||||
else
|
||||
MsStatus = Ms_MOVE;
|
||||
|
||||
}else MsStatus = Ms_ENTER;
|
||||
|
||||
m_bPalEn = true;
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if(Ms_NONE!=MsStatus ) BtnHandleAppEvent(MsStatus, Message.XPos, Message.YPos);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::BtnHandleAppEvent(MsState MsSrcTmp, int XPos, int YPos)
|
||||
{
|
||||
MsState MsTmp = Ms_NONE;
|
||||
BtnState BsTmp = Bs_NONE;
|
||||
|
||||
switch( MsSrcTmp )
|
||||
{
|
||||
case Ms_LDOWN:
|
||||
{
|
||||
m_bBtnLD = true;
|
||||
BsTmp = Bs_DOWN;
|
||||
FBtnCurState = BsTmp;
|
||||
|
||||
MsTmp = Ms_LDOWN;
|
||||
|
||||
} break;
|
||||
case Ms_LLDOWN:
|
||||
{
|
||||
MsTmp = Ms_LLDOWN;
|
||||
|
||||
} break;
|
||||
case Ms_LUP:
|
||||
{
|
||||
m_bBtnLD = false;
|
||||
if( PtInRect( TRect(Left, Top, Left+Width, Top+Height),
|
||||
TPoint(XPos, YPos) ) )
|
||||
BsTmp = Bs_ENTER;
|
||||
else
|
||||
BsTmp = Bs_NORMAL;
|
||||
FBtnCurState = BsTmp;
|
||||
|
||||
MsTmp = Ms_LUP;
|
||||
|
||||
} break;
|
||||
case Ms_RDOWN:
|
||||
{
|
||||
MsTmp = Ms_RDOWN;
|
||||
|
||||
} break;
|
||||
case Ms_RUP:
|
||||
{
|
||||
MsTmp = Ms_RUP;
|
||||
|
||||
} break;
|
||||
case Ms_ENTER:
|
||||
{
|
||||
if( true!=m_bBtnLD ) {
|
||||
|
||||
m_bBtnEn = true;
|
||||
BsTmp = Bs_ENTER;
|
||||
FBtnCurState = BsTmp;
|
||||
|
||||
MsTmp = Ms_ENTER;
|
||||
}
|
||||
} break;
|
||||
case Ms_LEAVE:
|
||||
{
|
||||
if( true!=m_bBtnLD ) {
|
||||
|
||||
m_bBtnEn = false;
|
||||
BsTmp = Bs_NORMAL;
|
||||
FBtnCurState = BsTmp;
|
||||
|
||||
MsTmp = Ms_LEAVE;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Ms_MOVE:
|
||||
{
|
||||
if( m_bBtnEn ) {
|
||||
|
||||
bool bIsPtInSubtn = IsPtInSubtn(XPos, YPos);
|
||||
if( bIsPtInSubtn ) {
|
||||
|
||||
m_bBtnEn = false;
|
||||
BsTmp = Bs_NORMAL;
|
||||
FBtnCurState = BsTmp;
|
||||
|
||||
MsTmp = Ms_LEAVE;
|
||||
|
||||
}else {
|
||||
|
||||
MsTmp = Ms_MOVE;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
m_bBtnEn = true;
|
||||
BsTmp = Bs_ENTER;
|
||||
FBtnCurState = BsTmp;
|
||||
|
||||
MsTmp = Ms_ENTER;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Ms_DRAG:
|
||||
{
|
||||
MsTmp = Ms_DRAG;
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if( Ms_NONE != MsTmp ) BtnMsEvent(MsTmp, XPos, YPos);
|
||||
if( Bs_NONE != BsTmp ) BtnDrEvent(FBtnCurState, XPos, YPos);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::BtnHandleState()
|
||||
{
|
||||
BtnState BtnStateTmp = this->FBtnCurState;
|
||||
if( false==m_pTWnCtl->Enabled ||
|
||||
false==FEnabled ) {
|
||||
|
||||
BtnStateTmp = Bs_DISABLE;
|
||||
|
||||
}else {
|
||||
|
||||
if( false==FStateEnter && Bs_ENTER==this->FBtnCurState )
|
||||
BtnStateTmp = Bs_NORMAL;
|
||||
|
||||
if( FDown ) BtnStateTmp = Bs_DOWN;
|
||||
|
||||
if( FStateCount<=BtnStateTmp ) BtnStateTmp = FStateCount-1;
|
||||
}
|
||||
|
||||
m_BtnCurStateBac = FBtnCurState = BtnStateTmp;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::BtnDrEvent(BtnState BsTmp, int XPos, int YPos)
|
||||
{
|
||||
if( Bs_DOWN == BsTmp ||
|
||||
Bs_ENTER == BsTmp ||
|
||||
Bs_NORMAL == BsTmp )
|
||||
{
|
||||
int BtnCurStateBac = m_BtnCurStateBac;
|
||||
BtnHandleState();
|
||||
if( BtnCurStateBac==m_BtnCurStateBac ) return;
|
||||
|
||||
Paint();
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::BtnMsEvent(MsState MsTmp, int XPos, int YPos)
|
||||
{
|
||||
if( Ms_LDOWN == MsTmp ||
|
||||
Ms_LUP == MsTmp ||
|
||||
Ms_LLDOWN == MsTmp ||
|
||||
Ms_RDOWN == MsTmp ||
|
||||
Ms_RUP == MsTmp ||
|
||||
Ms_ENTER == MsTmp ||
|
||||
Ms_LEAVE == MsTmp ||
|
||||
Ms_MOVE == MsTmp ||
|
||||
Ms_DRAG == MsTmp )
|
||||
{
|
||||
if( OnPanelMsEvent ) OnPanelMsEvent(MsTmp, XPos, YPos);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::AddSubPanel(TBtnPanel *pTBtnPanel)
|
||||
{
|
||||
m_VCSubtn.push_back(pTBtnPanel);
|
||||
pTBtnPanel->m_pParentBtn = this;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::SetBounds(int nLeft, int nTop, int nWidth, int nHeight)
|
||||
{
|
||||
FLeft = nLeft;
|
||||
FTop = nTop;
|
||||
FWidth = nWidth;
|
||||
FHeight = nHeight;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::PaintParent(TCanvas *CanvasDrawCus)
|
||||
{
|
||||
if( this->m_pParentBtn ) {
|
||||
this->m_pParentBtn->Paint(CanvasDrawCus, false);
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::PaintSub(TCanvas *CanvasParent)
|
||||
{
|
||||
if( m_VCSubtn.size() ) {
|
||||
|
||||
for(vc_pFindVCTBtnPanel =m_VCSubtn.begin();
|
||||
vc_pFindVCTBtnPanel!=m_VCSubtn.end();
|
||||
vc_pFindVCTBtnPanel++ )
|
||||
{
|
||||
((TBtnPanel *)(*vc_pFindVCTBtnPanel))->Paint(CanvasParent, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::Paint(TCanvas *Canvas, bool bParent)
|
||||
{
|
||||
TCanvas *CanvasDraw = Canvas;
|
||||
|
||||
TRect rtThis = TRect(this->Left, this->Top,
|
||||
this->Left+this->Width,
|
||||
this->Top +this->Height);
|
||||
|
||||
TRect rtCreate = TRect(this->m_pTWnCtl->Left, this->m_pTWnCtl->Top,
|
||||
this->m_pTWnCtl->Left+this->m_pTWnCtl->Width,
|
||||
this->m_pTWnCtl->Top +this->m_pTWnCtl->Height);
|
||||
|
||||
//自身创建
|
||||
HDC ParentDC = GetDC(this->m_pTWnCtl->Handle);
|
||||
HDC DCCreate;
|
||||
HBITMAP BmpCreate;
|
||||
TCanvas *CanvasCreate;
|
||||
if( NULL==Canvas ) {
|
||||
|
||||
DCCreate = CreateCompatibleDC(ParentDC);
|
||||
BmpCreate = CreateCompatibleBitmap(ParentDC,
|
||||
rtCreate.Width(),
|
||||
rtCreate.Height());
|
||||
SelectObject(DCCreate, BmpCreate);
|
||||
PerformEraseBackground(this->m_pTWnCtl, DCCreate);
|
||||
CanvasCreate = new TCanvas();
|
||||
CanvasCreate->Handle = DCCreate;
|
||||
|
||||
CanvasDraw = CanvasCreate;
|
||||
if( FTransparent ) {
|
||||
SetBkMode( CanvasDraw->Handle, TRANSPARENT);
|
||||
StyleServices()->DrawParentBackground(
|
||||
this->m_pTWnCtl->Handle,
|
||||
CanvasDraw->Handle,
|
||||
NULL, false, rtThis);
|
||||
}
|
||||
}
|
||||
|
||||
//绘制
|
||||
if( FPanelDrEvent )
|
||||
{
|
||||
BtnHandleState();
|
||||
|
||||
//新建绘制
|
||||
TCanvas *CanvasCusDraw = new TCanvas();
|
||||
HDC DCCusDraw;
|
||||
HBITMAP BmpCusDraw;
|
||||
DCCusDraw = CreateCompatibleDC(ParentDC);
|
||||
BmpCusDraw = CreateCompatibleBitmap(ParentDC, rtCreate.Width(),
|
||||
rtCreate.Height());
|
||||
SelectObject(DCCusDraw, BmpCusDraw);
|
||||
PerformEraseBackground(this->m_pTWnCtl, DCCusDraw);
|
||||
CanvasCusDraw->Handle = DCCusDraw;
|
||||
|
||||
if( FTransparent ) {
|
||||
|
||||
SetBkMode( CanvasCusDraw->Handle, TRANSPARENT);
|
||||
StyleServices()->DrawParentBackground(
|
||||
this->m_pTWnCtl->Handle,
|
||||
CanvasCusDraw->Handle,
|
||||
NULL, false, rtThis);
|
||||
|
||||
//parent贴图到自身区域
|
||||
if( this->m_pParentBtn ) {
|
||||
|
||||
if( true==bParent ) {
|
||||
|
||||
if( NULL==Canvas ) PaintParent(CanvasDraw);
|
||||
}
|
||||
|
||||
StretchBlt(CanvasCusDraw->Handle,
|
||||
rtThis.Left, rtThis.Top,
|
||||
rtThis.Width(), rtThis.Height(),
|
||||
CanvasDraw->Handle,
|
||||
rtThis.Left, rtThis.Top,
|
||||
rtThis.Width(), rtThis.Height(),
|
||||
SRCCOPY);
|
||||
}
|
||||
}
|
||||
|
||||
FPanelDrEvent(FBtnCurState, rtThis, CanvasCusDraw);
|
||||
|
||||
if( FTransparent ) {
|
||||
|
||||
BLENDFUNCTION BFun;
|
||||
BFun.BlendOp = AC_SRC_OVER;
|
||||
BFun.BlendFlags = 0;
|
||||
BFun.SourceConstantAlpha = FTransparentValue;
|
||||
BFun.AlphaFormat = 0;
|
||||
|
||||
::AlphaBlend( CanvasDraw->Handle,
|
||||
rtThis.Left, rtThis.Top,
|
||||
rtThis.Width(), rtThis.Height(),
|
||||
CanvasCusDraw->Handle,
|
||||
rtThis.Left, rtThis.Top,
|
||||
rtThis.Width(), rtThis.Height(),
|
||||
BFun);
|
||||
|
||||
}else{
|
||||
|
||||
StretchBlt(CanvasDraw->Handle,
|
||||
rtThis.Left, rtThis.Top,
|
||||
rtThis.Width(), rtThis.Height(),
|
||||
CanvasCusDraw->Handle,
|
||||
rtThis.Left, rtThis.Top,
|
||||
rtThis.Width(), rtThis.Height(),
|
||||
SRCCOPY);
|
||||
}
|
||||
|
||||
if( true==bParent )
|
||||
PaintSub(CanvasDraw);
|
||||
|
||||
DeleteDC(DCCusDraw);
|
||||
DeleteObject(BmpCusDraw);
|
||||
SAFE_DELETE(CanvasCusDraw)
|
||||
}
|
||||
|
||||
if( NULL==Canvas ) {
|
||||
|
||||
StretchBlt(ParentDC,
|
||||
this->Left, this->Top,
|
||||
this->Width, this->Height,
|
||||
CanvasDraw->Handle,
|
||||
this->Left, this->Top,
|
||||
this->Width, this->Height,
|
||||
SRCCOPY);
|
||||
|
||||
DeleteDC(DCCreate);
|
||||
DeleteObject(BmpCreate);
|
||||
SAFE_DELETE(CanvasCreate)
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TBtnPanel::Update(bool bEreaseBkg)
|
||||
{
|
||||
if( m_pParentBtn && bEreaseBkg ) {
|
||||
|
||||
((TBtnPanel *)m_pParentBtn)->Update(bEreaseBkg);
|
||||
|
||||
}else {
|
||||
|
||||
Paint();
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user