Я пытаюсь создать новый компонент из TPaintBox. Размер нового компонента — Rect (0,0,160,248). Я нарисовал два прямоугольника на новом компоненте, и я хотел бы реализовать события для каждого из вышеупомянутого прямоугольника.
Получить прямоугольник расположен в Rect (102,43,157,63), и я хотел бы реализовать события, такие как OnGetClick, OnGetMouseDown, OnGetMouseUp для этой области прямоугольника.
Установить прямоугольник находится по адресу Rect (102,69,157,89), и я хотел бы реализовать события, такие как OnSetClick, OnSetMouseDown, OnSetMouseUp для этой области прямоугольника.
Остальная часть новой области компонента будет отображать значения, связанные с VGauge, и я не включен в приведенный ниже код.
class PACKAGE TVGauge : public TPaintBox
{
public:
virtual void __fastcall Paint(void) ;
};
void __fastcall TVGauge::Paint(void)
{
int ind1, ind2 ;
TRect tempR ;
String str;
Canvas->Font->Size = 8 ;
//whole rect
Canvas->Pen->Color = clSilver ;
Canvas->Brush->Color = clBtnFace ;
Canvas->Rectangle(ClientRect) ; //Rect(0,0,160,248)
//----------
Canvas->Pen->Color = clMedGray ;
Canvas->Font->Color = clWindowText ;
Canvas->Brush->Color = clWhite ;
//Get Button ; draw a rectangle and it should act like a button
Canvas->Rectangle(102 , 43 , 157 , 63 ) ;
Canvas->TextOut(112, 48 ,L"Get");
//Set Button ; draw a rectangle and it should act like a button
Canvas->Rectangle(102 , 69 , 157 , 89 ) ;
Canvas->TextOut(112, 74 ,L"Set");
//display values related to the VGauge
//..
//..
if(OnPaint != NULL) OnPaint(this) ;
}
Я понятия не имею, как реализовать вышеуказанные события для нового компонента. Итак, я надеюсь получить предложения по реализации этого компонента.
Переопределить виртуальный MouseDown()
а также MouseUp()
методы, например:
enum TVGaugeButton { tvgGetBtn, tvgSetBtn };
typedef void __fastcall (__closure *TVGaugeMouseEvent)(TObject *Sender, TVGaugeButton GaugeButton, TMouseButton MouseButton, TShiftState Shift, int X, int Y);
typedef void __fastcall (__closure *TVGaugeClickEvent)(TObject *Sender, TVGaugeButton GaugeButton);
class PACKAGE TVGauge : public TPaintBox
{
typedef TPaintBox inherited;
private:
bool FMouseDown[2];
TVGaugeMouseEvent FOnGaugeButtonMouseDown;
TVGaugeMouseEvent FOnGaugeButtonMouseUp;
TVGaugeClickEvent FOnGaugeButtonClick;
TRect __fastcall GetButtonRect(TVGaugeButton WhichButton);
protected:
DYNAMIC void __fastcall MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y);
DYNAMIC void __fastcall MouseUp(TMouseButton Button, TShiftState Shift, int X, int Y);
virtual void __fastcall Paint();
public:
__fastcall TVGauge(TComponent *Owner);
virtual void __fastcall SetBounds(int ALeft, int ATop, int AWidth, int AHeight);
__published:
__property TVGaugeClickEvent OnGaugeButtonClick = {read=FOnGaugeButtonClick, write=FOnGaugeButtonClick};
__property TVGaugeMouseEvent OnGaugeButtonMouseDown ={read=FOnGaugeButtonMouseDown, write=FOnGaugeButtonMouseDown};
__property TVGaugeMouseEvent OnGaugeButtonMouseUp = {read=FOnGaugeButtonMouseUp, write=FOnGaugeButtonMouseUp};
};
__fastcall TVGauge::TVGauge(TComponent *Owner)
: TPaintBox(Owner)
{
}
void __fastcall TVGauge::SetBounds(int ALeft, int ATop, int AWidth, int AHeight)
{
inherited::SetBounds(ALeft, ATop, 160, 248);
}
TRect __fastcall TVGauge::GetButtonRect(TVGaugeButton WhichButton)
{
switch (WhichButton)
{
case tvgGetBtn:
return Rect(102, 43, 157, 63);
case tvgSetBtn:
return Rect(102, 69, 157, 89);
}
return Rect(0, 0, 0, 0);
}
void __fastcall TVGauge::MouseDown(TMouseButton Button, TShiftState Shift, int X, int Y)
{
inherited::MouseDown(Button, Shift, X, Y);
for (int i = tvgGetBtn; i <= tvgSetBtn; ++i)
{
TVGaugeButton myBtn = (TVGaugeButton) i;
TRect r = GetButtonRect(myBtn);
if (PtInRect(&r, Point(X, Y)))
{
if (Button == mbLeft)
FMouseDown[i] = true;
if (FOnGaugeButtonMouseDown)
FOnGaugeButtonMouseDown(this, myBtn, Button, Shift, X-r.Left, Y-r.Top);
break;
}
}
}
void __fastcall TVGauge::MouseUp(TMouseButton Button, TShiftState Shift, int X, int Y)
{
inherited::MouseDown(Button, Shift, X, Y);
for (int i = tvgGetBtn; i <= tvgSetBtn; ++i)
{
TVGaugeButton myBtn = (TVGaugeButton) i;
TRect r = GetButtonRect(myBtn);
if (PtInRect(&r, Point(X, Y)))
{
bool bClicked = false;
if (Button == mbLeft)
{
FMouseDown[i] = false;
bClicked = true;
}
if (FOnGaugeButtonMouseUp)
FOnGaugeButtonMouseUp(this, myBtn, Button, Shift, X-r.Left, Y-r.Top);
if ((bClicked) && (FOnGaugeButtonClick))
FOnGaugeButtonClick(this, myBtn);
break;
}
}
}
void __fastcall TVGauge::Paint()
{
TRect tempR;
Canvas->Font->Size = 8;
//whole rect
Canvas->Pen->Color = clSilver;
Canvas->Brush->Color = clBtnFace;
Canvas->Rectangle(ClientRect);
//----------
Canvas->Pen->Color = clMedGray;
Canvas->Font->Color = clWindowText;
Canvas->Brush->Color = clWhite;
//Get Button ; draw a rectangle and it should act like a button
tempR = GetButtonRect(tvgGetBtn);
Canvas->Rectangle(tempR);
Canvas->TextRect(tempR, tempR.Left + 10, tempR.Top + 5, _D("Get"));
//Set Button ; draw a rectangle and it should act like a button
tempR = GetButtonRect(tvgSetBtn);
Canvas->Rectangle(tempR);
Canvas->TextRect(tempR, tempR.Left + 10, tempR.Top + 5, _D("Set"));
//display values related to the VGauge
//..
//..
if (OnPaint)
OnPaint(this);
}
Кстати, вы действительно должны извлечь свой компонент из TGraphicControl
прямо вместо TPaintBox
, только разница между TPaintBox
а также TGraphicControl
в том, что TPaintBox
подвергает OnPaint
событие, где оно переопределяет Paint()
для запуска OnPaint
, Вам не нужно OnPaint
событие в вашем компоненте вообще, так как вы делаете все свои собственные рисунки (если вы действительно не хотите, чтобы пользователи рисовали поверх нашей картины).
Других решений пока нет …