AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Bild in Paintbox wird nach gewisser Zeit falsch dargestellt
Thema durchsuchen
Ansicht
Themen-Optionen

Bild in Paintbox wird nach gewisser Zeit falsch dargestellt

Ein Thema von BAMatze · begonnen am 10. Sep 2009 · letzter Beitrag vom 10. Sep 2009
Antwort Antwort
Seite 1 von 2  1 2      
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Bild in Paintbox wird nach gewisser Zeit falsch dargestellt

  Alt 10. Sep 2009, 11:09
Hallo und guten Tag nochmal an alle,

Also hatte ja vor kurzem ein paar Fragen zu einer "Oszilloskop"-Komponente welche ich geschrieben hab gestellt. Diese funktionierte mit Hilfe eines integirerten Timers auch wunder bar. Jetzt habe ich diese Komponente in mein eigentliches Projekt gepackt und dort wird der Komponente im 50ms-Takt (gleiche Takt-Frequenz wie bei dem Timer zuvor) Daten in den Eingang geschoben. Die Komponente verhält sich aber ganz anders, als ich dies erwarte. Sie flackert (trotz doublebuffered der Parent-Komponente) und nach einer Weile verschwindet der Graph, welcher gezeichnet wird komplett.

Hier mal meine Graph-Unit (Enthählt die Klasse für einen Oszilloskopen-Channel):
Delphi-Quellcode:
unit OsziChUnit;

interface

uses SysUtils, Dialogs, Controls, Classes, Graphics;

type TOnChangeEingangEvent = procedure(Sender: TObject; const IdentNumber: integer) of Object;

type TPunkt = record
  x: integer;
  y: double;
end;

Type TOszilloskopKanal = class
  
  private
    FadyWert, fadoffeneAbfragen, FadChanges: array of double;
    FadExtremaWert: array[0..4] of double;
    FdMinWert, FdMaxWert: double;
    FbAbfragen: boolean;
    FiYmax, FiWertaenderungen, FiIdent: integer;
    FsName: string;
    FKanalColor, FBackgroundColor: TColor;
    FOnChangeEingang: TOnChangeEingangEvent;
    procedure SetYWert(dWert: double);
    procedure SetName(sWert: string);
    procedure SetKanalFarbe(cWert: TColor);
    function GetYWert(Index: integer): double;
    function GetName: string;
    function GetKanalFarbe: TColor;
    function GetChanges: integer;
    function GetCheckValues: TPunkt;
    function GetMax: double;
    function GetMin: double;
    function GetIdent: integer;
    procedure movedArray(var temparray: array of double);
  protected
    procedure doChangeEingang;
  published
    property OnChangeEingang: TOnChangeEingangEvent read FOnChangeEingang write FOnChangeEingang;
  public
    constructor create(DisplayWidth, Number: integer); reintroduce;
    destructor destroy; override;
    property EingangY: double write SetYWert;
    property IdentNumber: integer read GetIdent;
    property AusgangY[Index: integer]: double read GetYWert;
    property ChangesSinceLastPrintOut: integer read GetChanges;
    property Name: string read GetName write SetName;
    property KanalColor: TColor read GetKanalFarbe write SetKanalFarbe;
    procedure ChangeDisplayWidth(NewDisplayWidth: integer);
    property CheckValus: TPunkt read GetCheckValues;
    property Maxwert: double read GetMax;
    property Minwert: double read GetMin;
end;

implementation

constructor TOszilloskopKanal.Create(DisplayWidth, Number: integer);
var i: integer;
begin
  inherited create;
  FiIdent := Number;
  SetLength(FadyWert, DisplayWidth);
  FiYmax := DisplayWidth -1;
  for i := 0 to FiYmax do FadyWert[i] := 0;
  FdMinWert := 0;
  FdMaxWert := 0;
  FsName := 'Signal '+ inttostr(Number);
  FKanalColor := clblue;
end;

destructor TOszilloskopKanal.Destroy;
begin
  SetLength(FadyWert,0);
  inherited destroy;
end;

procedure TOszilloskopKanal.movedArray(var temparray: array of double);
var i: integer;
begin
  for i := Low(temparray)+1 to High(temparray) do temparray[i] := temparray[i+1];
end;

// Es werden immer nur die letzen Werte gesetzt
procedure TOszilloskopKanal.SetYWert(dWert: double);
begin
  movedArray(FadyWert);
  FadyWert[FiYmax] := dWert;
  if dWert < FdMinWert then FdMinWert := dWert;
  if dWert > FdMaxWert then FdMaxWert := dWert;
  
  doChangeEingang;
end;

procedure TOszilloskopKanal.SetName(sWert: string);
begin
  FsName := sWert;
end;

