Ich hole mal ein bisschen aus um das Drumherum zu erklären:
Ich habe für den Töpferofen meiner Gattin eine Steuerung gebaut (AVR µC) welche die benötigten Temperaturkurven abfährt. Die jeweils aktuellen Mess- und Vorgabewerte werden sekündlich via RS232/BT rausgehauen und zunächst mittels einer kleinen Applikation auf meinem Laptop empfangen und in Textdateien geschrieben (jeweils eine für Ist-Temperatur, Soll-Temperatur, Schaltzustand des Steuerrelais, aktuelle Brennphase).
Das alles funzt prima, keine Probleme. Die Dateien umfassen dabei gut 30.000 Messwerte (so ein Brennvorgang dauert mehrere Stunden).
Ein weiteres Tool soll diese Daten dann später einlesen und grafisch darstellen, und da klemmt es.
Auf der Form liegt eine Scrollbox in Bildschirmbreite und z.B. 800px Höhe. Auf dieser Scrollbox liegt ein Image1 auf dessen Canvas die Brennkurve geschrieben wird. Zusätzlich gibts noch eine Scrollbar mit der ich die Ausgabe skalieren/stauchen kann, z.B. um die Brennkurve auch im Ganzen sehen zu können.
Auf der Scrollbox liegt ein weiteres Image2 mit der gleichen Grösse wie Image1, jedoch transparent.
Nachdem die Brennkurve gezeichnet wurde will ich ein Fadenkreuz (bzw. eine vertikale Linie) an der Mausposition einblenden um Messwerte an der Stelle lesen zu können (die werden in Labels eingeblendet, habe ich der Übersichtlichkeit halber im Code unten weggelassen).
Dazu erstelle ich ein transparentes TBitmap, setze es auf die gleiche Grösse wie Image1, zeichne an der Mausposition meine Linie, kopiere es mit image2.Picture.Bitmap.assign(Bmp) aufs Image2 und lösche das TBitmap wieder:
Delphi-Quellcode:
procedure TTempLogView.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); // Aufruf über OnMouseMove von Image2
var bmp : tbitmap;
begin
if mausflag = false then exit; // mausflag wird erst nach Zeichnen der Brennkurve auf TRUE gesetzt...quick&dirty, ich weiss...
bmp := tbitmap.Create ;
Bmp.Transparent := true;
Bmp.TransparentColor := clwhite;
Bmp.TransparentMode := tmFixed;
bmp.canvas.pen.Color := clblue;
bmp.Width := image1.Width; // z.B. 30000
bmp.Height := image1.Height; // z.B. 800
with bmp.Canvas do
begin
moveto(x,0);
lineto(x,image1.Height);
end;
image2.Picture.Bitmap.assign(Bmp);
FreeAndNil(bmp);
end;
Leider dauert die Änderung der Grösse des TBitmap sehr lange, geschätzt fast 1 Sekunde. Was natürlich bedeutet dass die Linie den Mausbewegungen nur sehr verzögert folgt.
Es ist definitiv die Grössenänderung die bremst, ich habe das durch ein Label getestet dass ich danach beschreibe und den Rest einfach auskommentiert, so dass ausser der Grössenänderung in der Prozedur nix passiert -> auch das Label wird mit dieser Verzögerung beschrieben, das kopieren aufs Image2 passiert z.B. blitzschnell. Und mache ich Image1 (und damit das TBitmap) mittels o.g. Scrollbar kleiner so wird die Ausgabe auch immer schneller, bis die Linie bei einem Image1 in Bildschirmbreite der Mausbewegung praktisch verzögerungsfrei folgt.
Das irritiert mich jetzt, wieso dauert die Grössenänderung so lange? Irgendeine Idee wie man das beschleunigen kann?
Danke & Gruss
Toenne
Achso, es handelt sich übrigens um XE5