AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi DrawCell vom Drawgrid belegt ganzes Programm
Thema durchsuchen
Ansicht
Themen-Optionen

DrawCell vom Drawgrid belegt ganzes Programm

Ein Thema von BeBored · begonnen am 17. Jun 2010 · letzter Beitrag vom 21. Jun 2010
Antwort Antwort
Benutzerbild von BeBored
BeBored

Registriert seit: 2. Jun 2004
Ort: Cremlingen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

DrawCell vom Drawgrid belegt ganzes Programm

  Alt 17. Jun 2010, 08:39
Delphi-Version: 2007
Hallo,

ich sitze mal wieder an meinem Bahnprogramm und möchte eine wichtige Optimierung durchführen und hoffe ihr könnt mir helfen.
Ich zeichne folgt auf ein Drawgrid:
Delphi-Quellcode:
procedure TfrmMain.gridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  I: Integer;
begin
  for I := Low(GleisArray) to High(GleisArray) do
  begin
    if GleisArray[i].Art = 'Textthen
      Gleis.Text(GleisArray[i].x, GleisArray[i].y, GleisArray[i].Feldtext);
    if GleisArray[i].Art = 'Geradethen
      Gleis.Gerade(GleisArray[i].x, GleisArray[i].y, GleisArray[i].Gesetzt);
    if GleisArray[i].Art = 'WeicheOLthen
      Gleis.WeicheOL(GleisArray[i].x, GleisArray[i].y, GleisArray[i].Gesetzt);
    if GleisArray[i].Art = 'WeicheOLGthen
      Gleis.WeicheOLG(GleisArray[i].x, GleisArray[i].y, GleisArray[i].Gesetzt);
    if GleisArray[i].Art = 'WeicheORthen
      Gleis.WeicheOR(GleisArray[i].x, GleisArray[i].y, GleisArray[i].Gesetzt);
    if GleisArray[i].Art = 'WeicheORGthen
      Gleis.WeicheORG(GleisArray[i].x, GleisArray[i].y, GleisArray[i].Gesetzt);
    if GleisArray[i].Art = 'WeicheULthen
      Gleis.WeicheUL(GleisArray[i].x, GleisArray[i].y, GleisArray[i].Gesetzt);
// und so weiter...
GleisArray ist ein Record
Delphi-Quellcode:
TGleisrecord = packed record
    x: Integer;
    y: Integer;
    Feldtext: string;
    Art: string;
    Gesetzt: Boolean;
  end;
und wird so gefüllt:
Delphi-Quellcode:
while not DataModule1.query2.Eof do
  begin
    {==============================================================================
    Das Array wird mit den einzelnen Feldern eingelesen.
    Das Array beginnt bei 1, da es nachher einfacher ist beim auslesen.
    ==============================================================================}

    GleisArray[i].x := DataModule1.query2.FieldByName('x').AsInteger;
    GleisArray[i].y := DataModule1.query2.FieldByName('y').AsInteger;
    GleisArray[i].Feldtext := DataModule1.query2.FieldByName('Feldtext').AsString;
    GleisArray[i].Art := DataModule1.query2.FieldByName('Art').AsString;
    GleisArray[i].Gesetzt := DataModule1.query2.FieldByName('Gesetzt').AsBoolean;
    Inc(i);
    {==============================================================================
    Weiter zum nächsten Datensatz.
    ==============================================================================}

    DataModule1.query2.Next;
Die Klasse Gleis beinhaltet die Bitmaps. Es ist alles als Bitmap vorhanden, ausser dem Text der wird "live" erzeugt.
Delphi-Quellcode:
// Die Gleise
procedure TGleisPic.DiagonalLinks(Spalte, Reihe: Integer; Gruen: Boolean);
var
  p: TRect;
begin
  p := Can.CellRect(Spalte, Reihe);
  if Gruen then
    BitBlt(Can.Canvas.Handle, p.Left, p.Top, p.Right - p.Left, p.Bottom - p.Top, Gleise.DiagonalLinks_G.Canvas.Handle, 0, 0, SRCCOPY)
  else
    BitBlt(Can.Canvas.Handle, p.Left, p.Top, p.Right - p.Left, p.Bottom - p.Top, Gleise.DiagonalLinks_S.Canvas.Handle, 0, 0, SRCCOPY);
end;

// und der Text
procedure TGleisPic.Text(Spalte, Reihe: Integer; Text: string);
var
  p: TRect;
begin
  SetBkMode(Can.Canvas.Handle, OPAQUE);
  Can.Canvas.Font.Color := clBlack;
  Can.Canvas.Font.Size := 7;
  Can.Canvas.Font.Style := [];
  Can.Canvas.Font.Name := 'Arial';
  p := Can.CellRect(Spalte, Reihe);
  Can.Canvas.TextOut(p.Left + 5, p.Top, Text);