procedure TOszilloskopKanal.SetKanalFarbe(cWert: TColor);
begin
  FKanalColor := cWert;
end;

function TOszilloskopKanal.GetYWert(Index: integer): double;
var i: integer;
begin
  result := FadyWert[Index];
end;

function TOszilloskopKanal.GetName;
begin
  result := FsName;
end;

function TOszilloskopKanal.GetKanalFarbe: TColor;
begin
  result := FKanalColor;
end;

function TOszilloskopKanal.GetChanges: integer;
begin
  result := FiWertaenderungen;
end;

function TOszilloskopKanal.GetMax: double;
begin
  result := FdMaxWert;
end;

function TOszilloskopKanal.GetMin;
begin
  result := FdMinwert;
end;

function TOszilloskopKanal.GetIdent;
begin
  result := FiIdent;
end;

procedure TOszilloskopKanal.ChangeDisplayWidth(NewDisplayWidth: integer);
var Temparray: array of double;
    i:integer;
begin
  SetLength(Temparray, Length(FadyWert));
  for i := 0 to Length(Temparray)-1 do Temparray[i] := FadyWert[i];
  SetLength(FadyWert, NewDisplayWidth);
  for i := 0 to Length(Temparray)-1 do FadyWert[Length(FadyWert)-1-i] := Temparray[Length(Temparray)-1-i];
  for i := 0 to Length(FadyWert) - Length(Temparray) do FadyWert[i] := 0;
  SetLength(Temparray,0);
end;

function TOszilloskopKanal.GetCheckValues: TPunkt;
begin
  result.y := FadyWert[Length(FadyWert)-2];
  result.x := Length(FadyWert)-2;
end;

procedure TOszilloskopKanal.doChangeEingang;
begin
  if Assigned(FOnChangeEingang) then FOnChangeEingang(Self, FiIdent);
end;

end.
Aus der eigentlichen OszilloskopenUnit ist eigentlich nur die Zusammenstellung aus den einzellnen Graphen und der "Maske" wichtig:
Delphi-Quellcode:
procedure TOszilloskop.NewPaint(Sender: TObject);
var i: integer;
begin
  FDarstellungsBitmap.Assign(FBitmap[0]); // <- in ein TBitmap wird die Maske kopiert
  for i := 0 to Length(FCB_Layer)-1 do
    begin
      if FCB_Layer[i].Checked then transparentBlt(FDarstellungsBitmap.Canvas.Handle, 0, 0, FDarstellungsBitmap.width, FDarstellungsBitmap.Height,
      Fbitmap[i+1].Canvas.Handle, 0, 0, Fbitmap[i+1].Width, Fbitmap[i+1].Height, FCtransparentColor); // auf das TBitmap mit der Maske werden die einzelnen Graphen (FBitmap´s) gezeichnet
    end;
  BitBlt(FPB_Display.Canvas.Handle, 0, 0, FPB_Display.width, FPB_Display.Height,
  FDarstellungsBitmap.Canvas.Handle, 0, 0, SRCCOPY); // alles wird in die Paintbox gezeichnet.
end;
Sieht jemand warum dies der Fall ist? Die Zeit nachdem der Graph verschwindet, ist unterschiedlich. Manchmal dauert es länger, manchmal verschwindet er sehr schnell.

Vielen Dank im Vorraus
BAMatze

Ps.: nur der Graph verschwindet, nicht die Maske!!!
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 11:24
Wie wäre es mit einem kleinen Demoprojekt?

// EDIT:
Hmm, so auf den ersten Blick sehe ich da nichts auffälliges. Deshalb wäre es wirklich gut das Problem mal live zu sehen / zu debuggen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 11:39
Hmm wird eine kleine Weile dauern, weil ich das aus meinem Projekt mit dem Thread auslagern muss. Das aktuelle Projekt darf ich nicht rausgeben.
2. Account Sero
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 11:58
Hier das ausgelagerte Projekt. Es konnten die beiden Fehler in einem Testlauf reproduziert werden, außerdem tritt noch ein Fehler auf, der bisher nicht so sehr zum Tragen kam, dass die Systemressourcen erschöpft sind. Was das bedeutet, kann ich mir zwar denken, aber viel anfangen, kann ich damit noch nicht.
Angehängte Dateien
Dateityp: zip anaologsignal_210.zip (305,4 KB, 13x aufgerufen)
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 12:23
Also, ich habe es kurz angeschaut. Den Fehler mit den Systemressourcen bekomme ich, bis dahin läuft noch alles normal. Ich werde also erst einmal den beseitigen und dann schauen wie es dann läuft.
Was mir aufgefallen ist: Wenn ich mit der Maus in die Paintbox gehe und das Kreuz daher angezeigt wird, kommt quasi sofort dieser Fehler.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 12:30
Also bei mir läuft es auch noch, wenn die Maus in der Paintbox ist. Daber vieleicht hat sich da bei dem Umschreiben ein kleiner Fehler eingeschlichen (ist ja nie ausgeschlossen).Die Fehler kommen erst nach einer WEile.
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 12:39
Argh, ich glaube ich sehe den Fehler schon. Du greifst ohne Synchronisierung aus dem Thread heraus auf Variablen (bzw. genauer die Property deines Formulars) außerhalb zu. Das kann ja nicht gut gehen...
Ich hoffe der Fehler kam jetzt bei der Demo rein? Jedenfalls kann ich mir dann jetzt ohne den Fehler das eigentliche Problem anschauen.

