Einzelnen Beitrag anzeigen

BAMatze

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

Probleme mit transparentBtl

  Alt 13. Aug 2009, 08:23
Hallo und guten Morgen an alle,

Habe in Ergänzung zu diesem Threat meine Klasse ein wenig umgebaut. Das alte Konzept war ja entsprechend: alle Signale, welche eingehen werden in ein Bild gezeichnet. Dies führte zu einigen Problemen, so dass ich eigentlich nur auf den Eingang von einem einzigen "Kanal" des Oszilloskopen reagieren konnte, da sonst das Bild verzerrt wurde(Zeichnen erfolgt per Event, wenn am Eingang ein Signal/ neuer Wert anliegt).
Das neue Konzept sieht jetzt so aus: Für jeden Kanal wird ein seperates Bitmap erzeugt und ein zusätzliches, welches als "Maske" fungiert. Diese sollen per transparentBtl ineinander gezeichnet werden. Dieses Verfahren hat den Vorteil, dass man einzelne Graphen einfach ausblenden kann und dass nur sich ändernde Signale neu gezeichnet werden müssen. Sicherlich ist der Nachteil, dass die Performance aufgrund der größeren Anzahl an Bildern etwas leidet.

Jetzt habe ich aber das Problem, dass das transparentBlt nich wirklich so funktioniert, wie ich mir das Vorstelle. Aber hier jetzt erstmal ein wenig Quellcode:

Delphi-Quellcode:
procedure TOszilloskop.CombineBitmap(var combinedBmp: TBitmap);
var i: integer;
begin
  transparentBlt(combinedBMP.Canvas.Handle, 0, 0, combinedBMP.width, combinedBMP.Height,
  Fbitmap[0].Canvas.Handle, 0, 0, Fbitmap[0].Width, Fbitmap[0].Height, FCtransparentColor);
  for i := 1 to Length(FSignal)-1 do
    begin
      if FCB_Layer[i-1].Checked then transparentBlt(combinedBMP.Canvas.Handle, 0, 0, combinedBMP.width, combinedBMP.Height,
      Fbitmap[i].Canvas.Handle, 0, 0, Fbitmap[i].Width, Fbitmap[i].Height, FCtransparentColor);
    end;
end;

procedure TOszilloskop.NewPaint(Sender: TObject); // Procedure welche ausgeführt wird bei PaintBox.Refresh
var i: integer;
    tempbmp: TBitmap;
begin
  tempbmp := TBitmap.Create;
  tempbmp.Width := FiDisplayWidth;
  tempbmp.Height := FiDisplayHeight;
  CombineBitmap(tempbmp);
  BitBlt(FPB_Display.Canvas.Handle, 0, 0, FPB_Display.width, FPB_Display.Height,
  tempbmp.Canvas.Handle, 0, 0, SRCCOPY);
  tempbmp.Free;
end;

procedure TOszilloskop.InitBitmap(BitmapNumber: integer);
var i, j: integer;
begin
  // Hintergrundfarbe setzen (transparente Farbe)
  FBitmap[BitmapNumber].Canvas.Pen.Color := FCtransparentColor;
  for i := 0 to Fbitmap[BitmapNumber].Height do
    begin
      FBitmap[BitmapNumber].Canvas.MoveTo(0,i);
      FBitmap[BitmapNumber].Canvas.LineTo(FBitmap[BitmapNumber].Width,i);
    end;
  FBitmap[BitmapNumber].Canvas.Pen.Color := FSignal[BitmapNumber-1].KanalColor;
  for j := 0 to FiDisplayWidth-2 do // Schleife durch Messpunkte
    begin
      // FBitmap[0] = Maske, deswegen gehören immer Fbitmap[i] und FSignal[i-1] zusammen!
      FBitmap[BitmapNumber].Canvas.MoveTo(j, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[j]- FdDisplayMin)*FdDisplayStrech));
      FBitmap[BitmapNumber].Canvas.LineTo(j+1, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[j+1]- FdDisplayMin)*FdDisplayStrech));
    end;
end;

procedure TOszilloskop.Bild_neuzeichnen(BitmapNumber: integer);
var i, j, iChanges: integer;
begin

  FBitmap[BitmapNumber].Canvas.CopyRect(rect(0,0,FiDisplayWidth-1,FiDisplayHeight-1),FBitmap[BitmapNumber].canvas,rect(1,0,FiDisplayWidth,FiDisplayHeight-1));
  FBitmap[BitmapNumber].Canvas.Pen.Color := FCtransparentColor;
  FBitmap[BitmapNumber].Canvas.MoveTo(FiDisplayWidth-1,0);
  FBitmap[BitmapNumber].Canvas.LineTo(FiDisplayWidth-1,FiDisplayHeight);

  FBitmap[BitmapNumber].Canvas.Pen.Color := FSignal[BitmapNumber-1].KanalColor;
  FBitmap[BitmapNumber].Canvas.MoveTo(FiDisplayWidth-2, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[FiDisplayWidth-2]- FdDisplayMin)*FdDisplayStrech));
  FBitmap[BitmapNumber].Canvas.LineTo(FiDisplayWidth-1, FiDisplayHeight-5 - round((FSignal[BitmapNumber-1].AusgangY[FiDisplayWidth-1]- FdDisplayMin)*FdDisplayStrech));

  end;

procedure TOszilloskop.Maske_erstellen;
var i: integer;
    dy: double;
begin
  // Striche setzen
  FBitmap[0].Canvas.Pen.Color := FCBackground;
  for i := 0 to Fbitmap[0].Height do
    begin
      FBitmap[0].Canvas.MoveTo(0,i);
      FBitmap[0].Canvas.LineTo(FBitmap[0].Width,i);
    end;
  FBitmap[0].Canvas.Pen.Color := FCMask;
  dy := (FiDisplayHeight-10)/4;
  for i := 0 to 5 do
    begin
      FBitmap[0].Canvas.MoveTo(0, 5+ round(dy * i));
      FBitmap[0].Canvas.LineTo(FiDisplayWidth, 5+ round(dy * i));
    end;
 // horizontale Labels ändern
 for i := 0 to 4 do FLblhorizontal[i].Caption := Format('%.2f',[FdDisplayMin+i*FdDisplayRange/4]);
end;
Es ist nur die Maske zu erkennen. Die graphen werden leider nur gezeichnet wenn ich in der NewPait-procedure das TransparentBtl in ein BitBtl umwandel und 1 Graphen (FBitmap[i]) übergebe.

Hoffe jemand kann mir helfen das Problem zu lösen, habe mich eigentlich an die Beispiele für transparentBtl hier aus der DP gehalten.

Vielen Dank
BAMatze
2. Account Sero
  Mit Zitat antworten Zitat