Hallo,
ich habe ein Problem mit Zeichnen auf dem Canvas und scrollen: in einer Paintbox, die in einer Scrollbox eingebettet ist, will ich einen bestimmen Bereich mit der Maus selektieren. Dabei soll der aktuelle Bereich immer mittels eines Rahmens angezeigt werden. Das funktioniert auch ganz gut, solange man nicht über die Ränder der Scrollbox kommt. Dann soll nämlich automatisch gescrollt werden. Tut das Programm auch, aber dabei bleiben jetzt Teile des Selektionsrahmens stehen.
Im Anhang ist eine Demoversion, die das Problem zeigt.
hier mal der wichtigste Code:
Delphi-Quellcode:
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FActive := True;
FStartPoint := Point(x,y);
FEndPoint := FStartPoint;
// Zeichenmode Selektionsrahmen setzen
PaintBox1.Canvas.Pen.Style := psDashDot;
PaintBox1.Canvas.Pen.Mode := pmNotXor;
PaintBox1.Canvas.Brush.Style := bsClear;
end;
procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if FActive then
begin
// alter Rahmen zum Löschen erneut zeichnen
PaintBox1.Canvas.Rectangle(rect(FStartPoint, FEndPoint));
// neuer Endpunkt
FEndPoint := Point(X,Y);
// neuer Rahmen
PaintBox1.Canvas.Rectangle(rect(FStartPoint, FEndPoint));
// vertikales scrollen
if (Y > ScrollBox1.VertScrollBar.Position + ScrollBox1.ClientHeight) then
ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position + 4;
if (Y < ScrollBox1.VertScrollBar.Position) then
ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position - 4;
// Horizontales scrollen
if (X > ScrollBox1.HorzScrollBar.Position + ScrollBox1.ClientWidth) then
ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position + 4;
if (X < ScrollBox1.HorzScrollBar.Position) then
ScrollBox1.HorzScrollBar.Position := ScrollBox1.HorzScrollBar.Position - 4;
end;
end;
Hat jemand eine Idee, wie man das umgehen kann? Ich hab es schon damit versucht, das Zeichnen des Selektionsrahmens in den OnPaint der Paintbox zu verschieben und im MouseMove nur ein Invalidate der Paintbox aufzurufen. Das geht zwar dann, ist aber leider für die echte Anwendung nicht möglich, da hier das Zeichnen sehr zeitintensiv ist und durch das dann erfolgende häufige Zeichnen die Anwendung de facto nicht mehr zu bedienen ist.
vielen Dank,
Uli