// EDIT:
Also bis jetzt sehe ich da keine Probleme. Ich glaube in deinem echten Projekt ist das genau dieses Problem.
Delphi-Quellcode:
  if bOszilloskop then
    Synchronize(Test);
  //Form1.Eingangssignal[0] := random(256);

  [...]
end;

procedure TControlCardControlThread.Test;
begin
  Form1.Eingangssignal[0] := random(256);
end;
So läuft bei mir jetzt schon minutenlang alles normal.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 12:49
Ja das sieht schonmal gut aus. Das restliche Flackern bekomme ich wohl nur weg, wenn ich die Inputrate verringere oder?

Ps.: Vielen Dank für deine Hilfe @jaenicke
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 13:09
Also wenn ich überall DoubleBuffered auf True setze (Form, TOszilloskop, ScrollBox) und das Intervall auf 25 stelle, dann flackert da kaum noch etwas.

Was mir aufgefallen ist: Wenn sich der Bereich gar nicht ändert, könntest du eigentlich auch die gleiche Bitmap weiterverwenden. Denn im Moment braucht das Programm für das was es macht eigentlich deutlich zu viel Prozessorleistung.
Oder du könntest auch direkt auf die Zielbitmap zeichnen statt auf viele kleine.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Bild in Paintbox wird nach gewisser Zeit falsch dargeste

  Alt 10. Sep 2009, 13:16
Zitat von jaenicke:
Also wenn ich überall DoubleBuffered auf True setze (Form, TOszilloskop, ScrollBox) und das Intervall auf 25 stelle, dann flackert da kaum noch etwas.

Was mir aufgefallen ist: Wenn sich der Bereich gar nicht ändert, könntest du eigentlich auch die gleiche Bitmap weiterverwenden. Denn im Moment braucht das Programm für das was es macht eigentlich deutlich zu viel Prozessorleistung.
Oder du könntest auch direkt auf die Zielbitmap zeichnen statt auf viele kleine.
Also eigentlich ist das so programmiert, dass nur gezeichnet wird, wenn etwas am Eingang passiert:

Auszug aus der OsziUnit {OszilloskopUnit}
Delphi-Quellcode:
procedure TOszilloskop.FOnSignalEingang(Sender: TObject; const IdentNumber: integer);
var i: integer;
begin
  GetRange;
  for I := 0 to Length(FSignal)-1 do InitBitmap(i+1);
  FPB_Display.Invalidate;
end;
und Auszug aus der OsziChUnit {OszilloskopKanalUnit}
Delphi-Quellcode:
procedure TOszilloskopKanal.SetYWert(dWert: double);
begin
  movedArray(FadyWert);
  FadyWert[FiYmax] := dWert;
  if dWert < FdMinWert then FdMinWert := dWert;
  if dWert > FdMaxWert then FdMaxWert := dWert;
  doChangeEingang;
end;

procedure TOszilloskopKanal.doChangeEingang;
begin
  if Assigned(FOnChangeEingang) then FOnChangeEingang(Self, FiIdent);
end;
Das Event, dass ein Eingangssignal in die OsziChUnit reinkommt, wird an die OsziUnit weiter gegeben und das löst die Maßnahmen zum Zeichnen aus. Hat allerdings noch einen großen Nachteil, wo ich noch kein Konzept für habe:

Wenn ich 20 Kanäle erzeuge dann wird das ganze 20mal ausgelöst, was zur Folge hat, dass die Graphen etwas verzerrt werden. Zur Zeit, da ich nur 1 Graphen benötige, kommt der Fehler nicht zum tragen, aber dafür muss ich noch ein machbares Konzept finden.

[Edit] Fehler: die verzerrte Darstellung seit der Trennung der der einzellnen Layer(Graphen) in separate Bitmaps hat sich erledigt. Die Lösung für den verzerrten Graphen war die Änderung des altes Konzeptalle: Signale werden bei Eingang eines Signals in einen Graphen gezeichnet. Also mit den Layern ist dieser Fehler nie aufgetreten![/Edit]
2. Account Sero
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz