// Lösungen zu "Richard Kaiser: C++ mit dem Borland C++Builder 2007", ISBN: 978-3-540-69575-2
// Copyright Richard Kaiser, 2007. http://www.rkaiser.de. All rights reserved.
// Diese Quelltexte dürfen in eigenen Programmen verwendet werden, wenn sie einen Hinweis auf die Quelle (die ersten beiden Zeilen) enthalten. In keinem Fall wird eine Haftung für direkte, indirekte, zufällige oder Folgeschäden übernommen, die sich aus der Nutzung ergeben.
// It is permitted to use this source text in programs of your own, provided that it contains a reference to the source (the first two lines above). All liabilities for use of the code are disclaimed.

// --------------- Aufgabe 4: TTabEdit ---------------------

__fastcall TTabEdit::TTabEdit(TComponent* Owner)
        : TEdit(Owner)
{
}

_fastcall TTabEdit::TTabEdit(TComponent* AOwner,TWinControl* Parent_,int Left_, int Top_, int Width_, int Height_):TEdit(AOwner)
{
Parent=Parent_;
SetBounds(Left_,Top_,Width_,Height_);
}

 __fastcall TTabEdit::TTabEdit(TComponent* AOwner, int Left_, int Top_, int Width_, int Height_):TEdit(AOwner)
{
// Falls Owner und Parent gleich sind (z.B. beide Form1), ist
// dieser Konstruktor auf den ersten Blick einfacher, da man nur
// eine Argument angeben muss, und nicht zwei wie beim letzten
// Konstruktor. Aber damit ist es nicht möglich, Owner und Parent
// verschieden zu setzen.
Parent=(TWinControl*)AOwner;
SetBounds(Left_,Top_,Width_,Height_);
};

void __fastcall TTabEdit::WMNextDlgCtl(TWMChar& Msg)
{
if (Msg.CharCode == 13)
  SendMessage(((TForm*)Owner)->Handle,WM_NEXTDLGCTL,0,0);
else
  inherited::Dispatch(&Msg);
};


// --------------- Aufgabe 5: TFocusColorEdit --------------

__fastcall TFocusColorEdit::TFocusColorEdit(TComponent* AOwner):TEdit(AOwner)
{
OnEnter=MyOnEnter;
OnExit=MyOnExit;
}

__fastcall TFocusColorEdit::TFocusColorEdit(TComponent* AOwner,TWinControl* Parent_,int Left_, int Top_, int Width_, int Height_):TEdit(AOwner)
{
Parent=Parent_;
Visible=true;
SetBounds(Left_,Top_,Width_,Height_);
OnEnter=MyOnEnter;
OnExit=MyOnExit;
}


void __fastcall TFocusColorEdit::SetFocusColor(TColor C)
{
FFocusColor = C;
}

#if TFocusColorEdit_Variant
void __fastcall TFocusColorEdit::WMSetFocus(TWMSetFocus& Msg)
{
prevColor = Color;
FFocusColor = clYellow;
Color = FFocusColor;
inherited::Dispatch(&Msg);
}

void __fastcall TFocusColorEdit::WMKillFocus(TWMKillFocus& Msg)
{
Color = prevColor;
inherited::Dispatch(&Msg);
}
#endif


// --------------- Aufgabe 6: TResizableMemo ---------------

__fastcall TResizableMemo::TResizableMemo(TComponent* AOwner):TMemo(AOwner)
{
}

__fastcall TResizableMemo::TResizableMemo(TComponent* AOwner,TWinControl* Parent_,
              int Left_, int Top_, int Width_, int Height_):TMemo(AOwner)
{
Parent=Parent_;
//Parent=(TWinControl*)AOwner;
SetBounds(Left_,Top_,Width_,Height_);
}

void __fastcall TResizableMemo::WMLButtonDown(TWMMouseMove& Msg)
{
LB_Down = true;
Cursor = crHSplit;
// TMemo::WMLButtonDown(Msg); // Zugriff nicht möglich
TMemo::Dispatch(&Msg); // wie inherited::Dispatch(&Msg);
}

void __fastcall TResizableMemo::WMLButtonUp(TWMMouseMove& Msg)
{
LB_Down = false;
Cursor = crDefault;
inherited::Dispatch(&Msg);
}

void __fastcall TResizableMemo::WMMouseMove(TWMMouseMove& Msg)
{
if (LB_Down) Width = Msg.XPos;
inherited::Dispatch(&Msg);
}


// --------------- Aufgabe 7: TRubberShape -----------------

__fastcall TRubberShape::TRubberShape(TComponent* AOwner,TWinControl* Parent_,
      int Left_, int Top_, int Width_, int Height_):TImage(AOwner)
 {
  Parent=Parent_;
  SetBounds(Left_,Top_,Width_,Height_);
 }

__fastcall TRubberShape::TRubberShape(TComponent* AOwner):TImage(AOwner)
 {
 }

void __fastcall TRubberShape::WMLButtonDown(TWMMouseMove& Msg)
{
LB_Down = true;
x_Start = Msg.Pos.x;
y_Start = Msg.Pos.y;
x = x_Start;
y = y_Start;
r = 0;
Canvas->Pen->Mode = pmNot;
Cursor = crHSplit;
inherited::Dispatch(&Msg);
}

void __fastcall TRubberShape::WMLButtonUp(TWMMouseMove& Msg)
{
LB_Down = false;
Cursor = crDefault;
Canvas->Pen->Mode = pmBlack;
inherited::Dispatch(&Msg);
}

void __fastcall TRubberShape::RectLine(int x1,int y1,int x2,int y2)
{
TPoint p[5]={Point(x1,y1),Point(x2,y1),
                     Point(x2,y2),Point(x1,y2),Point(x1,y1)};
Canvas->Polyline(p,5);
}

void __fastcall TRubberShape::CircLine(int x,int y, int r)
{
Canvas->Arc(x-r,y-r,x+r,y+r,0,0,0,0);
}

int round (double x)
{
return x+0.5;
}

#include <cmath>
using namespace std;

void __fastcall TRubberShape::WMMouseMove(TWMMouseMove& Msg)
{
if (LB_Down)
  {
    Canvas->MoveTo(x_Start,y_Start);
    switch (rsShape)
    {
      case rsLine: Canvas->LineTo(x,y);
        break;
      case rsRectangle: RectLine(x_Start,y_Start,x,y);
        break;
      case rsCircle: CircLine(x_Start,y_Start,r);
        break;
    };
    x = Msg.Pos.x;
    y = Msg.Pos.y;
    r = round(sqrt((x-x_Start)*(x-x_Start)+(y-y_Start)*(y-y_Start)));
    Canvas->MoveTo(x_Start,y_Start);
    switch (rsShape)
    {
      case rsLine: Canvas->LineTo(x,y);
        break;
      case rsRectangle: RectLine(x_Start,y_Start,x,y);
        break;
      case rsCircle: CircLine(x_Start,y_Start,r);
        break;
    };
  }
inherited::Dispatch(&Msg);
}

void __fastcall TRubberShape::WMRButtonDblClick(TWMLButtonDown& Msg)
{
AnsiString s;
// if (rsShape < High(rsShape)) rsShape++;
if (rsShape < High) rsShape=rsShape+1;
else rsShape = Low;
// else rsShape = low(rsShape);
if (rsShape==rsLine) s = "Line";
else if (rsShape==rsRectangle) s = "Rect";
else if (rsShape==rsCircle)  s = "Circ";
else s = "Undef";
Canvas->TextOut(0,0,s);
}

