Einzelnen Beitrag anzeigen

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, 10: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