Bewegung in PaintBox/OnPaint auslösen?

r_Alf

Mitglied
Hallo,

als relativer Neuling wollte ich mich darin üben etwas in die PaintBox zu zeichnen und diese Grafik in Richtung Mauszeiger bewegen wenn die Maustaste gedrückt und gehalten wird. Die Bewegung scheint soweit zu funktionieren, jedoch wird die PaintBox nicht nach jedem Bewegungsschritt aktualisiert, sondern nur nach dem verändern des Formulars.
Ausserdem Frage ich mich ob es nicht auch elegantere Lösungen für sowas gibt.

Hier mein Testcode (sollte ersichtlich sein wenns aktualisiert werden soll, im übrigen ist die Grafik ein Dreieck, was die Variablen besser verstehen lässt (auch wenns hier nicht wichtig ist)):

int SpitzeX = 15;
int SpitzeY = 50;
int LinksX = 30;
int LinksY = 1;
int RechtsX = 1;
int RechtsY = 1;

int *TempX = NULL;
int *TempY = NULL;

bool a = NULL;

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::paintBox1Paint(TObject *Sender)
{
PaintBox1->Canvas->MoveTo(SpitzeX,SpitzeY);
PaintBox1->Canvas->LineTo(LinksX,LinksY);
PaintBox1->Canvas->LineTo(RechtsX,RechtsY);
PaintBox1->Canvas->LineTo(SpitzeX,SpitzeY);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::paintBox1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
a = true; // "maustaste gedrückt"-status speichern
TempX = &X;
TempY = &Y;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::paintBox1Click(TObject *Sender)
{
a = false; // maustaste wird losgelassen
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{

if (a) // nur wenn maustaste gedrückt
{
if (1) // zum testen erstmal ohne bedingung
{
SpitzeX = *TempX-SpitzeX-1;
LinksX = *TempX-LinksX-1;
RechtsX = *TempX-RechtsX-1;
}
// Paint(); löst hier kein OnPaint für die PaintBox aus, was nun ? <------
}

}
//---------------------------------------------------------------------------
void __fastcall TForm1::paintBox1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{

if (a) // nur wenn maustaste gedrückt
{
TempX = &X;
TempY = &Y;
}

}
//--------------------------------------------------------------------------

vielen Dank im Vorraus und btw., kann ich im Post die Leerzeichen irgendwie erhalten, ist deshalb bissl unübersichtlich :confused:

Hab "Repaint()" gefunden, womit sich die Sache erledigt hat. Mittlerweile weiss ich auch das der Code ziemlich schrottich ist :/
 
Zuletzt bearbeitet:

Krypthonas

Erfahrenes Mitglied
r_Alf hat gesagt.:
Hab "Repaint()" gefunden, womit sich die Sache erledigt hat. Mittlerweile weiss ich auch das der Code ziemlich schrottich ist :/

Es ist der sogenannte Lerneffekt. Es ist doch am Anfang egal wie "schrottig" der Code ist, sondern es geht um das Verstehen einer Sache. Wenn du das Bearbeiten von Metallen lernst, machst du auch nicht als erstes ein Topbearbeitung sondern lernst erstmal den Umgang mit diesen.

So ist es auch hier ;)
Also, nur weiter so!
 

TheBadDwarf

Mitglied
Hallo,

ich denke für den Anfang solltest Du die globalen Variablen für die Speicherung der Mausposition nicht als Pointer deklarieren, da es ja sein kann, das die Variablen der Mauspositionen in den aufgerufenen Funktionen nur lokal gültig sind. Sprich: bei MouseMove speicherst Du nicht den Wert der Variable X und Y, sondern nur die Adresse. Nachdem die Funktion verlassen wird, kann es sein, dass der reservierte Speicher innerhalb der Funktion für X und Y wieder freigegeben wird. Hast Du nicht schonmal eine Fehlermeldung erhalten wegen Zugriff auf nicht reservierten Speicher? Ich würde Dir als Anfänger zunächst mal raten, die globalen Variablen ebenfalls als int zu deklarieren.
Dein Ziel habe ich allerdings nicht ganz verstanden: Soll der Benutzer die Grafik mit der Maus verschieben können, indem er die die linke Maustaste gedrückt hält und dabei die Maus bewegt (sowie Drag&Drop) oder soll die Grafik dem Mauszeiger einfach nur "hinterher laufen"? Für beide Fälle benötigst Du eigentlich keinen Timer, sondern aktualisierst immer nur bei OnMouseMove. Du lässt dann die neue Position berechnen und aktualisierst die Paintbox (OnPaint).
Also: MouseMove: neue Position berechnen und zeichnen. Danach Paintbox->OnPaint auslösen.
So sollte das funktionieren ...

MfG
TheBadDwarf

PS: Viel Spaß noch und immer daran denken: Es ist noch kein Meister vom Himmel gefallen