end;
Das Bild wird auch fix gezeichnet, aber so schnell hintereinander das die gesammte Anwendung völlig belegt ist.
Ich hatte das ganze auch mit ProcessMessages versucht, aber dann ist das Programm sehr anfällig für Abstürze.

Hat jemand einen Vorschlag wie ich das ganze optimieren oder vielleicht ganz anders angehen könnte?
Matthias
Wer nichts wagt der nichts verliert.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

AW: DrawCell vom Drawgrid belegt ganzes Programm

  Alt 17. Jun 2010, 08:49
Das wird zwar nicht der Performancekiller sein aber anstelle mehrere ifs unteinander zu schreiben, schau dir mal das schlüsselwort "else" an. Dadurch wird verhindert das die weiteren ifs noch ausgewertet werden selbst wenn zuvor ein passender Eintrag gefunden wurde.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
1.027 Beiträge
 
RAD-Studio 2009 Pro
 
#3

AW: DrawCell vom Drawgrid belegt ganzes Programm

  Alt 17. Jun 2010, 09:44
Die Gleisart als String zu speichern und abzufragen ist keine gute Idee. Mach dafür einen Aufzähltype, und verwende dann zum Abfragen ein Case statement.

Zitat:
Ich hatte das ganze auch mit ProcessMessages versucht, aber dann ist das Programm sehr anfällig für Abstürze.
Da gibt es wohl ein grundlegenderes Problem, Processmessages kann normalerweise ein Programm nicht anfällig für Abstürze machen, wenn nicht schon irgendwelche bösen Fehler da sind (nicht initialisierte Variable, Out of bounds Zugriff o.ä., die sich zufällig erst dann auswirken, wenn man den Befehl einbaut.
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#4

AW: DrawCell vom Drawgrid belegt ganzes Programm

  Alt 17. Jun 2010, 09:54
Hallo,

wenn ich den gezeigten Quelltext richtig interpretiere, wird bei jedem Aufruf von gridDrawCell das komplette Gleisbild gezeichnet. Die Aufgabe der Routine ist aber, nur den Inhalt der Zelle (ACol, ARow) darzustellen.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.477 Beiträge
 
Delphi 12 Athens
 
#5

AW: DrawCell vom Drawgrid belegt ganzes Programm

  Alt 17. Jun 2010, 10:13
Im OnDrawCell wird immer genau eine Zelle gezeichnet, nicht das komplette Grid.
Delphi-Quellcode:
procedure TfrmMain.gridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  I: Integer;
begin
  for I := Low(GleisArray) to High(GleisArray) do
  begin
    if (GleisArray[i].x = ACol) and (GleisArray[i].y = ARow) then
      Gleis.Zeichne(Grid.Canvas, Rect, GleisArray[i]);
  end;
end;

procedure TGleisPic.Zeichne(ACanvas: TCanvas; ARect: TRect; const AItem: TGleisrecord);
begin
  with AItem do
  begin
         if Art = 'Text'      then Text(ACanvas, ARect, Feldtext)
    else if Art = 'Gerade'    then Gerade(ACanvas, ARect, Gesetzt)
    else if Art = 'WeicheOL'  then WeicheOL(ACanvas, ARect, Gesetzt)
    else if Art = 'WeicheOLGthen WeicheOLG(ACanvas, ARect, Gesetzt)
    else if Art = 'WeicheOR'  then WeicheOR(ACanvas, ARect, Gesetzt)
    else if Art = 'WeicheORGthen WeicheORG(ACanvas, ARect, Gesetzt)
    else if Art = 'WeicheUL'  then WeicheUL(ACanvas, ARect, Gesetzt)
// und so weiter...
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von BeBored
BeBored

Registriert seit: 2. Jun 2004
Ort: Cremlingen
90 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

AW: DrawCell vom Drawgrid belegt ganzes Programm

  Alt 17. Jun 2010, 12:06
Spitze!
Ich habe nun alle Vorschläge umgesetzt und es schnurrt wie ein Kätzchen
Ich danke euch recht herzlich.
Matthias
Wer nichts wagt der nichts verliert.

Geändert von BeBored (17. Jun 2010 um 12:07 Uhr) Grund: Frage geschlossen
  Mit Zitat antworten Zitat
David Martens

Registriert seit: 29. Sep 2003
205 Beiträge
 
Delphi XE Enterprise
 
#7

AW: DrawCell vom Drawgrid belegt ganzes Programm

  Alt 21. Jun 2010, 01:13
Nur so ein Vorschlag, damit wird dein Programm nicht schneller aber, ich finde, es wird übersichtlicher:

Delphi-Quellcode:
case StrUtils.AnsiIndexStr(sourcestring, ['foo','bar']) of
  0:;
  1:;
end;
  Mit Zitat antworten Zitat
Antwort Antwort


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 19:55 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