Einzelnen Beitrag anzeigen

Dejan Vu
(Gast)

n/a Beiträge
 
#29

AW: Item in DrawItem ändern?

  Alt 22. Jun 2014, 08:29
Ich finde Mattzes Ansinnen, Fragestellung, Argumenation und Vorgehensweise absolut ok. Dieses 'völlig sinnfreie Anliegen' ist ein sehr wichtiger Bestandteil einer für viele vermutlich komplett überflüssigen Tätigkeit, die unsere Gesellschaft zwar weiterbringt ('Fortschritt'), aber jedoch im eigentlichen Sinne unproduktiv und für Laien teilweise auch blödsinnig ist.

Diese offensichtlich für Einige bekloppte Tätigkeit nennt sich: Forschen und basiert in erster Linie auf Wissensdurst. Und dieser Durst nach Wissen kann nur gestillt werden, wenn Vorbehalte ("Das braucht man doch nicht", "Geht auch anders", "völlig Sinnfrei") mal außen vor gelassen werden. Diese Vorbehalte kommen in der Anwendung zum Einsatz (und sind Antrieb von so etwas wie Wirtschaftlichkeit), haben in der Forschung jedoch nichts zu suchen.

Für Einige scheint Forschung und Programmieren nichts miteinander zu tun zu haben.

Zum Thema: Endllosschleifen in ereignisgesteuerten Programmabläufen lassen sich zuverlässig über Markierungen vermeiden. Grundsätzlich geht da so:
Delphi-Quellcode:
Procedure MyEventHandler(SomeObject : TSomeObject);
Begin
  If IsHandled[SomeObject] then exit;
  IsHandled[SomeObject] := true;
  Try
    DoSomeThingWith(SomeObject); // <<< Löst das Ereignis 'MyEvent' erneut aus
  Finally
    IsHandled[SomeObject] := false;
  End
End;
Eine andere Vorgehensweise ist die, einen die Schleife auslösenden Aufruf nur dann auszuführen, wenn es unbedingt nötig ist. Ein Beispiel ist ein Grid, welches die Spaltenbreite automatisch anpasst, wenn der darzustellende Text breiter als die augenblickliche Spaltenbreite ist. Dann wird die Breite ja nur gesetzt, wenn die Spalte noch nicht breit genug war. Hier findet zwar ein rekursiver Aufruf statt, aber nach dem ersten Aufruf ist Schluss, da die Breite ja beim 2. Aufruf passt.
Delphi-Quellcode:
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  sg : TStringGrid;
begin
  if not (Sender is TStringGrid) then exit;
  sg := TStringGrid(Sender);
  w := sg.Canvas.TextWidth(sg.Cells[aCol, aRow]);

  if w>sg.ColWidths[aCol] then
    sg.ColWidths[aCol] := w; // <<< löst ein erneuten Aufruf von DrawCell aus!
  ...
end;
Hier würde ich vermutlich den zweiten Ansatz nehmen, denn der Text muss ja nur verändert werden, wenn noch nicht geändert wurde.

Eigentlich ist das 2.Pattern eine Spezialisierung des 1.Patterns, denn das [Delphi]IsModified[SomeObject][/delpi] wird ja durch die Änderung des Objekts abgebildet.

Geändert von Dejan Vu (22. Jun 2014 um 08:43 Uhr)
  Mit Zitat antworten Zitat